-
Notifications
You must be signed in to change notification settings - Fork 0
/
scorpion.py
executable file
·116 lines (105 loc) · 3.72 KB
/
scorpion.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python3
# command to run with all jpgs in data directory
# find data -name "*.jpg" | xargs ./scorpion.py
# for the flags
# find data -name "*.jpg" | xargs -I '{}' ./scorpion.py '{}' -d
import piexif
import datetime
import os
import argparse
from PIL import Image, ExifTags
from colorama import Fore, Style
class Scorpion:
def __init__(self, files, changes = None, delete = False):
self.files = files
self.changes = {}
self.print_data()
if changes and not delete:
try:
self.validate_changes(changes)
except Exception as err:
print(f"{Fore.RED}Error: {err}{Style.RESET_ALL}")
return
self.modify_exif()
self.print_data()
elif delete:
self.delete_exif()
self.print_data()
def validate_changes(self, changes):
for change in changes:
try:
tag, value = change.split("=")
except ValueError:
raise ValueError(f"Invalid change: {change}")
try:
tag = int(tag)
except ValueError:
raise ValueError(f"Invalid Exif tag: {tag}")
if tag not in ExifTags.TAGS:
raise ValueError(f"Invalid Exif tag: {tag}")
if not value:
raise ValueError(f"Invalid value for tag {tag}")
self.changes[tag] = value
def print_data(self):
for file in self.files:
if not os.path.exists(file):
print(f"{Fore.RED}File not found: {Style.RESET_ALL}{file}")
continue
try:
image = Image.open(file)
print(f"{Fore.GREEN}File: {Style.RESET_ALL}{file}")
created = datetime.datetime.fromtimestamp(os.path.getctime(file)).strftime("%Y-%m-%d %H:%M:%S")
print(f"{Fore.CYAN}Created: {Style.RESET_ALL}{created}")
modified = datetime.datetime.fromtimestamp(os.path.getmtime(file)).strftime("%Y-%m-%d %H:%M:%S")
print(f"{Fore.CYAN}Modified: {Style.RESET_ALL}{modified}")
exif = image._getexif()
print(f"{Fore.CYAN}Format: {Style.RESET_ALL}{image.format}")
print(f"{Fore.CYAN}Mode: {Style.RESET_ALL}{image.mode}")
print(f"{Fore.CYAN}Size: {Style.RESET_ALL}{image.size}")
if exif:
print(f"{Fore.BLUE}Exif data:{Style.RESET_ALL}")
for tag, value in exif.items():
print(f" - {Fore.CYAN}{ExifTags.TAGS.get(tag, tag)}{Style.RESET_ALL}: {value}")
else:
print(f"{Fore.YELLOW}No Exif data found.{Style.RESET_ALL}")
except Exception as err:
print(f"{Fore.RED}Error: {err}{Style.RESET_ALL}")
print()
def modify_exif(self):
for file in self.files:
if not os.path.exists(file):
print(f"{Fore.RED}File not found: {Style.RESET_ALL}{file}")
continue
try:
image = Image.open(file)
try:
exif_dict = piexif.load(image.info["exif"])
except KeyError:
exif_dict = {"0th": {}}
for tag, value in self.changes.items():
exif_dict["0th"][tag] = value
exif_bytes = piexif.dump(exif_dict)
image.save(file, "jpeg", exif=exif_bytes)
print(f"{Fore.GREEN}Exif data modified: {Style.RESET_ALL}{file}")
except Exception as err:
print(f"{Fore.RED}Error: {err}{Style.RESET_ALL}")
def delete_exif(self):
for file in self.files:
if not os.path.exists(file):
print(f"{Fore.RED}File not found: {Style.RESET_ALL}{file}")
continue
try:
image = Image.open(file)
image.save(file)
print(f"{Fore.GREEN}Exif data deleted: {Style.RESET_ALL}{file}")
except Exception as err:
print(f"{Fore.RED}Error: {err}{Style.RESET_ALL}")
def main():
parser = argparse.ArgumentParser(description="Print image data and Exif data from given files.")
parser.add_argument("files", nargs="+", help="Files to print data from.")
parser.add_argument("-c", "--changes", nargs="+", help="Changes to Exif data: tag=value.")
parser.add_argument("-d", "--delete", action="store_true", help="Delete Exif data.")
args = parser.parse_args()
Scorpion(args.files, args.changes, args.delete)
if __name__ == "__main__":
main()