diff --git a/photosorter-tests.py b/photosorter-tests.py index 5d488f7..5cdd7c0 100755 --- a/photosorter-tests.py +++ b/photosorter-tests.py @@ -36,7 +36,7 @@ def test_transforms(self): for i in range(0, 5): p.rotate_clockwise(f) p.flip_horizontal(f) - p.delete(f) + p.delete_photo(f, p.CURRENT_BUCKET) self.assertEquals(f.rotation, 90) self.assertEquals(f.flip_horizontal, True) self.assertEquals(f.delete, True) @@ -192,7 +192,6 @@ def direction(): buckets = [] PhotoSorter._tree_traverse(p.buckets, buckets) - print "bux", buckets self.assertEquals(buckets[0].before, buckets[2].unsorted) self.assertEquals(buckets[0].after, buckets[1].unsorted) self.assertEquals(buckets[0].unknown, set([2])) diff --git a/photosorter.py b/photosorter.py index a80cfe5..20c28d9 100755 --- a/photosorter.py +++ b/photosorter.py @@ -146,8 +146,9 @@ def rotate_clockwise(self, photo): def flip_horizontal(self, photo): photo.flip_horizontal ^= True # use xor in case of a double-flip - def delete_photo(self, photo): + def delete_photo(self, photo, bucket): photo.delete = True + bucket.unsorted -= set([photo]) ## sort related methods @@ -162,8 +163,12 @@ def next_photo(self): while True: for f in copy(self.CURRENT_BUCKET.unsorted): if f in sorted(self.CURRENT_BUCKET.unsorted): - self.CURRENT_PHOTO = f - yield f + # minor hack here (checking type) for testing + if type(f) is Photo and f.delete is True: + continue + else: + self.CURRENT_PHOTO = f + yield f else: break break @@ -194,20 +199,6 @@ def _tree_traverse(cls, l, pivot_list): pass -# @classmethod -# def _tree_traverse(cls, l, pivot_list): -# if len(l) == 0: -# return -# -# elif len(l) == 1: -# pivot_list.append(l[0]) -# return -# -# pivot = l[(len(l)/2)] -# pivot_list.append(pivot) -# cls._tree_traverse(l[0:(len(l)/2)], pivot_list) -# cls._tree_traverse(l[(len(l)/2)+1:], pivot_list) - def next_bucket(self): """Generator which yields a bucket to sort on. Buckets will be handed back in a tree-like fashion to produce a sorting effect similar to quicksort""" @@ -234,16 +225,19 @@ def sort_photo(self, photo, bucket, direction): # earlier or later bucket based on sort direction bucketsInOrder = [] - self._tree_traverse(sorted(self.buckets), bucketsInOrder) - bucketsInOrder = bucketsInOrder[bucketsInOrder.index(bucket)+1:] + self._tree_traverse(self.buckets, bucketsInOrder) earlierBucket = None laterBucket = None - for b in bucketsInOrder: - if b < bucket: + for b in bucketsInOrder[bucketsInOrder.index(bucket)+1:]: + # avoid a corner case where photos are added as unsorted to buckets + # far less than the starting bucket. this happens because the bucket + # traversal happens ascending first, then descending; so only add to + # lower buckets if we're sorting downwards. if that makes sense. + if b < bucket < bucketsInOrder[0]: earlierBucket = b break - for b in bucketsInOrder: + for b in bucketsInOrder[bucketsInOrder.index(bucket)+1:]: if b > bucket: laterBucket = b break @@ -292,9 +286,6 @@ def merge_during(self): - - - class PhotoSorterGui(object): def __init__(self): self.image = None @@ -374,6 +365,18 @@ def quit(self, widget, event): self.photoSortingBackend.dump() gtk.main_quit() + + def _display_image(self): + self.image.set_from_file(self.photoSortingBackend.CURRENT_PHOTO.filename) + + rotation = 0 + while rotation < self.photoSortingBackend.CURRENT_PHOTO.rotation: + self.image.set_from_pixbuf(self.image.get_pixbuf().rotate_simple(gtk.gdk.PIXBUF_ROTATE_CLOCKWISE)) + rotation += 90 + + if self.photoSortingBackend.CURRENT_PHOTO.flip_horizontal: + self.image.set_from_pixbuf(self.image.get_pixbuf().flip(True)) + def redraw_window(self, increment=False): if increment is True: # use photo sorting backend's funky generators. very weird try/except @@ -384,7 +387,6 @@ def redraw_window(self, increment=False): # still keep generating photos. try: self.photoGenerator.next() - self.image.set_from_file(self.photoSortingBackend.CURRENT_PHOTO.filename) # current bucket has no more photos except StopIteration: @@ -424,12 +426,13 @@ def redraw_window(self, increment=False): try: self.photoGenerator = self.photoSortingBackend.next_photo() self.photoGenerator.next() - self.image.set_from_file(self.photoSortingBackend.CURRENT_PHOTO.filename) except StopIteration: self.redraw_window(increment=increment) + if self.photoSortingBackend.CURRENT_PHOTO is not None: self.currentFilenameLabel.set_text(os.path.basename(self.photoSortingBackend.CURRENT_PHOTO.filename)) + self._display_image() try: self.progressbar.set_fraction(float((1.0*self.sortedItems) / self.totalItems)) @@ -452,15 +455,6 @@ def redraw_window(self, increment=False): def keyboard_command(self, widget, event): try: - if chr(event.keyval).upper() == "A": - pass - - if chr(event.keyval).upper() == "B": - pass - - if chr(event.keyval).upper() == "N": - pass - # 1: photo is before current bucket if chr(event.keyval) == "1": if self.photoSortingBackend.CURRENT_PHOTO is not None: @@ -499,6 +493,13 @@ def keyboard_command(self, widget, event): # H: flip photo horizontally if chr(event.keyval).upper() == "H": self.photoSortingBackend.flip_horizontal(self.photoSortingBackend.CURRENT_PHOTO) + + # X: delete photo + if chr(event.keyval).upper() == "X": + self.photoSortingBackend.delete_photo(self.photoSortingBackend.CURRENT_PHOTO, + self.photoSortingBackend.CURRENT_BUCKET) + self.sortedItems += 1 + self.redraw_window(increment=True) # Q: dump state and quit if chr(event.keyval).upper() == "Q":