Skip to content

Commit 440a3e0

Browse files
python source code added for all tools
1 parent ea582df commit 440a3e0

5 files changed

Lines changed: 439 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import os
2+
from PIL import Image
3+
from pillow_heif import register_heif_opener
4+
from gooey import Gooey, GooeyParser
5+
# Iterate through all the HEIC files in the directory
6+
7+
def convert_images(path):
8+
register_heif_opener()
9+
for root, dirs, files in os.walk(path, topdown=True):
10+
for i,f in enumerate(files, start=1):
11+
#COPY_FROM = Path(root)
12+
input_file = os.path.join(root, f)
13+
print('file:'+input_file)
14+
if input_file.endswith(".heic") or input_file.endswith(".heif"):
15+
try:
16+
with Image.open(input_file) as im:
17+
im = im.convert("RGB")
18+
output_file = os.path.join(root, os.path.splitext(f)[0] + ".JPG")
19+
im.save(output_file, "JPEG")
20+
except:
21+
print(f"Error: {f} is not a valid HEIC or HEIF file")
22+
else:
23+
print(f"Error: {f} is not a valid image file")
24+
25+
def check_slash(string):
26+
slash_to_add = "\\"
27+
if string and len(string) > 3:
28+
return string
29+
else:
30+
newvalue = os.path.join(string,slash_to_add)
31+
return newvalue
32+
@Gooey(program_name='HEIC and HEIF Converter - HEIC/HEIF to JPG.',
33+
menu=[{
34+
'name': 'File',
35+
'items': [{
36+
'type': 'AboutDialog',
37+
'menuTitle': 'About',
38+
'name': 'HEIC and HEIF Converter - HEIC/HEIF to JPG.',
39+
'description': 'Python based HEIC and HEIF Converter - HEIC/HEIF to JPG.',
40+
'version': '1.0',
41+
'copyright': '',
42+
'website': '',
43+
'developer': 'Michael Akridge'}]}])
44+
45+
def parse_args():
46+
parser = GooeyParser(description='HEIC and HEIF Converter')
47+
parser.add_argument('SELECT_PATH', widget='DirChooser',type=check_slash)
48+
return parser.parse_args()
49+
50+
def main():
51+
# setup file path
52+
args = parse_args()
53+
pathvalue = args.SELECT_PATH
54+
print(pathvalue)
55+
convert_images(pathvalue)
56+
print('---- Working ----')
57+
print('-------------------------------------------------')
58+
print('---- Complete ----')
59+
60+
if __name__ == '__main__':
61+
main()
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# Import the libraries we need for this script
2+
import hashlib
3+
import optparse
4+
import os
5+
import os.path
6+
import sys
7+
from gooey import Gooey, GooeyParser
8+
9+
def read_hash_from_md5_file(md5_filename):
10+
"""This function reads a hash out of a .md5 file."""
11+
12+
with open(md5_filename) as file:
13+
for line in file:
14+
possible_hash = pos = line.split(",")[1]
15+
if len(possible_hash) == 32:
16+
return possible_hash
17+
18+
return None # failed to find the hash
19+
20+
21+
def generate_md5_hash(filename, block_size=2 ** 20, progress_blocks=128):
22+
"""This function generates an md5 hash for a given file."""
23+
24+
md5 = hashlib.md5()
25+
blocks = 0
26+
total_blocks = 1 + (os.path.getsize(filename) / block_size)
27+
with open(filename, 'rb') as file:
28+
while True:
29+
data = file.read(block_size)
30+
if not data:
31+
break
32+
md5.update(data)
33+
# Display progress in the command line
34+
if (blocks % progress_blocks) == 0:
35+
percentage_string = "{0}%".format(100 * blocks / total_blocks)
36+
sys.stdout.write("\r{1:<10}{0}".format(filename, percentage_string))
37+
sys.stdout.flush()
38+
blocks += 1
39+
return md5.hexdigest()
40+
41+
42+
def check_against_md5_file(filename, md5_filename):
43+
"""This function checks a filename against its md5 filename."""
44+
45+
# Get the expected hash from the .md5 file
46+
expected_hash = read_hash_from_md5_file(md5_filename)
47+
48+
# If we couldn't read the expected hash, return an error
49+
if expected_hash is None:
50+
print("ERROR {0}".format(filename))
51+
print("Could not read a valid md5 hash from {0}".format(md5_filename))
52+
return (filename, 'could not read from .md5 file', 'not generated')
53+
54+
# Generate the actual hash for the file being protected
55+
actual_hash = generate_md5_hash(filename)
56+
57+
# Print out success or failure messages
58+
error = None
59+
if actual_hash == expected_hash:
60+
sys.stdout.write("\rOK {0}\n".format(filename))
61+
sys.stdout.flush()
62+
else:
63+
sys.stdout.write("\rERROR {0}\n".format(filename))
64+
sys.stdout.flush()
65+
print(" expected hash {0}".format(expected_hash))
66+
print(" actual hash is {0}".format(actual_hash))
67+
error = (filename, expected_hash, actual_hash)
68+
69+
return error
70+
71+
72+
def generate_md5_file_for(filename, md5_filename):
73+
"""This function generates an md5 file for an existing file."""
74+
try:
75+
output_file = open(md5_filename, 'w')
76+
except IOError:
77+
sys.stdout.write("ERROR: can't write to file {0}\n".format(md5_filename))
78+
79+
generated_hash = generate_md5_hash(filename)
80+
file_size = os.path.getsize(filename)
81+
output_file.write("{0},{1},{2}\n".format(os.path.basename(filename),generated_hash,file_size))
82+
output_file.close()
83+
84+
sys.stdout.write("\rDONE {0}\n".format(filename))
85+
sys.stdout.flush()
86+
87+
88+
def get_file_info_dictionaries(dirs):
89+
"""Walk the directories recursively and match up .mnf files to the files they describe."""
90+
91+
# Recursively walk the directories, trying to pair up the .md5 files
92+
file_info_dicts = {}
93+
for (dirpath, dirnames, filenames) in os.walk(dirs):
94+
for each_filename in filenames:
95+
full_file_path = os.path.join(dirpath, each_filename)
96+
is_md5_file = (full_file_path[-4:].lower() == '.mnf')
97+
if is_md5_file:
98+
key = full_file_path[:-4]
99+
else:
100+
key = full_file_path
101+
d = file_info_dicts.setdefault(key, dict(file=False, md5=False))
102+
if is_md5_file:
103+
d['md5'] = True
104+
else:
105+
d['file'] = True
106+
107+
# Print information about what was found
108+
files_found = 0
109+
md5_found = 0
110+
both_found = 0
111+
for file_name, d in iter(file_info_dicts.items()):
112+
if d['md5'] and d['file']:
113+
both_found += 1
114+
elif d['file']:
115+
files_found += 1
116+
elif d['md5']:
117+
md5_found += 1
118+
119+
print("Found {0} files with matching .mnf files.".format(both_found))
120+
print("Found {0} .mnf files with no matching file.".format(md5_found))
121+
print("Found {0} files with no matching .mnf file.".format(files_found))
122+
123+
return file_info_dicts
124+
125+
@Gooey(
126+
program_name='Mnftool',
127+
menu=[{
128+
'name': 'File',
129+
'items': [{
130+
'type': 'AboutDialog',
131+
'menuTitle': 'About',
132+
'name': 'Mnftool',
133+
'description': 'Python based',
134+
'version': '2.1',
135+
'copyright': '2022',
136+
'website': '',
137+
'developer': 'Michael Akridge'}]
138+
139+
}]
140+
)
141+
142+
143+
def parse_args():
144+
parser = GooeyParser(description='MNF Tool Checker & Generator.')
145+
parser.add_argument('SELECT_FILE_FOLDER', widget="DirChooser")
146+
parser.add_argument('SELECT_OPERATION',choices=['check','generate'])
147+
return parser.parse_args()
148+
149+
def main():
150+
args = parse_args()
151+
dirs = args.SELECT_FILE_FOLDER
152+
operation = args.SELECT_OPERATION
153+
file_info_dicts = get_file_info_dictionaries(dirs)
154+
if operation == 'check':
155+
# Check each pair of matching files
156+
num_checked = 0
157+
errors = []
158+
for filename, d in sorted(iter(file_info_dicts.items())):
159+
if d['file'] and d['md5']:
160+
error = check_against_md5_file(filename, filename + '.mnf')
161+
if error:
162+
errors.append(error)
163+
num_checked += 1
164+
print("===============================================================")
165+
print("SUMMARY")
166+
print("{0} files checked.".format(num_checked))
167+
print("{0} had errors.".format(len(errors)))
168+
for (filename, expected_hash, actual_hash) in errors:
169+
print(filename)
170+
print(" expected hash {0}".format(expected_hash))
171+
print(" actual hash is {0}".format(actual_hash))
172+
print("===============================================================")
173+
174+
elif operation == 'generate':
175+
print(file_info_dicts)
176+
# Generate an .md5 file for files which don't have one
177+
for filename, d in sorted(iter(file_info_dicts.items())):
178+
if d['file'] and not d['md5']:
179+
generate_md5_file_for(filename, filename + '.mnf')
180+
print("===============================================================")
181+
182+
183+
if __name__ == "__main__":
184+
main()
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import os
2+
import subprocess
3+
from pathlib import Path
4+
# to get current date & time
5+
from datetime import datetime
6+
from gooey import Gooey, GooeyParser
7+
8+
def do_the_copy(path1,path2,path3):
9+
subprocess.call(["robocopy", path1 ,path2, "/mt","/XX", "/z", "/mir","/log:" + path3])
10+
11+
@Gooey(program_name='File Copy Tool',
12+
menu=[{
13+
'name': 'File',
14+
'items': [{
15+
'type': 'AboutDialog',
16+
'menuTitle': 'About',
17+
'name': 'File Copy',
18+
'description': 'Python based file copy using robocopy ',
19+
'version': '1.0',
20+
'copyright': '2022',
21+
'website': '',
22+
'developer': 'Michael Akridge'}]}])
23+
24+
def parse_args():
25+
parser = GooeyParser(description='Folder Size Stat App.')
26+
parser.add_argument('COPY_FROM', widget='DirChooser')
27+
parser.add_argument('COPY_TO_PATH', widget='DirChooser')
28+
parser.add_argument('COPY_LOG_PATH', widget='DirChooser')
29+
return parser.parse_args()
30+
31+
def main():
32+
args = parse_args()
33+
current_datetime = datetime.now().strftime("%m_%d_%Y_%H%M")
34+
pathvalue1 = args.COPY_FROM
35+
pathvalue2 = args.COPY_TO_PATH
36+
pathvalue3 = args.COPY_LOG_PATH
37+
LOG_FILENAME = current_datetime + "_filecopy_log.log"
38+
LOG_FILENAME_PATH = os.path.join(pathvalue3, LOG_FILENAME)
39+
40+
do_the_copy(pathvalue1,pathvalue2,LOG_FILENAME_PATH)
41+
print('-------------------------------------------------')
42+
print('---- Copy Process Complete ----')
43+
44+
if __name__ == '__main__':
45+
main()
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#import re
2+
#import numpy as np
3+
import os
4+
import stat
5+
import pandas as pd
6+
import csv
7+
from datetime import datetime
8+
from gooey import Gooey, GooeyParser
9+
10+
def get_tree_size(path):
11+
total = 0
12+
for entry in os.scandir(path):
13+
if entry.is_dir(follow_symlinks=False):
14+
total += get_tree_size(entry.path)
15+
else:
16+
total += entry.stat(follow_symlinks=False).st_size
17+
return total
18+
19+
def search_folders(path):
20+
# define empty data list to be used in file metadata script
21+
final_datas = []
22+
df = pd.DataFrame()
23+
for src_dir, dirs, files in os.walk(path):
24+
for dir_ in dirs:
25+
current_src = os.path.join(src_dir, dir_)
26+
print(current_src)
27+
print('Scanning ' + current_src)
28+
a= get_tree_size(current_src)
29+
# returns path size in mb
30+
b= a/1048576
31+
# returns path size in gb
32+
c=a/1073741824
33+
# returns path size in tb
34+
d=a/float(1<<40)
35+
final_data = current_src,d,c,b
36+
final_datas.append(final_data)
37+
print("Size: " + str(c) + " GB")
38+
df = pd.DataFrame(final_datas)
39+
#use break to just get first loop, root directory, stats
40+
break
41+
return df
42+
43+
def check_slash(string):
44+
slash_to_add = "\\"
45+
if string and len(string) > 3:
46+
return string
47+
else:
48+
newvalue = os.path.join(string,slash_to_add)
49+
return newvalue
50+
51+
@Gooey(program_name='Folder Stats',
52+
menu=[{
53+
'name': 'File',
54+
'items': [{
55+
'type': 'AboutDialog',
56+
'menuTitle': 'About',
57+
'name': 'Folder Size Stats',
58+
'description': 'Python based file tree stat maker',
59+
'version': '1.0',
60+
'copyright': '2022',
61+
'website': '',
62+
'developer': 'Michael Akridge'}]}])
63+
64+
def parse_args():
65+
parser = GooeyParser(description='Folder Size Stat App.')
66+
parser.add_argument('SELECT_PATH', widget='DirChooser',type=check_slash)
67+
return parser.parse_args()
68+
69+
def main():
70+
# create csv list of files with metadta
71+
header = ['Path', 'Size(TB)','Size(GB)','Size(MB)']
72+
# setup file name & path
73+
current_datetime = datetime.now().strftime("%m_%d_%Y_%H%M")
74+
file_log_filename = current_datetime + '_folder_size_log.csv'
75+
args = parse_args()
76+
pathvalue = args.SELECT_PATH
77+
print(pathvalue)
78+
df=search_folders(pathvalue)
79+
file_log_filename_path = os.path.join(pathvalue, file_log_filename)
80+
df.to_csv(file_log_filename_path, index=False, header=header)
81+
print('-------------------------------------------------')
82+
print('---- Scan Complete ----')
83+
print('---- Folder Size Log Located at ----')
84+
print(file_log_filename_path)
85+
86+
if __name__ == '__main__':
87+
main()

0 commit comments

Comments
 (0)