mirror of
				https://github.com/arsenetar/dupeguru.git
				synced 2025-09-11 17:58:17 +00:00 
			
		
		
		
	[#201 state:fixed] Added an EXIF Timestamp column in PE.
This commit is contained in:
		
							parent
							
								
									20320f539f
								
							
						
					
					
						commit
						75b08125c0
					
				@ -22,6 +22,7 @@ http://www.hardcoded.net/licenses/bsd_license
 | 
			
		||||
        {@"size", 63, 16, 0, YES, nil},
 | 
			
		||||
        {@"extension", 40, 16, 0, YES, nil},
 | 
			
		||||
        {@"dimensions", 73, 16, 0, YES, nil},
 | 
			
		||||
        {@"exif_timestamp", 120, 16, 0, YES, nil},
 | 
			
		||||
        {@"mtime", 120, 16, 0, YES, nil},
 | 
			
		||||
        {@"percentage", 58, 16, 0, YES, nil},
 | 
			
		||||
        {@"dupe_count", 80, 16, 0, YES, nil},
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ def get_delta_dimensions(value, ref_value):
 | 
			
		||||
 | 
			
		||||
class DupeGuru(DupeGuruBase):
 | 
			
		||||
    NAME = __appname__
 | 
			
		||||
    METADATA_TO_READ = ['size', 'mtime', 'dimensions']
 | 
			
		||||
    METADATA_TO_READ = ['size', 'mtime', 'dimensions', 'exif_timestamp']
 | 
			
		||||
    
 | 
			
		||||
    def __init__(self, view, appdata):
 | 
			
		||||
        DupeGuruBase.__init__(self, view, appdata)
 | 
			
		||||
@ -54,6 +54,7 @@ class DupeGuru(DupeGuruBase):
 | 
			
		||||
            'size': format_size(size, 0, 1, False),
 | 
			
		||||
            'extension': dupe.extension,
 | 
			
		||||
            'dimensions': format_dimensions(dimensions),
 | 
			
		||||
            'exif_timestamp': dupe.exif_timestamp,
 | 
			
		||||
            'mtime': format_timestamp(mtime, delta and m),
 | 
			
		||||
            'percentage': format_perc(percentage),
 | 
			
		||||
            'dupe_count': format_dupe_count(dupe_count),
 | 
			
		||||
 | 
			
		||||
@ -6,26 +6,18 @@
 | 
			
		||||
# which should be included with this package. The terms are also available at 
 | 
			
		||||
# http://www.hardcoded.net/licenses/bsd_license
 | 
			
		||||
 | 
			
		||||
import logging
 | 
			
		||||
from collections import defaultdict
 | 
			
		||||
from itertools import combinations
 | 
			
		||||
 | 
			
		||||
from hscommon import io
 | 
			
		||||
from hscommon.trans import tr
 | 
			
		||||
 | 
			
		||||
from core.engine import Match
 | 
			
		||||
from . import exif
 | 
			
		||||
 | 
			
		||||
def getmatches(files, match_scaled, j):
 | 
			
		||||
    timestamp2pic = defaultdict(set)
 | 
			
		||||
    for picture in j.iter_with_progress(files, tr("Read EXIF of %d/%d pictures")):
 | 
			
		||||
        try:
 | 
			
		||||
            with io.open(picture.path, 'rb') as fp:
 | 
			
		||||
                exifdata = exif.get_fields(fp)
 | 
			
		||||
                timestamp = exifdata['DateTimeOriginal']
 | 
			
		||||
                timestamp2pic[timestamp].add(picture)
 | 
			
		||||
        except Exception:
 | 
			
		||||
            logging.info("Couldn't read EXIF of picture: %s", picture.path)
 | 
			
		||||
        timestamp = picture.exif_timestamp
 | 
			
		||||
        timestamp2pic[timestamp].add(picture)
 | 
			
		||||
    if '0000:00:00 00:00:00' in timestamp2pic: # very likely false matches
 | 
			
		||||
        del timestamp2pic['0000:00:00 00:00:00']
 | 
			
		||||
    matches = []
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@
 | 
			
		||||
# which should be included with this package. The terms are also available at 
 | 
			
		||||
# http://www.hardcoded.net/licenses/bsd_license
 | 
			
		||||
 | 
			
		||||
from hscommon import io
 | 
			
		||||
import logging
 | 
			
		||||
from hscommon.util import get_file_ext
 | 
			
		||||
from core import fs
 | 
			
		||||
from . import exif
 | 
			
		||||
@ -15,6 +15,7 @@ class Photo(fs.File):
 | 
			
		||||
    INITIAL_INFO = fs.File.INITIAL_INFO.copy()
 | 
			
		||||
    INITIAL_INFO.update({
 | 
			
		||||
        'dimensions': (0,0),
 | 
			
		||||
        'exif_timestamp': '',
 | 
			
		||||
    })
 | 
			
		||||
    __slots__ = fs.File.__slots__ + tuple(INITIAL_INFO.keys())
 | 
			
		||||
    
 | 
			
		||||
@ -30,7 +31,7 @@ class Photo(fs.File):
 | 
			
		||||
    def _get_orientation(self):
 | 
			
		||||
        if not hasattr(self, '_cached_orientation'):
 | 
			
		||||
            try:
 | 
			
		||||
                with io.open(self.path, 'rb') as fp:
 | 
			
		||||
                with self.path.open('rb') as fp:
 | 
			
		||||
                    exifdata = exif.get_fields(fp)
 | 
			
		||||
                    # the value is a list (probably one-sized) of ints
 | 
			
		||||
                    orientations = exifdata['Orientation']
 | 
			
		||||
@ -49,6 +50,13 @@ class Photo(fs.File):
 | 
			
		||||
            self.dimensions = self._plat_get_dimensions()
 | 
			
		||||
            if self._get_orientation() in {5, 6, 7, 8}:
 | 
			
		||||
                self.dimensions = (self.dimensions[1], self.dimensions[0])
 | 
			
		||||
        elif field == 'exif_timestamp':
 | 
			
		||||
            try:
 | 
			
		||||
                with self.path.open('rb') as fp:
 | 
			
		||||
                    exifdata = exif.get_fields(fp)
 | 
			
		||||
                    self.exif_timestamp = exifdata['DateTimeOriginal']
 | 
			
		||||
            except Exception:
 | 
			
		||||
                logging.info("Couldn't read EXIF of picture: %s", self.path)
 | 
			
		||||
    
 | 
			
		||||
    def get_blocks(self, block_count_per_side):
 | 
			
		||||
        return self._plat_get_blocks(block_count_per_side, self._get_orientation())
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@ class ResultTable(ResultTableBase):
 | 
			
		||||
        Column('size', coltr("Size (KB)"), optional=True),
 | 
			
		||||
        Column('extension', coltr("Kind"), visible=False, optional=True),
 | 
			
		||||
        Column('dimensions', coltr("Dimensions"), optional=True),
 | 
			
		||||
        Column('exif_timestamp', coltr("EXIF Timestamp"), visible=False, optional=True),
 | 
			
		||||
        Column('mtime', coltr("Modification"), visible=False, optional=True),
 | 
			
		||||
        Column('percentage', coltr("Match %"), optional=True),
 | 
			
		||||
        Column('dupe_count', coltr("Dupe Count"), visible=False, optional=True),
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ class ResultsModel(ResultsModelBase):
 | 
			
		||||
        Column('size', defaultWidth=60),
 | 
			
		||||
        Column('extension', defaultWidth=40),
 | 
			
		||||
        Column('dimensions', defaultWidth=100),
 | 
			
		||||
        Column('exif_timestamp', defaultWidth=120),
 | 
			
		||||
        Column('mtime', defaultWidth=120),
 | 
			
		||||
        Column('percentage', defaultWidth=60),
 | 
			
		||||
        Column('dupe_count', defaultWidth=80),
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user