1
2
3
4
5 '''
6 These are the base class for metapho images and taggers.
7 Programs with better UI can inherit from these classes.
8
9 '''
10
11
12
13
14
15
16 import os
17 import collections
18
20 '''An image, with additional info such as rotation and tags.
21 '''
22
23 g_image_list = []
24
25 - def __init__(self, filename, displayed=True) :
26 '''Initialize an image filename.
27 Pass displayed=False if this image isn't to be shown
28 in the current session, only used for remembering
29 previously set tags.
30 '''
31 self.filename = filename
32 self.tags = []
33
34 self.displayed = displayed
35
36
37
38
39 self.rot = None
40
42 str = "Image %s" % self.filename
43
44 if self.rot :
45 str += " (rotation %s)" % self.rot
46
47 if self.tags :
48 str += " Tags: " + self.tags.__repr__()
49
50 str += '\n'
51
52 return str
53
55 '''Delete the image file FROM DISK, and the image object
56 from the imageList. DOES NOT ASK FOR CONFIRMATION --
57 do that (if desired) from the calling program.
58 '''
59 print "Deleting", self.filename
60 os.unlink(self.filename)
61 Image.g_image_list.remove(self)
62
63 import shlex
64
66 '''Manages tags for images.
67 '''
68
70 '''tagger: an object to manage metapho image tags'''
71
72
73
74
75
76 self.categories = collections.OrderedDict()
77
78
79
80 self.tag_list = []
81
82
83 self.tagfiles = []
84
85 self.commondir = None
86
87
88
89 self.changed = False
90
91
92 self.current_category = "Tags"
93
95 '''Returns a string summarizing all known images and tags,
96 suitable for printing on stdout or pasting into a Tags file.
97 '''
98 outstr = ''
99 for cat in self.categories :
100 outstr += '\ncategory ' + cat + '\n\n'
101
102 for tagno in self.categories[cat] :
103 tagstr = self.tag_list[tagno]
104
105
106 if tagstr.strip() == '' :
107 continue
108
109 imgstr = ''
110 for img in Image.g_image_list :
111 if tagno in img.tags :
112 if ' ' in img.filename :
113 fname = '"' + img.filename + '"'
114 else :
115 fname = img.filename
116 imgstr += ' ' + fname
117 if imgstr :
118 outstr += "tag %s :" % tagstr + imgstr + '\n'
119
120 return outstr
121
123 for i in range(len(self.categories)):
124 k,v = self.categories.popitem(False)
125 self.categories[new if old == k else k] = v
126
128 '''Save the current set of tags to a Tags file chosen from
129 the top-level directory used in the images we've seen.
130 If there was a previous Tags file there, it will be saved
131 as Tags.bak.
132 '''
133 if not self.changed :
134 print "No tags changed; not rewriting Tags file"
135 return
136
137 outpath = os.path.join(self.commondir, "Tags")
138 print "Saving to", outpath
139 if os.path.exists(outpath) :
140 os.rename(outpath, outpath + ".bak")
141 outfile = open(outpath, "w")
142 outfile.write(str(self))
143 outfile.close()
144
241
243 '''After reading a tag from a tags file, add it to the global
244 tags list if it isn't there already, and add the given filenames
245 to it.
246 '''
247 try :
248 tagindex = self.tag_list.index(tagname)
249 except :
250 tagindex = len(self.tag_list)
251 self.tag_list.append(tagname)
252
253 try :
254 self.categories[self.current_category].append(tagindex)
255
256
257 except KeyError :
258 self.categories[self.current_category] = [tagindex]
259
260
261
262
263
264 for fil in filenames :
265 tagged = False
266 for img in Image.g_image_list :
267 if img.filename.endswith(fil) and tagindex not in img.tags :
268 img.tags.append(tagindex)
269 tagged = True
270 break
271
272
273 if not tagged :
274 newim = Image(fil, displayed=False)
275 newim.tags.append(tagindex)
276 Image.g_image_list.append(newim)
277
279 '''Add a tag to the given image.
280 img is a metapho.Image.
281 tag may be a string, which can be a new string or an existing one,
282 or an integer index into the tag list.
283 Return the index (in the global tags list) of the tag just added,
284 or None if error.
285 '''
286 self.changed = True
287
288 if type(tag) is int :
289 if tag not in img.tags :
290 img.tags.append(tag)
291 return tag
292
293
294 if tag in self.tag_list :
295 tagno = self.tag_list.index(tag)
296 if tagno not in self.categories[self.current_category] :
297 self.categories[self.current_category].append(tagno)
298 img.tags.append(tagno)
299 return tagno
300
301 self.tag_list.append(tag)
302 newindex = len(self.tag_list) - 1
303 img.tags.append(newindex)
304 self.categories[self.current_category].append(newindex)
305 return newindex
306
308 self.changed = True
309
310 if type(tag) is int :
311 if tag in img.tags :
312 img.tags.remove(tag)
313
314
315 try :
316 self.tag_list.remove(tag)
317 except :
318 pass
319
322
324 '''Toggle tag number tagno for the given img.'''
325 self.changed = True
326
327 if tagno in img.tags :
328 img.tags.remove(tagno)
329 return
330
331
332
333
334
335 img.tags.append(tagno)
336
338 '''Return a list of tags matching the pattern.'''
339 return None
340