1.py


1
#!/usr/bin/python
2
3
# max zeitabstand in sekunden
4
DELTA = 400
5
6
import sys
7
import os
8
import re
9
from PIL import Image
10
from PIL.ExifTags import TAGS
11
from datetime import datetime
12
13
def get_exif(fn):
14
    '''exif-daten zu einer datei fn lesen'''
15
    ret = {}
16
    i = Image.open(fn)
17
    info = i._getexif()
18
    for tag, value in info.items():
19
        decoded = TAGS.get(tag, tag)
20
        ret[decoded] = value
21
    return ret
22
23
def get_date(fn):
24
    '''DateTimeOriginal aus datei als datetime'''
25
    info = get_exif(fn)
26
    d = info['DateTimeOriginal']
27
    return datetime.strptime(d, '%Y:%m:%d %H:%M:%S')
28
29
def build_dict(files):
30
    '''dict aus zeit und dateinamen'''
31
    res = dict()
32
    for f in files:    
33
        d = get_date(f)
34
        if d not in res:
35
            res[d] = list()
36
        res[d].append(f)
37
    return res
38
39
def sec_delta(a,b):
40
    '''abstand zwischen zwei datetimes'''
41
    td = a - b
42
    # mit python 2.7 ginge das eleganter:
43
    return abs((td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 )
44
45
def sort_and_group(di):
46
    '''list mit lists aus files mit zeitabstand <= DELTA'''
47
    res=list()
48
    dates = sorted(di.keys())
49
    last_d = dates[0]
50
    group = list()
51
    for x in di[last_d]: 
52
        group.append(x)
53
    group_saved = True
54
    for d in dates[1:]:
55
        diff = sec_delta(d , last_d)
56
        if diff > DELTA:    #neue list anfangen, alte ins ergebnis schubsen
57
            res.append(group)
58
            group = list()
59
            group_saved = True
60
        for x in di[d]:
61
            group.append(x)
62
        group_saved = False
63
        last_d = d
64
    if not group_saved:
65
        res.append(group)
66
    return res
67
68
def move_sorted(d, wd):
69
    '''order fuer jede gruppe von mehr als einem file erstellen und files verschieben, gibt nur shellbefehle aus'''
70
    num = 1
71
    for p in d:
72
        if len(p) > 1:
73
            foldername = '%s/foo_%05d' % (wd, num)
74
            num += 1
75
            print 'mkdir "%s"' % foldername
76
            for f in p:
77
                print 'mv "%s" "%s/"' % (f, foldername)
78
        else:
79
            print '# ignoring %s' % (p[0])
80
81
def list_files(d):
82
    ''' alle jpgs aus ordner d'''
83
    return [os.path.join(d, f) for f in os.listdir(d) if  re.match('\.jpe?g$', os.path.splitext(f)[1], re.IGNORECASE ) ]
84
85
if __name__ == '__main__':
86
    working_dir = sys.argv[1].rstrip('/')
87
    pics = list_files(working_dir)
88
    picswithdate = build_dict(pics)
89
90
    if False:
91
        picswithdate = dict()
92
        picswithdate[datetime(2010, 1, 1, 2, 3, 4)] = ['a0']
93
        picswithdate[datetime(2010, 1, 1, 2, 3, 5)] = ['a1']
94
        picswithdate[datetime(2010, 1, 1, 2, 3, 12)] = ['a2']
95
        picswithdate[datetime(2010, 1, 1, 2, 3, 12)].append('a3')
96
        picswithdate[datetime(2010, 1, 1, 2, 3, 13)] = ['a4']
97
        picswithdate[datetime(2010, 1, 1, 2, 3, 30)] = ['a5']
98
        picswithdate[datetime(2010, 1, 1, 2, 3, 32)] = ['a6']
99
    pics_sorted = sort_and_group(picswithdate)
100
    move_sorted(pics_sorted, working_dir)