from PyQt4.QtGui import *
from PyQt4.QtSql import *
+class MergePreview(QDialog):
+ def __init__(self, parent=None):
+ QDialog.__init__(self, parent)
+ self.layout = QGridLayout()
+ self.okay = QPushButton("Import")
+ self.bad = QPushButton("Cancel")
+ self.scrollarea = QScrollArea()
+ self.scrollcontents = QWidget()
+ self.scrollcontents.resize(700,600)
+ self.innerlayout = QGridLayout()
+ self.scrollcontents.setLayout(self.innerlayout)
+ self.layout.addWidget(self.scrollarea, 0, 0, 1, 2)
+ self.layout.addWidget(self.okay, 1, 0 )
+ self.layout.addWidget(self.bad, 1, 1 )
+ self.scrollarea.setWidget(self.scrollcontents)
+ QObject.connect( self.okay, SIGNAL("clicked()"), self.accept )
+ QObject.connect( self.bad, SIGNAL("clicked()"), self.reject )
+ self.setLayout(self.layout)
+ self.resize(750,600)
+ def addToList(self, name, photo):
+ row = self.innerlayout.rowCount()
+ name_label = QLabel(name)
+ name_label.setAlignment(Qt.AlignCenter)
+ self.innerlayout.addWidget(name_label, row, 0)
+ pic_label = QLabel()
+ pic_label.setAlignment(Qt.AlignCenter)
+ pic_label.setPixmap(photo)
+ self.innerlayout.addWidget(pic_label, row, 1)
+ def doneAdding(self):
+ self.scrollcontents.resize(700, (self.innerlayout.rowCount()+1) * 300)
+
+
class MergePhotos(QWidget):
def __init__(self, parent=None, db=None):
QWidget.__init__(self, parent)
dir = QDir(foldertext)
#dir.setNameFilters(["*.jpg", "*.JPG"])
q = QSqlQuery(self.db)
- q.exec_("SELECT id, netid FROM people WHERE photo IS NULL")
+ q.exec_("SELECT id, netid, forename, surname FROM people WHERE photo IS NULL")
rec = q.record()
col_id = rec.indexOf("id")
col_netid = rec.indexOf("netid")
- while q.next():
- # if netid.jpg exists, load it, write it to a QByteArray, bind it, and update that row
- fileName = q.value(col_netid).toString() + QString(".jpg")
+ col_forename = rec.indexOf("forename")
+ col_surname = rec.indexOf("surname")
+ people = [] # Tuples of (id, netid, name)
+ while q.next(): # Fetch results
+ people.append( (q.value(col_id).toString(), q.value(col_netid).toString(), q.value(col_forename).toString() + QString(" ") + q.value(col_surname).toString() ) )
+ merging_people = [] # records that have matching photos
+ filelist = [] # the corresponding photos
+ for person in people:
+ fileName = person[1] + QString(".jpg")
if not dir.exists(fileName):
- fileName = q.value(col_netid).toString() + QString(".JPG")
+ fileName = person[1] + QString(".JPG")
if dir.exists(fileName):
+ merging_people.append(person)
+ filelist.append(fileName)
+ # Generate preview
+ preview = MergePreview(self)
+ progress = QProgressDialog("Preparing preview...", "Cancel", 0, len(merging_people))
+ progress.setWindowModality(Qt.WindowModal)
+ for i in xrange(len(merging_people)):
+ progress.setValue(i)
+ if progress.wasCanceled():
+ progress.setValue(len(merging_people))
+ return
+ image = QImage()
+ image.load(dir.absoluteFilePath(filelist[i]))
+ preview.addToList( merging_people[i][2] + QString("\n") + merging_people[i][1], QPixmap.fromImage(image.scaled(QSize(400,300), Qt.KeepAspectRatio)) )
+ progress.setValue(len(merging_people))
+ preview.doneAdding()
+
+ if not preview.exec_():
+ return
+
+ # If preview accepted, proceed with the import
+ progress = QProgressDialog("Importing photos...", "Can't cancel!", 0, len(merging_people))
+ progress.setWindowModality(Qt.WindowModal)
+ for i in xrange(len(merging_people)):
+ progress.setValue(i)
+ progress.setLabelText(QString("Importing photo for %1...").arg(merging_people[i][2]) )
+ # if netid.jpg exists, load it, write it to a QByteArray, bind it, and update that row
+ image = QImage()
+ image.load(dir.absoluteFilePath(filelist[i]))
+ ba = QByteArray()
+ buffer = QBuffer(ba)
+ buffer.open(QIODevice.WriteOnly)
+ image.save(buffer, "JPG")
+ buffer.close()
+ update_q = QSqlQuery(self.db)
+ update_q.prepare("UPDATE people SET photo=:photo WHERE id=:id")
+ update_q.bindValue(":photo", QVariant(ba))
+ update_q.bindValue(":id", merging_people[i][0])
+ update_q.exec_()
+ print "Auto-imported photo for", merging_people[i][2]
+ progress.setValue(len(merging_people))
+ self.done()
+
+ def beginMergeTimestamp(self):
+ foldertext = QFileDialog.getExistingDirectory( None, "Pick folder of photos", ".")
+ if not foldertext.isEmpty():
+ print foldertext
+ dir = QDir(foldertext)
+ dir.setNameFilters(["*.jpg", "*.JPG"]) # Only import jpegs (for now)
+ dir.setFilter(QDir.Files | QDir.Readable) # Don't list subdirectories
+ dir.setSorting(QDir.Time) # Sort by mtime (should probably make this sort by ctime, or better, EXIF ctime, but in the general case this should work)
+ q = QSqlQuery(self.db)
+ q.exec_("SELECT id, forename, surname FROM people WHERE photo IS NULL ORDER BY createtime")
+ rec = q.record()
+ col_id = rec.indexOf("id")
+ col_forename = rec.indexOf("forename")
+ col_surname = rec.indexOf("surname")
+ people = [] # List of tuples (id, name)
+ while q.next():
+ people.append( (q.value(col_id).toString(), q.value(col_forename).toString() + QString(" ") + q.value(col_surname).toString() ) )
+ photofiles = dir.entryList()
+ print len(people), "people without photos"
+ print len(photofiles), "photo files provided"
+ if len(people) == len(photofiles):
+ print "merging by timestamp possible, generating preview"
+ preview = MergePreview(self)
+ # do some progress bar magic
+ progress = QProgressDialog("Preparing preview...", "Cancel", 0, len(people) )
+ progress.setWindowModality(Qt.WindowModal)
+ for i in xrange(len(people)):
+ progress.setValue(i)
+ if progress.wasCanceled():
+ progress.setValue(len(people))
+ return
image = QImage()
- image.load(dir.absoluteFilePath(fileName))
+ image.load(dir.absoluteFilePath(photofiles[i]))
+ preview.addToList(people[i][1], QPixmap.fromImage(image.scaled(QSize(400,300), Qt.KeepAspectRatio)) )
+ progress.setValue(len(people))
+ preview.doneAdding()
+
+ if not preview.exec_():
+ return
+
+ # If preview accepted, proceed with the import
+ progress = QProgressDialog("Importing photos...", "Abort", 0, len(people))
+ progress.setWindowModality(Qt.WindowModal)
+ for i in xrange(len(people)):
+ progress.setValue(i)
+ progress.setLabelText(QString("Importing photo for %1...").arg(people[i][1] ))
+ if progress.wasCanceled():
+ progress.setValue(len(people))
+ return
+ image = QImage()
+ image.load(dir.absoluteFilePath(photofiles[i]))
ba = QByteArray()
buffer = QBuffer(ba)
buffer.open(QIODevice.WriteOnly)
update_q = QSqlQuery(self.db)
update_q.prepare("UPDATE people SET photo=:photo WHERE id=:id")
update_q.bindValue(":photo", QVariant(ba))
- update_q.bindValue(":id", q.value(col_id))
+ update_q.bindValue(":id", people[i][0])
update_q.exec_()
- print "Auto-imported photo for",q.value(col_netid).toString()
- self.done()
-
- def beginMergeTimestamp(self):
- print "merging by timestamp"
- self.done()
+ print "Auto-imported photo for", people[i][1]
+ progress.setValue(len(people))
+ self.done()
+ else:
+ print "incorrect number of photos, can't merge"
def done(self):
self.emit(SIGNAL("done()") )