1
0
mirror of https://github.com/sashacmc/photo-importer.git synced 2025-02-10 18:31:08 +02:00
photo-importer/fileprop.py
2018-06-25 09:47:59 +02:00

197 lines
5.2 KiB
Python
Executable File

#!/usr/bin/python3
import os
import re
import stat
import time
import logging
import exifread
import datetime
import config
IGNORE = 0
IMAGE = 1
VIDEO = 2
AUDIO = 3
GARBAGE = 4
class FileProp(object):
DATE_REX = [
(re.compile('\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}'),
'%Y-%m-%d_%H-%M-%S'),
(re.compile('\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}'),
'%Y-%m-%d-%H-%M-%S'),
(re.compile('\d{4}-\d{2}-\d{2}T\d{2}.\d{2}.\d{2}'),
'%Y-%m-%dT%H.%M.%S'),
(re.compile('\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}'),
'%Y-%m-%dT%H:%M:%S'),
(re.compile('\d{8}_\d{6}'), '%Y%m%d_%H%M%S'),
(re.compile('\d{14}'), '%Y%m%d%H%M%S'),
(re.compile('\d{8}'), '%Y%m%d'),
]
TIME_SRC_CFG = {
IMAGE: 'time_src_image',
VIDEO: 'time_src_video',
AUDIO: 'time_src_audio',
}
FILE_EXT_CFG = {
IMAGE: 'file_ext_image',
VIDEO: 'file_ext_video',
AUDIO: 'file_ext_audio',
GARBAGE: 'file_ext_garbage',
IGNORE: 'file_ext_ignore',
}
EXT_TO_TYPE = {}
def __init__(self, config):
self.__config = config
self.__prepare_ext_to_type()
self.__out_list = set()
def __prepare_ext_to_type(self):
self.EXT_TO_TYPE = {}
for tp, cfg in self.FILE_EXT_CFG.items():
for ext in self.__config['main'][cfg].split(','):
ext = '.' + ext.lower()
if ext in self.EXT_TO_TYPE:
logging.fatal('Double ext: ' + ext)
self.EXT_TO_TYPE[ext] = tp
def __type_by_ext(self, ext):
try:
return self.EXT_TO_TYPE[ext.lower()]
except KeyError:
logging.warning('Unknown ext: ' + ext)
return IGNORE
def __time(self, fullname, name, tp):
if tp not in (IMAGE, VIDEO, AUDIO):
return None
for src in self.__config['main'][self.TIME_SRC_CFG[tp]].split(','):
time = None
if src == 'exif':
time = self.__time_by_exif(fullname)
elif src == 'name':
time = self.__time_by_name(name)
elif src == 'attr':
time = self.__time_by_attr(fullname)
else:
raise Exception('Wrong time_src: ' + src)
if time:
return time
return None
def __time_by_name(self, fname):
for exp, fs in self.DATE_REX:
mat = exp.findall(fname)
if len(mat):
try:
time = datetime.datetime.strptime(mat[0], fs)
if time.year < 1990 or time.year > 2100:
continue
return time
except ValueError:
pass
return None
def __time_by_exif(self, fullname):
try:
with open(fullname, 'rb') as f:
tags = exifread.process_file(f)
strtime = tags['EXIF DateTimeOriginal'].values
return datetime.datetime.strptime(strtime, '%Y:%m:%d %H:%M:%S')
except (FileNotFoundError, KeyError) as ex:
logging.warning('time by exif (%s) exception: %s' % (fullname, ex))
def __time_by_attr(self, fullname):
try:
return datetime.datetime.fromtimestamp(
time.mktime(time.localtime(os.stat(fullname)[stat.ST_MTIME])))
except (FileNotFoundError, KeyError) as ex:
logging.warning('time by attr (%s) exception: %s' % (fullname, ex))
def _out_name_full(self, path, out_name, ext):
res = os.path.join(path, out_name) + ext
i = 1
while os.path.isfile(res) or res in self.__out_list:
i += 1
res = os.path.join(path, out_name + '_' + str(i) + ext)
self.__out_list.add(res)
return res
def get(self, fullname):
path, fname_ext = os.path.split(fullname)
fname, ext = os.path.splitext(fname_ext)
tp = self.__type_by_ext(ext)
ftime = self.__time(fullname, fname, tp)
if ftime:
out_name = ftime.strftime(
self.__config['main']['out_time_format'])
else:
out_name = None
if out_name:
ok = fname[0:len(out_name)] == out_name
else:
ok = False
return FilePropRes(self, tp, ftime, path, ext, out_name, ok)
class FilePropRes(object):
def __init__(self, prop_ptr, tp, time, path, ext, out_name, ok):
self.__prop_ptr = prop_ptr
self.__type = tp
self.__time = time
self.__path = path
self.__ext = ext
self.__out_name = out_name
self.__ok = ok
def type(self):
return self.__type
def time(self):
return self.__time
def ok(self):
return self.__ok
def path(self):
return self.__path
def ext(self):
return self.__ext
def out_name(self):
return self.__out_name
def out_name_full(self, path=None):
if path is None:
path = self.__path
return self.__prop_ptr._out_name_full(
path, self.__out_name, self.__ext)
if __name__ == '__main__':
import sys
fp = FileProp(config.Config(), sys.argv[1])
print(fp.type(), fp.time(), fp.ok())