forked from akkana/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fotogr
executable file
·143 lines (124 loc) · 4.49 KB
/
fotogr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python
# Photo Search:
# Search under the current dir, or the first argument given,
# for grep matches within files named "Keywords".
# Then translate that to a list of full pathnames.
# Copyright 2007,2009 by Akkana Peck: share and enjoy under the GPLv2 or later.
# Wish list: Boolean logic. Currently this can search only for one
# term/phrase at a time.
import sys, os, string
def search_for_keywords(grepdirs, orpats, andpats, notpats, separate) :
'''Inside grepdirs, open files named Tags or Keywords.
Search those lines looking for matches in the keywords for pats.
'''
results = []
for d in grepdirs:
for root, dirs, files in os.walk(d) :
if not files :
continue
for f in files :
if f == "Tags" or f == "Keywords":
search_for_keywords_in(root, f, orpats, andpats, notpats,
separate, results)
break # Would prefer to break out of this root, not f
return results
def search_for_keywords_in(d, f, orpats, andpats, notpats, separate,
results=None) :
'''Search in d/f for lines matching or, and and not pats.
Those have lines in a format like:
[tag ]keyword, keyword: file.jpg file.jpg
If results is passed in, append to it, else just print.
'''
filetags = {}
for line in open(os.path.join(d, f)):
line = line.strip()
if not line:
continue
if line.startswith("tag "):
line = line[4:]
elif line.startswith("category "):
continue
# Now we know it's a tag line.
parts = line.split(':')
if len(parts) < 2:
continue
tags = parts[0].strip()
# There may be several comma-separated tags here, but we
# actually don't care about that for matching purposes.
for imgfile in parts[1].strip().split():
fullpath = os.path.join(d, imgfile)
if fullpath.startswith('./'):
fullpath = fullpath[2:]
if not os.path.exists(fullpath):
continue
if fullpath not in filetags.keys():
filetags[fullpath] = tags
else:
filetags[fullpath] += ', ' + tags
# Now we have a list of tagged files in the directory, and their tags.
for imgfile in filetags.keys():
tags = filetags[imgfile]
if has_match(tags, orpats, andpats, notpats):
if results != None:
results.append(imgfile)
elif separate:
print tags, ':', imgfile
else:
print imgfile,
def has_match(tags, orpats, andpats, notpats):
'''Do the tags contain any of the patterns in orpats,
AND all of the patterns in andpats,
AND none of the patterns in notpats?
'''
#print "Looking for OR", orpats, "AND", andpats, "NOT", notpats, "IN", tags
for pat in notpats:
if pat in tags:
return False
for pat in andpats:
if pat not in tags:
return False
if not orpats:
return True
for pat in orpats:
if pat in tags:
return True
return False
if __name__ == "__main__":
# Sadly, we can't use argparse if we want to be able to use -term
# to indicate "don't search for that term".
def Usage():
print '''Usage: %s [-s] condition [condition ...]
Search for files matching patterns in Tags or Keywords files.
Conditions can include three types of patterns:
1. Starts with +: must be present (AND).
2. Starts with -: must NOT be present (NOT).
3. Starts with neither: one of these must be present (OR).
Optional arguments:
-s, --separate print separate lines from different tag files
Copyright 1009,2014 by Akkana Peck; share and enjoy under the GPL v2 or later.''' % os.path.basename(sys.argv[0])
sys.exit(0)
args = sys.argv[1:]
if args[0] == '-h' or args[0] == '--help':
Usage()
if args[0] == '-s':
separate = True
args = args[1:]
else:
separate = False
andpats = []
orpats = []
notpats = []
for pat in args:
if pat[0] == '+':
andpats.append(pat[1:])
elif pat[0] == '-':
notpats.append(pat[1:])
else:
orpats.append(pat)
r = search_for_keywords(['.'], orpats, andpats, notpats, separate)
s = set(r)
r = list(s)
r.sort()
for f in r:
print f,
print