Example #1
0
    def is_size_ok(self, index):
        model = self.sourceModel()

        size = model.data(index, QtCore.Qt.UserRole+5).toPyObject()
        if size is None:
            return True

        width, height = size
        if width * height == 0:
            photo_id = model.data(index, QtCore.Qt.UserRole+7).toPyObject()
            path = model.data(index, QtCore.Qt.UserRole+6).toPyObject()
            if path is not None and photo_id is not None and os.path.exists(path):
                # Fix up the database by reading the image
                image = Image.open(str(path))
                width, height = image.size
                Photo.upsert({'id': photo_id, 'width': width, 'height': height})
            else:
                return False

        if (width * height) < 20000:
            return False

        space_used = (6 * height) / (8 * width)
        if space_used > 1:
            space_used = 1 / space_used

        if space_used < 0.95:
            return False

        return True
Example #2
0
 def person_updated(self, origin):
     if not origin - set(['CropFrame']):
         return
     if self.person.current_photo_id is None:
         return
     if self.photo is not None and self.photo.id == self.person.current_photo_id:
         return
     if self.photo is not None:
         self.photo.updated.disconnect(self.photo_updated)
     self.photo = Photo.get(id=self.person.current_photo_id)
     self.photo.updated.connect(self.photo_updated)
     self.photo_load_retries = 0
     self.photo_updated(set(['init']))
Example #3
0
    def load_person(self, id, refresh=False):
        if self.photo_load_failed:
            return

        p = self.image_list_items[id].person
        photo = self.image_list_items[id].photo

        # Suppress history updates when changing the item with
        # back/forwards, because they have special handling
        if not self.suppress_history and self.current_photo is not None and self.current_person.id != id:
            self.history_back.append(self.current_person.id)
            self.back.setDisabled(False)
            self.history_forwards.clear()
            self.forwards.setDisabled(True)
            while len(self.history_back) > 10:
                self.history_back.popleft()

        self.clear_image()
        self.history_model.clear()
        self.current_person = p

        self.info_person_id.setText('%d' % self.current_person.id)
        self.info_fullname.setText(self.current_person.fullname)
        self.info_title.setText(self.current_person.title)
        self.info_firstname.setText(self.current_person.firstname)
        self.info_lastname.setText(self.current_person.lastname)
        self.info_police_status.setText(self.current_person.police_status)
        self.info_person_fetched_at.setText(time.ctime(self.current_person.last_checked_at))

        if photo is not None and photo.full_path() is not None:
            self.current_photo = photo
            filename = self.current_photo.local_filename()
            self.info_photo_filename.setText(filename if filename else '')
            self.info_photo_fetched_at.setText(time.ctime(self.current_photo.date_fetched))
            self.person_name.setText(u'Loading %s...' % p)
            self.upload_wizard.upload_photos_thisname.setText(unicode(p))

            self.main_photo_cache.load_image(photo.id, photo.full_path(), photo.url,
                                             ready_cb=self.handle_photo_ready,
                                             fail_cb=self.handle_photo_fail,
                                             urgent=True, refresh=refresh,
                                             )
        else:
            self.person_name.setText(unicode(self.current_person))

        photos = Photo.by_person(self.current_person.id)
        self.history_model.clear()
        self.history_items = {}
        for photo in sorted(photos, key=lambda photo: photo.date_fetched, reverse=True):
            item = QtGui.QStandardItem()
            msg = "Fetched at %s" % time.ctime(photo.date_fetched)
            if self.current_person.current_photo_id == photo.id:
                msg = msg + "\nCurrent photo"
            else:
                msg = msg + "\n%s" % photo.opinion
            item.setText(msg)
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            item.setData(photo.id)
            self.history_items[photo.id] = item
            self.history_model.appendRow(item)
            self.list_photo_cache.load_image(photo.id, photo.full_path(), photo.url,
                                             ready_cb=self.handle_history_photo_ready)
