Use list.sort's keyword parameters
[joel/kofoto.git] / src / packages / kofoto / gkofoto / handleimagesdialog.py
1 import gtk
2 import gobject
3 import os
4 from kofoto.gkofoto.environment import env
5 from kofoto.shelf import \
6      ImageVersionDoesNotExistError, \
7      MultipleImageVersionsAtOneLocationError, \
8      computeImageHash
9 from kofoto.clientutils import walk_files
10
11 class HandleImagesDialog(gtk.FileChooserDialog):
12     def __init__(self):
13         gtk.FileChooserDialog.__init__(
14             self,
15             title="Handle images",
16             action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
17             buttons=(
18                 gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
19                 gtk.STOCK_OK, gtk.RESPONSE_OK))
20         self.connect("response", self._response)
21
22     def _response(self, unused, responseId):
23         self.hide()
24         if responseId != gtk.RESPONSE_OK:
25             return
26         widgets = gtk.glade.XML(env.gladeFile, "handleImagesProgressDialog")
27         handleImagesProgressDialog = widgets.get_widget(
28             "handleImagesProgressDialog")
29         knownUnchangedImagesCount = widgets.get_widget(
30             "knownUnchangedImagesCount")
31         knownMovedImagesCount = widgets.get_widget(
32             "knownMovedImagesCount")
33         unknownModifiedImagesCount = widgets.get_widget(
34             "unknownModifiedImagesCount")
35         unknownFilesCount = widgets.get_widget(
36             "unknownFilesCount")
37         investigatedFilesCount = widgets.get_widget(
38             "investigatedFilesCount")
39         okButton = widgets.get_widget("okButton")
40         okButton.set_sensitive(False)
41
42         handleImagesProgressDialog.show()
43
44         knownUnchangedImages = 0
45         knownMovedImages = 0
46         unknownModifiedImages = 0
47         unknownFiles = 0
48         investigatedFiles = 0
49         modifiedImages = []
50         movedImages = []
51         try:
52             directory = self.get_filename().decode("utf-8")
53         except UnicodeDecodeError:
54             directory = self.get_filename().decode("latin1")
55         for filepath in walk_files([directory]):
56             try:
57                 imageversion = env.shelf.getImageVersionByHash(
58                     computeImageHash(filepath))
59                 if imageversion.getLocation() == os.path.realpath(filepath):
60                     # Registered.
61                     knownUnchangedImages += 1
62                     knownUnchangedImagesCount.set_text(
63                         str(knownUnchangedImages))
64                 else:
65                     # Moved.
66                     knownMovedImages += 1
67                     knownMovedImagesCount.set_text(str(knownMovedImages))
68                     movedImages.append(filepath)
69             except ImageVersionDoesNotExistError:
70                 try:
71                     env.shelf.getImageVersionByLocation(filepath)
72                     # Modified.
73                     unknownModifiedImages += 1
74                     unknownModifiedImagesCount.set_text(
75                         str(unknownModifiedImages))
76                     modifiedImages.append(filepath)
77                 except MultipleImageVersionsAtOneLocationError:
78                     # Multiple images at one location.
79                     # TODO: Handle this error.
80                     pass
81                 except ImageVersionDoesNotExistError:
82                     # Unregistered.
83                     unknownFiles += 1
84                     unknownFilesCount.set_text(str(unknownFiles))
85             investigatedFiles += 1
86             investigatedFilesCount.set_text(str(investigatedFiles))
87             while gtk.events_pending():
88                 gtk.main_iteration()
89
90         okButton.set_sensitive(True)
91         handleImagesProgressDialog.run()
92         handleImagesProgressDialog.destroy()
93
94         if modifiedImages or movedImages:
95             if modifiedImages:
96                 self._dialogHelper(
97                     "Update modified images",
98                     "The above image files have been modified. Press OK to"
99                     " make Kofoto recognize the new contents.",
100                     modifiedImages,
101                     self._updateModifiedImages)
102             if movedImages:
103                 self._dialogHelper(
104                     "Update moved or renamed images",
105                     "The above image files have been moved or renamed. Press OK to"
106                     " make Kofoto recognize the new locations.",
107                     movedImages,
108                     self._updateMovedImages)
109         else:
110             dialog = gtk.MessageDialog(
111                 type=gtk.MESSAGE_INFO,
112                 buttons=gtk.BUTTONS_OK,
113                 message_format="No modified, renamed or moved images found.")
114             dialog.run()
115             dialog.destroy()
116
117     def _dialogHelper(self, title, text, filepaths, handlerFunction):
118         widgets = gtk.glade.XML(env.gladeFile, "updateImagesDialog")
119         dialog = widgets.get_widget("updateImagesDialog")
120         dialog.set_title(title)
121         filenameList = widgets.get_widget("filenameList")
122         renderer = gtk.CellRendererText()
123         column = gtk.TreeViewColumn("Image filename", renderer, text=0)
124         filenameList.append_column(column)
125         dialogText = widgets.get_widget("dialogText")
126         dialogText.set_text(text)
127         model = gtk.ListStore(gobject.TYPE_STRING)
128         for filepath in filepaths:
129             model.append([filepath])
130         filenameList.set_model(model)
131         if dialog.run() == gtk.RESPONSE_OK:
132             handlerFunction(filepaths)
133         dialog.destroy()
134
135     def _error(self, errorText):
136         dialog = gtk.MessageDialog(
137             type=gtk.MESSAGE_ERROR,
138             buttons=gtk.BUTTONS_OK,
139             message_format=errorText)
140         dialog.run()
141         dialog.destroy()
142
143     def _updateModifiedImages(self, filepaths):
144         for filepath in filepaths:
145             try:
146                 imageversion = env.shelf.getImageVersionByLocation(filepath)
147                 imageversion.contentChanged()
148             except ImageVersionDoesNotExistError:
149                 self._error("Image does not exist: %s" % filepath)
150             except MultipleImageVersionsAtOneLocationError:
151                 # TODO: Handle this.
152                 pass
153             except IOError, x:
154                 self._error("Error while reading %s: %s" % (
155                     filepath, x))
156
157     def _updateMovedImages(self, filepaths):
158         for filepath in filepaths:
159             try:
160                 imageversion = env.shelf.getImageVersionByHash(
161                     computeImageHash(filepath))
162                 imageversion.locationChanged(filepath)
163             except ImageVersionDoesNotExistError:
164                 self._error("Image does not exist: %s" % filepath)
165             except MultipleImageVersionsAtOneLocationError:
166                 # TODO: Handle this.
167                 pass
168             except IOError, x:
169                 self._error("Error while reading %s: %s" % (
170                     filepath, x))