Форум сайта python.su
0
Скрипт для копирования фото с телефона на nas и сортировкой по папкам с датой
#!/usr/bin/env python import sys, os.path, shutil, re from PIL import Image from PIL.ExifTags import TAGS # ./phone_photos_to_nas.py input_dir output_dir inputdir = sys.argv[1] outputdir = sys.argv[2] def main (): if os.path.isdir(inputdir): for root, dirs, files in os.walk(inputdir): for f in files: # if filename like 20141111_191402.jpg match_obj = re.match(r"\d{8}_\d{6}", f) if match_obj: year = f[0:4] month = f[4:6] day = f[6:8] date = day + '.' + month + '.' + year else: # get date from exif data img_info = {} i = Image.open(os.path.join(root, f)) info = i._getexif() for tag, value in info.items(): decoded = TAGS.get(tag, tag) img_info[decoded] = value raw_date = img_info['DateTimeDigitized'] # 2014:11:11 19:14:02 year = raw_date[0:4] month = raw_date[5:7] day = raw_date[8:10] date = day + '.' + month + '.' + year dirs = os.walk(outputdir).next()[1] if date in dirs: shutil.copy2(os.path.join(root, f), os.path.join(outputdir, date)) else: os.makedirs(os.path.join(outputdir, date)) shutil.copy2(os.path.join(root, f), os.path.join(outputdir, date)) print "Done!" main()
Офлайн
103
сразу бросается
match_obj = re.match(r"\d{8}_\d{6}", f) if match_obj: year = f[0:4] month = f[4:6] day = f[6:8] date = day + '.' + month + '.' + year
year = raw_date[0:4] month = raw_date[5:7] day = raw_date[8:10] date = day + '.' + month + '.' + year
if os.path.isdir(inputdir):
import sys, os.path, shutil, re
os.makedirs(os.path.join(outputdir, date))
Офлайн
857
l1nxmatch_obj = re.match(r"\d{8}_\d{6}", f) if match_obj: year = f[0:4] month = f[4:6] day = f[6:8] date = day + '.' + month + '.' + year
>>> import re >>> >>> s = '20141111_191402.jpg' >>> >>> match = re.match(r'(\d{4})(\d{2})(\d{2})_\d{6}', s) >>> day, month, year = match.groups()[::-1] >>> date = '{}.{}.{}'.format(day, month, year) >>> date '11.11.2014' >>>
l1nx1) Это всё надо на разных строках писать. (прочитай PEP8 и PEP20 из списка)import sys, os.path, shutil, re
Отредактировано py.user.next (Апрель 21, 2015 00:35:25)
Офлайн
0
Версия 2. Разбила функцию на функции и добавлена обработка ошибок
#!/usr/bin/env python import os import re import shutil import sys from PIL import Image from PIL.ExifTags import TAGS # ./phone_photos_to_nas.py input_dir output_dir if len(sys.argv) == 2 and (sys.argv[1] == '-h' or sys.argv[1] == 'help'): exit("Need 2 arguments: input_dir and output_dir") elif len(sys.argv)!= 3: exit("Error: need 2 arguments: input_dir and output_dir") inputdir = sys.argv[1] outputdir = sys.argv[2] date = '' def main(): if os.path.isdir(inputdir): for root, dirs, files in os.walk(inputdir): for f in files: # if filename like 20141111_191402.jpg match_obj = re.match(r"\d{8}_\d{6}", f) if match_obj: format_date(f) else: # get date from exif data img_info = {} i = Image.open(os.path.join(root, f)) info = i._getexif() for tag, value in info.items(): decoded = TAGS.get(tag, tag) img_info[decoded] = value format_date(img_info['DateTimeDigitized']) # 2014:11:11 19:14:02 copy_files(root, f, date) else: print inputdir +" is not dir" def copy_files(root, f, date): if os.path.isdir(outputdir): dirs = os.walk(outputdir).next()[1] if date in dirs: shutil.copy2(os.path.join(root, f), os.path.join(outputdir, date)) else: os.mkdir(os.path.join(outputdir, date)) shutil.copy2(os.path.join(root, f), os.path.join(outputdir, date)) else: print outputdir +" is not dir" def format_date(s): match = re.match(r'(\d{4}):?(\d{2}):?(\d{2})[_|\s]\d{2}:?\d{2}:?\d{2}', s) day, month, year = match.groups()[::-1] global date date = '{}.{}.{}'.format(day, month, year) return date # '11.11.2014' main()
Офлайн
103
date = ''
global date
def format_date(s): match = re.match(r'(\d{4}):?(\d{2}):?(\d{2})[_|\s]\d{2}:?\d{2}:?\d{2}', s) day, month, year = match.groups()[::-1] global date date = '{}.{}.{}'.format(day, month, year) return date # '11.11.2014'
i = Image.open(os.path.join(root, f)) info = i._getexif() for tag, value in info.items(): decoded = TAGS.get(tag, tag) img_info[decoded] = value format_date(img_info['DateTimeDigitized']) # 2014:11:11 19:14:02
i = Image.open(os.path.join(root, f)) info = i._getexif() img_info = dict(info.items()) format_date(img_info['DateTimeDigitized']) # 2014:11:11 19:14:02
#!/usr/bin/env python import os import re import shutil import sys from datetime import datetime from PIL import Image from PIL.ExifTags import TAGS # ./phone_photos_to_nas.py input_dir output_dir if len(sys.argv) == 2 and (sys.argv[1] == '-h' or sys.argv[1] == 'help'): exit("Need 2 arguments: input_dir and output_dir") elif len(sys.argv)!= 3: exit("Error: need 2 arguments: input_dir and output_dir") def main(inputdir, outputdir): if os.path.isdir(inputdir): for root, dirs, files in os.walk(inputdir): for f in files: # if filename like 20141111_191402.jpg match_obj = re.match(r"\d{8}_\d{6}", f) if match_obj: date = format_date(f, "%Y%m%d_%H%M%S") else: info = Image.open(os.path.join(root, f))._getexif() for tag, value in info.items(): if TAGS.get(tag, tag) == 'DateTimeDigitized': date = format_date(value, "%Y:%m:%d %H:%M:%S") break copy_files(root, f, date, outputdir) else: print inputdir +" is not dir" def copy_files(root, f, date, outputdir): if os.path.isdir(outputdir): dirs = os.walk(outputdir).next()[1] if date in dirs: shutil.copy2(os.path.join(root, f), os.path.join(outputdir, date)) else: os.mkdir(os.path.join(outputdir, date)) shutil.copy2(os.path.join(root, f), os.path.join(outputdir, date)) else: print outputdir +" is not dir" def format_date(s, r): return datetime.strftime(datetime.strptime(s, r), "%d.%m.%Y") main(sys.argv[1], sys.argv[2])
Отредактировано terabayt (Апрель 22, 2015 19:04:27)
Офлайн
857
terabaytНе, ей просто надо переставить символы в имени файла. С датой/временем она не работает никак.
нужно воспользоваться функциями модуля datetime
l1nxВот это всё надо заменить на argparse; там всё красиво, удобно и компактно.if len(sys.argv) == 2 and (sys.argv[1] == '-h' or sys.argv[1] == 'help'): exit("Need 2 arguments: input_dir and output_dir") elif len(sys.argv)!= 3: exit("Error: need 2 arguments: input_dir and output_dir") inputdir = sys.argv[1] outputdir = sys.argv[2]
l1nxГлобальных переменных и ссылок на них вообще не должно быть.inputdir = sys.argv[1] outputdir = sys.argv[2] date = ''
l1nxСтарайся делать функции такими, чтобы они ничего не выводили, а либо возвращали значение True/False, 0 (успех) / 1 2 3 4 … (ошибка), либо порождали исключение в случае ошибки, а в случае успеха не возвращали ничего.print outputdir +" is not dir"
Отредактировано py.user.next (Апрель 23, 2015 01:00:15)
Офлайн
103
py.user.next
Не, ей просто надо переставить символы в имени файла. С датой/временем она не работает никак.
Просто функцию надо назвать не format_date(), а translate_name() или около того.
img_info = {} i = Image.open(os.path.join(root, f)) info = i._getexif() for tag, value in info.items(): decoded = TAGS.get(tag, tag) img_info[decoded] = value format_date(img_info['DateTimeDigitized']) # 2014:11:11 19:14:02
Отредактировано terabayt (Апрель 23, 2015 01:04:18)
Офлайн
857
terabaytА, она, походу, слила две функции в одну.
а это? я сильно не вникал
l1nxА я ещё думаю, что это регулярка у неё такая странная с двоеточиями для имён файлов.match = re.match(r'(\d{4}):?(\d{2}):?(\d{2})[_|\s]\d{2}:?\d{2}:?\d{2}', s)
terabaytКогда у тебя есть целые числа, обозначающие временные величины, и тебе нужно сформировать на их основе строку - тогда да. А когда у тебя строки, которые просто нужно переставить местами, - тогда нет.
строковое представление лучше же переделать через модуль datetime чем переставлять местами символы?!
>>> s = '1.12.2015' >>> >>> d, m, y = s.split('.') >>> >>> out = '{}_{}_{}'.format(y, m, d) >>> out '2015_12_1' >>>
Отредактировано py.user.next (Апрель 23, 2015 01:31:00)
Офлайн
103
py.user.nextдля облегчения и универсальности
А зачем его тут использовать?
py.user.nextэто хороший пример, все красиво, но
Вот пример
20141111_191402
2014:11:11 19:14:02
py.user.next
А зачем его тут использовать?
Офлайн
857
terabaytА если там вдруг появятся имена файлов/директорий, которые вообще ничего из даты/времени не содержат?
для облегчения и универсальности
terabaytЭто делается канонизация и всё:
напишите как это20141111_191402можно так же красиво обработать2014:11:11 19:14:02
>>> import re >>> >>> def trans_name(s): ... match = re.match(r'(\d{4})(\d{2})(\d{2})\d{6}', s) ... day, month, year = match.groups()[::-1] ... out = '{}.{}.{}'.format(day, month, year) ... return out ... >>> def canon(s): ... return re.sub(r'[ :_]', r'', s) ... >>> lst = ['20141111_191402', ... '2014:11:11 19:14:02', ... '2014_11_11_19_14_02.jpg'] >>> >>> out = [trans_name(canon(i)) for i in lst] >>> out ['11.11.2014', '11.11.2014', '11.11.2014'] >>>
Отредактировано py.user.next (Апрель 23, 2015 04:06:15)
Офлайн