custom_shelf initial commit
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
info = {
|
||||
'icon' : 'LIGHT_SPOT',
|
||||
'description' : 'Save as lighting file from currently opened anim file',
|
||||
}
|
||||
|
||||
import bpy
|
||||
import os
|
||||
from os import listdir
|
||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
||||
import re, fnmatch, glob
|
||||
from mathutils import Vector, Matrix
|
||||
from math import radians, degrees
|
||||
|
||||
import datetime
|
||||
|
||||
C = bpy.context
|
||||
D = bpy.data
|
||||
scene = C.scene
|
||||
|
||||
|
||||
|
||||
def create_lighting_file():
|
||||
'''Create lighting_v001 file from anim'''
|
||||
# if D.is_dirty:
|
||||
# print('Current file is not saved')
|
||||
# return
|
||||
|
||||
if 'lighting' in D.filepath:
|
||||
print('File already detected as lighting')
|
||||
return
|
||||
|
||||
if not 'animation' in D.filepath:
|
||||
print('Not in animation folder')
|
||||
return
|
||||
|
||||
name = re.sub(r'anim_v\d{3}', 'lighting_v001', basename(D.filepath))
|
||||
print('name: ', name)
|
||||
|
||||
fp = dirname(dirname(D.filepath))
|
||||
print('shot path: ', fp)
|
||||
fp = join(fp, 'lighting', name)
|
||||
print('light filepath: ', fp)
|
||||
|
||||
if exists(fp):
|
||||
print('lighting_v001 already exists in folder')
|
||||
return
|
||||
|
||||
|
||||
info = D.texts.get('info')
|
||||
if not info:
|
||||
info = D.texts.new('info')
|
||||
|
||||
info.write(f'\nCreated from {basename(D.filepath)} at {str( datetime.datetime.now() )}')
|
||||
print('Saving current file as lighting')
|
||||
bpy.ops.wm.save_as_mainfile(filepath=fp)
|
||||
|
||||
print('Done')
|
||||
|
||||
create_lighting_file()
|
||||
@@ -0,0 +1,43 @@
|
||||
info = {
|
||||
'icon' : 'CHECKMARK',
|
||||
'description' : 'Check objects modifiers',
|
||||
}
|
||||
|
||||
import bpy
|
||||
import os, re, shutil
|
||||
from os.path import dirname, basename, join, abspath, splitext, exists, isfile, isdir
|
||||
from os import listdir
|
||||
import datetime
|
||||
C = bpy.context
|
||||
D = bpy.data
|
||||
scn = scene = C.scene
|
||||
|
||||
## in scene syubloop ob.instance_collection.all_objects:
|
||||
|
||||
print(f'\n== Modifiers check {basename(D.filepath)} ==')
|
||||
for ob in bpy.data.objects:
|
||||
if ob.type != 'ARMATURE' and ob.hide_viewport != ob.hide_render:
|
||||
print(f'/!\ {ob.name} view != render : hide_viewport {ob.hide_viewport}, hide_render {ob.hide_render}')
|
||||
|
||||
if ob.type in ('MESH', 'CURVE', 'TEXT') and len(ob.modifiers) > 0:
|
||||
for mod in ob.modifiers:
|
||||
#mod.show_viewport = True
|
||||
#mod.show_render = True
|
||||
if mod.type == 'SUBSURF':
|
||||
# print (ob.name)
|
||||
if mod.render_levels < mod.levels:
|
||||
print(f'[M] {ob.name} subsurf render levels inferior to viewport : view {mod.levels} > render {mod.render_levels}')
|
||||
elif mod.render_levels == 0:
|
||||
print(f'[M] {ob.name} subsurf useless : render levels set to 0 : view {mod.levels} > render {mod.render_levels}')
|
||||
'''
|
||||
if mod.type == 'ARMATURE':
|
||||
if mod.object:
|
||||
print (mod.object.name)#print armatrue target
|
||||
#ob.modifiers.remove(mod) #remove modifier
|
||||
|
||||
if mod.type == 'SOLIDIFY':
|
||||
mod.thickness
|
||||
mod.offset
|
||||
'''
|
||||
|
||||
print('== check done.')
|
||||
@@ -0,0 +1,68 @@
|
||||
info = {
|
||||
'icon' : 'DECORATE_LIBRARY_OVERRIDE',
|
||||
'description' : 'Check available library update',
|
||||
'update' : False,
|
||||
'fullreport': False,
|
||||
}
|
||||
|
||||
import bpy
|
||||
import os
|
||||
from os import listdir, scandir
|
||||
from os.path import abspath, relpath, join, dirname, basename, exists, isfile, isdir, splitext
|
||||
import re, fnmatch, glob
|
||||
from mathutils import Vector, Matrix
|
||||
from math import radians, degrees
|
||||
C = bpy.context
|
||||
D = bpy.data
|
||||
scene = C.scene
|
||||
|
||||
auto_update = info['update']#False
|
||||
fullreport = info['fullreport']
|
||||
|
||||
## 1: all execpt num, 2: num, 3:ext
|
||||
rseq = re.compile('^(.*?)(\d+)(\D*)$')
|
||||
|
||||
|
||||
print('\n--library check--')
|
||||
for ob in bpy.context.scene.objects:
|
||||
if not ob.type == 'EMPTY': continue
|
||||
if not ob.instance_collection: continue
|
||||
if not ob.instance_collection.library: continue
|
||||
lib = ob.instance_collection.library
|
||||
if not lib: continue
|
||||
fp = lib.filepath
|
||||
if not fp: continue
|
||||
rel_dir = dirname(fp)
|
||||
abs_lib = abspath(bpy.path.abspath(fp))
|
||||
if not exists(abs_lib):
|
||||
print(f'Lib not found: obj: {ob.name} > instance: {ob.instance_collection.name}\n-> {abs_lib}')
|
||||
continue
|
||||
lib_dir = dirname(abs_lib)
|
||||
lib_name = basename(abs_lib)
|
||||
|
||||
#same length ? #last modified ? #last by name without #must be 90% identical ? # parts without rightmost number must be identical (good enough)
|
||||
regname = rseq.search(lib_name)
|
||||
if not regname:
|
||||
print(f'X - {lib_name} : could not identify version using regex: {rseq.pattern}')
|
||||
continue
|
||||
name_base = regname.group(1)
|
||||
|
||||
# filelist = [f for f in scandir(lib_dir) if f.is_file() and len(f.name) == len(lib_name)]
|
||||
|
||||
# more strict with filename
|
||||
filelist = [f for f in scandir(lib_dir) if f.is_file() and len(f.name) == len(lib_name) and rseq.search(f.name) and rseq.search(f.name).group(1) == name_base]
|
||||
filelist.sort(key=lambda x : x.name)#sort in place alphabetically
|
||||
|
||||
last = filelist[-1]
|
||||
if last.name != lib.name:
|
||||
print(f'/!\ Lib update found : obj: {ob.name} > instance: {ob.instance_collection.name}\n {lib_name} >> {last.name}\n')
|
||||
|
||||
if auto_update:
|
||||
### use relocate or do it automagically...
|
||||
nfp = join(dirname(fp), last.name)
|
||||
lib.filepath = nfp
|
||||
continue
|
||||
|
||||
if fullreport: print(f'Lib OK : obj: {ob.name} > instance: {ob.instance_collection.name} > file: {lib_name}')
|
||||
## make breakdown popup for addon version
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
info = {
|
||||
'icon' : 'TOOL_SETTINGS',
|
||||
'description' : 'Set render path for PNG - RGB out',
|
||||
'stamp' : False
|
||||
}
|
||||
|
||||
import bpy
|
||||
import os
|
||||
from os import listdir
|
||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
||||
import re, fnmatch, glob
|
||||
from mathutils import Vector, Matrix
|
||||
from math import radians, degrees
|
||||
from time import time
|
||||
|
||||
C = bpy.context
|
||||
D = bpy.data
|
||||
scn = scene = C.scene
|
||||
rd = scn.render
|
||||
ev = scn.eevee
|
||||
|
||||
def render_anim(GL=False):
|
||||
#openGl render
|
||||
if GL:
|
||||
bpy.ops.render.opengl(animation=True, view_context=False)#view_context False > look throughcam
|
||||
else:
|
||||
bpy.ops.render.render(animation=True)
|
||||
|
||||
def set_stamp(active_note=False):
|
||||
rd.use_stamp = True
|
||||
|
||||
## Enable
|
||||
rd.use_stamp_filename = True
|
||||
rd.use_stamp_frame = True
|
||||
rd.use_stamp_render_time = True
|
||||
rd.use_stamp_time = True
|
||||
rd.use_stamp_date = True
|
||||
|
||||
## Disable
|
||||
rd.use_stamp_sequencer_strip = False
|
||||
rd.use_stamp_marker = False
|
||||
rd.use_stamp_scene = False
|
||||
rd.use_stamp_lens = False
|
||||
rd.use_stamp_camera = False
|
||||
rd.use_stamp_hostname = False
|
||||
rd.use_stamp_memory = False
|
||||
rd.use_stamp_frame_range = False
|
||||
|
||||
## Notes
|
||||
rd.use_stamp_note = active_note
|
||||
|
||||
if rd.use_stamp_note:
|
||||
info = D.texts.get('info')
|
||||
txt = ''
|
||||
if info:
|
||||
for l in info.lines[:2]:
|
||||
if 'Created from' in l.body:
|
||||
txt = l.body
|
||||
if txt:
|
||||
rd.stamp_note_text = txt
|
||||
else:#disable notes
|
||||
rd.use_stamp_note = False
|
||||
|
||||
def setup_render_params(use_stamp=False):
|
||||
'''set dimensions, percentage, fps...'''
|
||||
if use_stamp:
|
||||
set_stamp(active_note=True)
|
||||
else:
|
||||
rd.use_stamp = False
|
||||
|
||||
rd.resolution_x = 1920
|
||||
rd.resolution_y = 1080
|
||||
rd.resolution_percentage = 100
|
||||
rd.use_border = False
|
||||
rd.fps = 25
|
||||
rd.use_sequencer = False
|
||||
|
||||
#sampling
|
||||
ev.taa_render_samples = 128#push up sample for shadow mainly
|
||||
|
||||
#AO
|
||||
ev.use_gtao = True
|
||||
ev.gtao_distance = 0.7
|
||||
ev.gtao_factor = 0.7
|
||||
ev.gtao_quality = 0.2
|
||||
ev.use_gtao_bent_normals = False#bent normal makes it lighter than shadows !
|
||||
#not sure...
|
||||
ev.use_gtao_bounce = True#no bounce is darker... (less AO on claer object)
|
||||
|
||||
#setup color management
|
||||
scene.view_settings.look = 'Filmic - Medium High Contrast'
|
||||
|
||||
#no disable auto folder opening after auto video making
|
||||
if hasattr(scene, 'MVopen'):
|
||||
scene.MVopen = False
|
||||
|
||||
|
||||
def set_render_path():
|
||||
setup_render_params(use_stamp=info['stamp'])
|
||||
rd.image_settings.file_format = 'PNG'
|
||||
rd.image_settings.color_mode = 'RGB'#A
|
||||
rd.image_settings.color_depth = '8'
|
||||
rd.use_file_extension = True
|
||||
rd.use_overwrite = True#erase file
|
||||
rd.use_placeholder = False
|
||||
rd.image_settings.compression = 50#default = 15, high = slower and lighter (same quality)
|
||||
|
||||
filename = splitext(basename(D.filepath))[0]
|
||||
# fp = join(dirname(D.filepath), 'render')
|
||||
|
||||
|
||||
rd.filepath = join(dirname(D.filepath), 'images', filename, filename + '.')# '.####' #let a dot to separate padding number
|
||||
|
||||
set_render_path()
|
||||
|
||||
|
||||
'''
|
||||
start = time()
|
||||
render_anim(GL=False)
|
||||
print(f'elapsed {time() - start}')
|
||||
'''
|
||||
@@ -0,0 +1,155 @@
|
||||
info = {
|
||||
'icon' : 'TOOL_SETTINGS',
|
||||
'description' : 'Set filepath and video settings for direct video out',
|
||||
'stamp' : False
|
||||
}
|
||||
|
||||
|
||||
import bpy
|
||||
import os
|
||||
from os import listdir
|
||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
||||
import re, fnmatch, glob
|
||||
from mathutils import Vector, Matrix
|
||||
from math import radians, degrees
|
||||
from time import time
|
||||
|
||||
C = bpy.context
|
||||
D = bpy.data
|
||||
scn = scene = C.scene
|
||||
rd = scn.render
|
||||
ev = scn.eevee
|
||||
|
||||
def set_stamp(active_note=False):
|
||||
rd.use_stamp = True
|
||||
|
||||
## Enable
|
||||
rd.use_stamp_filename = True
|
||||
rd.use_stamp_frame = True
|
||||
rd.use_stamp_render_time = True
|
||||
rd.use_stamp_time = True
|
||||
rd.use_stamp_date = True
|
||||
|
||||
## Disable
|
||||
rd.use_stamp_sequencer_strip = False
|
||||
rd.use_stamp_marker = False
|
||||
rd.use_stamp_scene = False
|
||||
rd.use_stamp_lens = False
|
||||
rd.use_stamp_camera = False
|
||||
rd.use_stamp_hostname = False
|
||||
rd.use_stamp_memory = False
|
||||
rd.use_stamp_frame_range = False
|
||||
|
||||
## Notes
|
||||
rd.use_stamp_note = active_note
|
||||
|
||||
if rd.use_stamp_note:
|
||||
info = D.texts.get('info')
|
||||
txt = ''
|
||||
if info:
|
||||
for l in info.lines[:2]:
|
||||
if 'Created from' in l.body:
|
||||
txt = l.body
|
||||
if txt:
|
||||
rd.stamp_note_text = txt
|
||||
else:#disable notes
|
||||
rd.use_stamp_note = False
|
||||
|
||||
|
||||
def setup_render_params(use_stamp=False):
|
||||
'''set dimensions, percentage, fps...'''
|
||||
if use_stamp:
|
||||
set_stamp(active_note=True)
|
||||
else:
|
||||
rd.use_stamp = False
|
||||
|
||||
rd.resolution_x = 1920
|
||||
rd.resolution_y = 1080
|
||||
rd.resolution_percentage = 100
|
||||
rd.use_border = False
|
||||
rd.fps = 25
|
||||
rd.use_sequencer = False
|
||||
|
||||
#sampling
|
||||
ev.taa_render_samples = 128#push up sample for shadow mainly
|
||||
|
||||
#AO
|
||||
ev.use_gtao = True
|
||||
ev.gtao_distance = 0.7
|
||||
ev.gtao_factor = 0.7
|
||||
ev.gtao_quality = 0.2
|
||||
ev.use_gtao_bent_normals = False#bent normal makes it lighter than shadows !
|
||||
#not sure...
|
||||
ev.use_gtao_bounce = True#no bounce is darker... (less AO on claer object)
|
||||
|
||||
#setup color management
|
||||
scene.view_settings.look = 'Filmic - Medium High Contrast'
|
||||
|
||||
#no disable auto folder opening after auto video making
|
||||
if hasattr(scene, 'MVopen'):
|
||||
scene.MVopen = False
|
||||
|
||||
def render_anim(GL=False):
|
||||
#openGl render
|
||||
if GL:
|
||||
bpy.ops.render.opengl(animation=True, view_context=False)#view_context False > look throughcam
|
||||
else:
|
||||
bpy.ops.render.render(animation=True)
|
||||
|
||||
|
||||
def check_name(name, fp):
|
||||
filelist = [splitext(f)[0] for f in os.listdir(fp)]#raw names
|
||||
if not name in filelist:
|
||||
return name
|
||||
|
||||
ct = 2
|
||||
new = name + '_' + str(ct).zfill(2)
|
||||
while new in filelist:
|
||||
new = name + '_' + str(ct).zfill(2)
|
||||
ct+=1
|
||||
if ct > 99:
|
||||
return None
|
||||
return new
|
||||
|
||||
|
||||
|
||||
def set_video_path():
|
||||
setup_render_params(use_stamp=info['stamp'])
|
||||
rd.image_settings.file_format = 'FFMPEG'
|
||||
rd.image_settings.color_mode = 'RGB'
|
||||
rd.ffmpeg.codec = 'H264'
|
||||
rd.ffmpeg.constant_rate_factor = 'HIGH'#default 'MEDIUM'
|
||||
rd.ffmpeg.format = 'MPEG4'#'MKV', 'QUICKTIME'
|
||||
rd.ffmpeg.ffmpeg_preset = 'GOOD'#default = 'GOOD'(compromise), BEST(light - slow), REALTIME(fat-fast)'
|
||||
|
||||
ext = ''
|
||||
if rd.ffmpeg.format == 'MPEG4':
|
||||
ext = '.mp4'
|
||||
elif rd.ffmpeg.format == 'QUICKTIME':
|
||||
ext = '.mov'
|
||||
elif rd.ffmpeg.format == 'MKV':
|
||||
ext = '.mkv'
|
||||
|
||||
filename = splitext(basename(D.filepath))[0]
|
||||
fp = join(dirname(D.filepath), 'images')
|
||||
|
||||
if not exists(fp):
|
||||
print(f'not found : {fp} ')
|
||||
return
|
||||
|
||||
filename = check_name(filename, fp)
|
||||
if not filename:
|
||||
print('name not available')
|
||||
return
|
||||
|
||||
rd.filepath = join(dirname(D.filepath), 'images', filename + ext)
|
||||
|
||||
|
||||
set_video_path()
|
||||
|
||||
|
||||
'''
|
||||
start = time()
|
||||
render_anim(GL=False)
|
||||
print(f'elapsed {time() - start}')
|
||||
'''
|
||||
@@ -0,0 +1,39 @@
|
||||
info = {
|
||||
'icon' : 'RENDER_ANIMATION',
|
||||
'description' : 'render timed',
|
||||
}
|
||||
|
||||
import bpy
|
||||
import os
|
||||
from os import listdir
|
||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
||||
import re, fnmatch, glob
|
||||
from mathutils import Vector, Matrix
|
||||
from math import radians, degrees
|
||||
from time import time
|
||||
import datetime
|
||||
|
||||
C = bpy.context
|
||||
D = bpy.data
|
||||
scn = scene = C.scene
|
||||
rd = scn.render
|
||||
|
||||
|
||||
def render_anim(GL=False):
|
||||
#openGl render
|
||||
if GL:
|
||||
bpy.ops.render.opengl(animation=True, view_context=True)#view_context False > look throughcam
|
||||
else:
|
||||
bpy.ops.render.render(animation=True)
|
||||
|
||||
start = time()
|
||||
|
||||
render_anim()
|
||||
|
||||
secs = time() - start
|
||||
timesec_str = f'elapsed {secs} seconds'
|
||||
time_str = str(datetime.timedelta(seconds=secs))
|
||||
|
||||
print(timesec_str)
|
||||
print(time_str)
|
||||
C.window_manager.clipboard = time_str
|
||||
@@ -0,0 +1,39 @@
|
||||
info = {
|
||||
'icon' : 'RENDER_ANIMATION',
|
||||
'description' : 'render this viewport openGL',
|
||||
}
|
||||
|
||||
import bpy
|
||||
import os
|
||||
from os import listdir
|
||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
||||
import re, fnmatch, glob
|
||||
from mathutils import Vector, Matrix
|
||||
from math import radians, degrees
|
||||
from time import time
|
||||
import datetime
|
||||
|
||||
C = bpy.context
|
||||
D = bpy.data
|
||||
scn = scene = C.scene
|
||||
rd = scn.render
|
||||
|
||||
|
||||
def render_anim(GL=False):
|
||||
#openGl render
|
||||
if GL:
|
||||
bpy.ops.render.opengl(animation=True, view_context=True)#view_context False > look throughcam
|
||||
else:
|
||||
bpy.ops.render.render(animation=True)
|
||||
|
||||
start = time()
|
||||
|
||||
render_anim(GL=True)
|
||||
|
||||
secs = time() - start
|
||||
timesec_str = f'elapsed {secs} seconds'
|
||||
time_str = str(datetime.timedelta(seconds=secs))
|
||||
|
||||
print(timesec_str)
|
||||
print(time_str)
|
||||
C.window_manager.clipboard = time_str
|
||||
@@ -0,0 +1,62 @@
|
||||
info = {
|
||||
'icon' : 'RENDER_STILL',
|
||||
'description' : 'render still image timed',
|
||||
}
|
||||
|
||||
import bpy
|
||||
import os
|
||||
from os import listdir
|
||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
||||
import re, fnmatch, glob
|
||||
from mathutils import Vector, Matrix
|
||||
from math import radians, degrees
|
||||
from time import time
|
||||
import datetime
|
||||
|
||||
C = bpy.context
|
||||
D = bpy.data
|
||||
scn = scene = C.scene
|
||||
rd = scn.render
|
||||
|
||||
|
||||
|
||||
def pad_with_current_frame(match):
|
||||
return str(C.scene.frame_current).zfill(len(match.group(0)))
|
||||
|
||||
def add_frame_padding(name):
|
||||
'''
|
||||
return string padded with current blender frame
|
||||
if # found, use this padding to write theframe
|
||||
'''
|
||||
import re
|
||||
if not '#' in name: return name + str(C.scene.frame_current).zfill(4)
|
||||
# return re.sub(r'\#{1,10}', pad_with_current_frame, name)# all '#...' in string
|
||||
return re.sub(r'\#{1,10}(?!.*\#)', pad_with_current_frame, name)# only last '#...'
|
||||
|
||||
|
||||
def render(anim=False, GL=False):
|
||||
if GL:#openGl render
|
||||
bpy.ops.render.opengl(animation=anim, write_still=True, view_context=True)#view_context False > look throughcam
|
||||
else:
|
||||
bpy.ops.render.render(animation=anim, write_still=True)
|
||||
|
||||
start = time()
|
||||
|
||||
orgfp = C.scene.render.filepath
|
||||
C.scene.render.filepath = add_frame_padding(C.scene.render.filepath)
|
||||
|
||||
try:
|
||||
render(anim=False)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
finally:
|
||||
C.scene.render.filepath = orgfp
|
||||
|
||||
secs = time() - start
|
||||
timesec_str = f'elapsed {secs} seconds'
|
||||
time_str = str(datetime.timedelta(seconds=secs))
|
||||
|
||||
print(timesec_str)
|
||||
print(time_str)
|
||||
C.window_manager.clipboard = time_str
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
info = {
|
||||
'icon' : 'PACKAGE',
|
||||
'description' : 'pack all videos',
|
||||
'dryrun' : False
|
||||
}
|
||||
|
||||
import os, re, shutil
|
||||
from os.path import dirname, basename, join, abspath, splitext, exists, isfile, isdir
|
||||
from os import listdir
|
||||
import datetime
|
||||
|
||||
|
||||
dryrun = info['dryrun']
|
||||
|
||||
resid = re.compile(r'\d{2}-\d{3}-\d{2}$')
|
||||
|
||||
shots = '/z/___SERIE/WIND-UPS/episodes/00/shots/'
|
||||
|
||||
packzone = '/z/___SERIE/WIND-UPS/medias/pack'
|
||||
old_folder = join(packzone, '_old')
|
||||
|
||||
new_list = []
|
||||
warning = []
|
||||
|
||||
extension_filter = ('mp4', 'mov',)#, 'mkv'
|
||||
exclusion_words = ('test', 'old',)#use this for loose word search
|
||||
rexclude = re.compile(r'[ _-]old|test')#old if after separator (' _-') and word test anywhere (might be too loose)
|
||||
|
||||
for f in os.scandir(shots):
|
||||
if not resid.match(f.name):continue
|
||||
|
||||
imgfp = f'/z/___SERIE/WIND-UPS/episodes/00/shots/{f.name}/lighting/images'
|
||||
if not exists(imgfp):continue
|
||||
|
||||
#need to be video file type
|
||||
all_videos = [v for v in os.scandir(imgfp) if v.name.lower().endswith(extension_filter) and not rexclude.search(v.name)]#any(x in v.name for x in exclusion_words)
|
||||
if not all_videos:continue
|
||||
|
||||
print(f'\n{f.name}')
|
||||
|
||||
bytime = sorted(all_videos, key=lambda x: x.stat().st_mtime)
|
||||
byname = sorted(all_videos, key=lambda x: x.name)
|
||||
# print('bytime: ', bytime[-1].name)
|
||||
# print('byname: ', byname[-1].name)
|
||||
|
||||
if bytime[-1] != byname[-1]:
|
||||
warn = f'''/!\\ {f.name}
|
||||
last by name and by modif time different in {imgfp}
|
||||
by time : {bytime[-1].name} ({datetime.datetime.fromtimestamp(bytime[-1].stat().st_mtime)})
|
||||
by name : {byname[-1].name} ({datetime.datetime.fromtimestamp(byname[-1].stat().st_mtime)})
|
||||
'''
|
||||
print(warn)
|
||||
warning.append(warn)
|
||||
|
||||
good_file = bytime[-1]
|
||||
topack = good_file.path
|
||||
topackname = good_file.name
|
||||
dest = join(packzone, topackname)
|
||||
|
||||
# run checks and copy if needed
|
||||
if exists(dest):
|
||||
dup = [basename(dest)]
|
||||
else:
|
||||
print(f"compare with {'_'.join(splitext(good_file.name)[0].split('_')[:3])}")
|
||||
# ex : twu_00-008-01_lighting_v001.mp4 (split on third to)
|
||||
dup = [i for i in listdir(packzone) if isfile(join(packzone, i)) and '_'.join(splitext(i)[0].split('_')[:3]) == '_'.join(splitext(good_file.name)[0].split('_')[:3])]
|
||||
|
||||
# check duplication against this file
|
||||
if dup:
|
||||
print(f'same shot already exists:{dup}')
|
||||
newer = True
|
||||
for i in dup:
|
||||
dfp = join(packzone, i)
|
||||
# print(f'{os.stat(dfp).st_mtime} VS file {good_file.stat().st_mtime}')
|
||||
if os.stat(dfp).st_mtime >= good_file.stat().st_mtime:
|
||||
# print(f'{i} is same or most recent')
|
||||
newer = False
|
||||
|
||||
if not newer:
|
||||
print(f'{good_file.name} is not newer, skip')
|
||||
continue
|
||||
|
||||
#src is most recent, do the copy and erase/move older
|
||||
for d in dup:
|
||||
if not exists(old_folder):os.mkdir(old_folder)
|
||||
old_src = join(packzone, d)
|
||||
old_dest = join(old_folder, d)
|
||||
if exists(old_dest):
|
||||
print(f' - deleting {d} (already in _old)')
|
||||
if not dryrun: os.remove(old_src)
|
||||
else:
|
||||
print(f' - moving {d} to _old')
|
||||
if not dryrun: shutil.move(old_src, old_dest)
|
||||
|
||||
# if made it here, safely do the copy
|
||||
print(f'- packing new file : {topack}')
|
||||
if not dryrun: shutil.copy2(topack, dest)
|
||||
new_list.append(f'{topackname} : {topack}')
|
||||
|
||||
|
||||
print('DONE\n----')
|
||||
|
||||
if warning:
|
||||
print('\nWarnings')
|
||||
for w in warning: print(w)
|
||||
|
||||
if new_list:
|
||||
print(f'\n{len(new_list)} New:')
|
||||
for n in new_list: print(n)
|
||||
Reference in New Issue
Block a user