Example #4
0
    def __init__(self, dbmanager, parent=None):
        super(QtGui.QWidget, self).__init__(parent)
        self.setupUi(self)

        self.setWindowTitle('Image Editing v' + ef.__version__)

        self.settings = QtCore.QSettings()

        self.main_stack.setCurrentIndex(0)

        self.username = self.settings.value('ef-username', '').toString()
        self.ef_username.setText(self.username)
        self.password = ''
        self.try_login = TryLogin()
        self.try_login.completed.connect(self.try_login_completed)
        self.try_login.error.connect(self.try_login_error)
        self.ef_login.clicked.connect(self.try_ef_login)
        self.ef_password.returnPressed.connect(self.try_ef_login)

        self.history_make_current.setIcon(self.style().standardIcon(QtGui.QStyle.SP_ArrowRight))
        self.back.setIcon(self.style().standardIcon(QtGui.QStyle.SP_ArrowBack))
        self.forwards.setIcon(self.style().standardIcon(QtGui.QStyle.SP_ArrowForward))
        self.back.setDisabled(True)
        self.forwards.setDisabled(True)

        self.photodownloader = PhotoDownloader()
        self.list_photo_cache = ThumbnailCache(self.photodownloader, 100)
        self.main_photo_cache = PhotoImageCache(self.photodownloader, 10)
        self.fetcher = Fetcher()
        self.reportsfetcher = ReportsFetcher()
        self.uploader = Uploader()
        self.current_person = None
        self.current_photo = None
        self.current_image = None
        self.loading_now = False
        self.photo_load_failed = False
        self.registration_loaded = self.person_loaded = False

        self.history_back = deque()
        self.history_forwards = deque()
        self.suppress_history = False

        self.upload_wizard = UploadPeopleWizard()

        self.image_list_items = {}

        self.edit_scene = QtGui.QGraphicsScene(self)
        self.main_image.setScene(self.edit_scene)

        self.main_pixmap = EditPixmap(self.wheel_event)
        self.edit_scene.addItem(self.main_pixmap)

        self.crop_frame = CropFrame(self.main_pixmap, self.output_updated)

        self.main_pixmap.setZValue(1)
        self.crop_frame.setZValue(2)

        self.events = {}
        self.event_load_handlers = {}

        self.person_model = QtGui.QStandardItemModel(self)
        self.person_model.setColumnCount(1)

        self.person_model_proxy = FilterProxyModel()
        self.person_model_proxy.setDynamicSortFilter(True)
        self.person_model_proxy.setSourceModel(self.person_model)
        self.person_model_proxy.setSortCaseSensitivity(False)
        self.person_model_proxy.setSortRole(QtCore.Qt.UserRole+1)
        self.person_model_proxy.sort(0)

        self.person_model_proxy.rowsInserted.connect(self.handle_filter_count)
        self.person_model_proxy.rowsRemoved.connect(self.handle_filter_count)
        self.person_model_proxy.modelReset.connect(self.handle_filter_count)

        self.filter_opinion.currentIndexChanged[str].connect(self.person_model_proxy.set_opinion)
        self.filter_DNU.currentIndexChanged[str].connect(self.person_model_proxy.set_DNU)
        self.filter_event.currentIndexChanged[int].connect(self.handle_filter_event_changed)
        self.filter_category.currentIndexChanged[str].connect(self.person_model_proxy.set_category)
        self.filter_police.currentIndexChanged[str].connect(self.person_model_proxy.set_police_status)
        self.filter_by_size.stateChanged.connect(self.person_model_proxy.set_only_bad_sizes)
        self.filter_only_missing.stateChanged.connect(self.person_model_proxy.set_only_missing)
        self.filter_only_upload.stateChanged.connect(self.person_model_proxy.set_only_upload)

        self.filters_reset.clicked.connect(self.handle_reset_filters)
        self.export_people.clicked.connect(self.handle_export_people)

        self.history_model = QtGui.QStandardItemModel(self)
        self.history_model.setColumnCount(1)

        self.history_list.setModel(self.history_model)
        self.history_items = {}
        self.history_make_current.clicked.connect(self.handle_historymakecurrent)

        self.dbmanager = dbmanager
        dbmanager.created.connect(self.handle_db_created)
        dbmanager.exception.connect(self.handle_db_exception)
        dbmanager.existing_done.connect(self.handle_db_existing_done)
        dbmanager.process_done.connect(self.handle_db_process_done)
        Photo.signal_existing_created()
        Registration.signal_existing_created()
        Event.signal_existing_created()
        Person.signal_existing_created()

        self.output_updated.connect(self.handle_crop)
        self.wheel_event.connect(self.crop_frame.handle_wheel)
        self.opinion_ok.clicked.connect(self.handle_opinion_ok)
        self.opinion_bad.clicked.connect(self.handle_opinion_bad)
        self.opinion_unsure.clicked.connect(self.handle_opinion_unsure)
        self.do_not_upload.stateChanged.connect(self.handle_do_not_upload)
        self.back.clicked.connect(self.handle_back)
        self.forwards.clicked.connect(self.handle_forwards)
        self.search.clicked.connect(self.handle_search)
        self.search_for.returnPressed.connect(self.handle_search)

        self.action_fetch.triggered.connect(self.handle_fetch_wizard)
        self.fetch_this_person.clicked.connect(self.handle_fetch_person)

        self.fetcher.completed.connect(self.handle_fetch_completed)
        self.fetcher.error.connect(self.handle_fetch_error)
        self.fetcher.progress.connect(self.handle_fetch_progress)

        self.reportsfetcher.error.connect(self.handle_reportsfetch_error)

        self.action_upload.triggered.connect(self.handle_upload_wizard)
        self.upload_wizard.accepted.connect(self.handle_upload)
        self.upload_wizard.rejected.connect(self.handle_upload_rejected)

        self.uploader.completed.connect(self.handle_upload_completed)
        self.uploader.error.connect(self.handle_upload_error)
        self.uploader.progress.connect(self.handle_upload_progress)

        self.rotate.valueChanged.connect(self.handle_rotate)
        self.rotate_0.clicked.connect(lambda: self.rotate.setValue(0))
        self.rotate_l90.clicked.connect(lambda: self.rotate.setValue(-90))
        self.rotate_l180.clicked.connect(lambda: self.rotate.setValue(-180))
        self.rotate_r90.clicked.connect(lambda: self.rotate.setValue(90))
        self.rotate_r180.clicked.connect(lambda: self.rotate.setValue(180))
        self.brightness_slider.valueChanged.connect(self.handle_brightness)
        self.contrast_slider.valueChanged.connect(self.handle_contrast)

        self.gamma_slider.valueChanged.connect(lambda v: self.gamma_spin.setValue(v/10))
        self.gamma_spin.valueChanged.connect(lambda v: self.gamma_slider.setValue(v*10))
        self.gamma_slider.valueChanged.connect(self.handle_gamma)

        self.action_openeventsforce.triggered.connect(self.handle_openeventsforce)
        self.openeventsforce.clicked.connect(self.handle_openeventsforce)
        self.action_reloadphoto.triggered.connect(self.handle_reloadphoto)
        self.action_editimage.triggered.connect(self.handle_editimage)
        self.editimage.clicked.connect(self.handle_editimage)
        self.action_importphoto.triggered.connect(self.handle_import_photo)

        self.openimage = QtGui.QFileDialog(self, 'Import image')
        self.openimage.setFileMode(QtGui.QFileDialog.ExistingFile)
        self.openimage.setNameFilter('*.jpg *.jpeg')
        self.openimage.restoreState(self.settings.value('openimage-state', '').toByteArray())

        self.action_chooseeditor.triggered.connect(self.handle_chooseeditor)

        self.chooseeditor = QtGui.QFileDialog(self, 'Choose image editor')
        self.chooseeditor.setFileMode(QtGui.QFileDialog.ExistingFile)
        if os.name == 'nt':
            self.chooseeditor.setNameFilter('*.exe')
        self.chooseeditor.restoreState(self.settings.value('chooseeditor-state', '').toByteArray())

        self.savereport = QtGui.QFileDialog(self, 'Save report')
        self.savereport.setFileMode(QtGui.QFileDialog.AnyFile)
        self.savereport.setAcceptMode(QtGui.QFileDialog.AcceptSave)
        self.savereport.setNameFilter('*.csv')
        self.savereport.setDefaultSuffix('csv')
        self.savereport.restoreState(self.settings.value('savereport-state', '').toByteArray())

        self.image_editor = self.settings.value('image-editor', '').toString()

        self.action_export.triggered.connect(self.handle_export)
        self.action_import.triggered.connect(self.handle_import)

        self.saveexport = QtGui.QFileDialog(self, 'Export database')
        self.saveexport.setFileMode(QtGui.QFileDialog.AnyFile)
        self.saveexport.setAcceptMode(QtGui.QFileDialog.AcceptSave)
        self.saveexport.setNameFilter('*.yaml')
        self.saveexport.setDefaultSuffix('yaml')
        self.saveexport.restoreState(self.settings.value('saveexport-state', '').toByteArray())

        self.openimport = QtGui.QFileDialog(self, 'Import database')
        self.openimport.setFileMode(QtGui.QFileDialog.ExistingFile)
        self.openimport.setNameFilter('*.yaml')
        self.openimport.restoreState(self.settings.value('openimport-state', '').toByteArray())

        self.status_expiry_timer = QtCore.QTimer(self)
        self.status_expiry_timer.setInterval(5000)
        self.status_expiry_timer.timeout.connect(self.status_idle)

        self.status_task = ''
        self.status_started = None
        self.status_timer = QtCore.QTimer(self)
        self.status_timer.setInterval(500)
        self.status_timer.timeout.connect(self.status_timer_update)
        self.status_is_idle = True

        self.draw_timer = QtCore.QTimer(self)
        self.draw_timer.setInterval(50)
        self.draw_timer.timeout.connect(self.handle_draw)
        self.draw_timer.start()
        self.image_draw_needed = False

        self.photodownloader.queue_size.connect(self.status_downloader)
        self.photodownloader.error.connect(self.photodownload_error)

        self.procs = {}

        self.status_idle()
Example #5
0
 def photodownload_error(self, id, msg):
     photo = Photo.get(id=id)
     photo.update_load_failed(True, origin='load_failed')