Skip to content

Instantly share code, notes, and snippets.

@Day0Dreamer
Created October 18, 2017 16:44
Show Gist options
  • Save Day0Dreamer/2a9ebf9ad82bad1fb37ef43afe4fd526 to your computer and use it in GitHub Desktop.
Save Day0Dreamer/2a9ebf9ad82bad1fb37ef43afe4fd526 to your computer and use it in GitHub Desktop.
This class can generate a file sequence, clean a folder, find missing files, rename the sequence. Expected sequence 'text00000.text'
from os import path, makedirs, scandir, listdir, remove, rename
from re import search, compile
from warnings import warn
# ##################################################### CONFIG ####################################################### #
conf_default_working_path = '.'
conf_default_new_name = 'default_'
# #################################################################################################################### #
class SequenceCheck(object):
"""This class can generate a file sequence, clean a folder, find missing files, rename the sequence
Expected sequence 'text00000.text'"""
def __init__(self, working_path=None, new_name=None):
self.working_path = working_path or conf_default_working_path
self.new_name = new_name or conf_default_new_name
self.working_set = []
self.working_set_int = []
self.most_common_ext = None
def generate_placeholder_sequence(self,
prefix='image_', suffix='.jpg',
range_start=0, range_stop=99, step=1,
empty_folder_check=True):
"""Follows a pattern of 'prefix+number+suffix' to generate files,
makes a new folder and requires it to be empty"""
makedirs(self.working_path, exist_ok=True)
try:
if empty_folder_check:
next(scandir(self.working_path)) # If there is a file inside
raise FileExistsError('{} is not empty'.format(path.abspath(self.working_path)))
else:
raise StopIteration
except StopIteration:
pass # If there is nothing inside
except FileExistsError:
warn('{} is not empty'.format(path.abspath(self.working_path)))
return
for i in range(range_start, range_stop, step): # Make a bunch of empty files
file_path = path.join(path.abspath(self.working_path), str(prefix) + str(i) + str(suffix))
open(file_path, 'w').close()
def clean_working_path(self):
"""Simply delete everything inside the working path"""
[remove(file.path) for file in scandir(self.working_path)]
def analyse_sequence(self):
"""Analyse the folder contents to guess what is the most likely sequence"""
dir_content = listdir(self.working_path)
ls = [path.splitext(file) for file in dir_content] # Get [file names, extensions]
ext = set([file_item[1] for file_item in ls]) # Get extensions of files
ext_dict = {} # Count files by extension
for i in list(ext):
ext_dict[i] = [i[1] for i in ls].count(i)
self.most_common_ext = max(ext_dict, key=(lambda key: ext_dict[key]))
# Get most likely sequence
self.working_set = [file for file in dir_content if path.splitext(file)[1] == self.most_common_ext]
# Extract ints from file names
self.working_set_int = []
frame_number_re = compile('[0-9]+\.')
start, end = search(frame_number_re, self.working_set[0]).span()
for file in self.working_set:
frame_number_extracted = file[start:end-1]
if frame_number_extracted.isdigit():
self.working_set_int.append(int(frame_number_extracted))
def check_missing_frames(self):
self.analyse_sequence()
# Check for missing frames
for frame_n_int in range(self.working_set_int[1], self.working_set_int[-1]):
if frame_n_int not in self.working_set_int:
print('Frame #{} is missing'.format(frame_n_int))
def rename_sequence(self, new_name=None, zfill=3):
if new_name:
self.new_name = new_name
self.analyse_sequence()
# Create the new names
assembled_names_list = []
for i in self.working_set_int:
assembled_name = str(self.new_name)+str(i).zfill(zfill)+str(self.most_common_ext)
assembled_names_list.append(assembled_name)
# Churning through the new names list and renaming them
for i in zip(self.working_set, assembled_names_list):
if i[0] == i[1]:
print('Names are equal')
break
else:
self.new_name = path.join(self.working_path, i[0]), path.join(self.working_path, i[1])
try:
rename(*self.new_name) # *unpacking a tuple into two arguments
print('Rename successful: {} -> {}'.format(*self.new_name)) # *unpacking a tuple into two arguments
except OSError:
print('Renaming went wrong')
if __name__ == '__main__':
w_dir = input('Tell me the folder [DEFAULT = {}]\n'.format(path.abspath(path.curdir)))
sc = SequenceCheck(w_dir)
while 1:
gen_quest = input('Generate sample sequence? [Y/N]\n')
if gen_quest.upper() == 'Y':
sc.generate_placeholder_sequence(range_stop=4, empty_folder_check=False)
break
while 1:
ren_quest = input('Rename the sequence? [Y/N]\n')
if ren_quest.upper() == 'Y':
sc.rename_sequence()
break
else:
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment