summary refs log tree commit diff stats
path: root/ranger
diff options
context:
space:
mode:
authortoonn <toonn@toonn.io>2019-12-23 23:23:38 +0100
committertoonn <toonn@toonn.io>2019-12-24 00:26:31 +0100
commitce3de17e70f9e6c0e5dc30c9879a5e8d43b19b9c (patch)
tree7dee210515214d81288a9ea7f4fd8b2ccc810c22 /ranger
parente3fd4eeefd8e1c1bf559361b111bec2cc1c70d74 (diff)
downloadranger-ce3de17e70f9e6c0e5dc30c9879a5e8d43b19b9c.tar.gz
Add duplicate filter to filter_stack
Diffstat (limited to 'ranger')
-rw-r--r--ranger/core/filter_stack.py41
1 files changed, 41 insertions, 0 deletions
diff --git a/ranger/core/filter_stack.py b/ranger/core/filter_stack.py
index 9b4d2779..a479b6ed 100644
--- a/ranger/core/filter_stack.py
+++ b/ranger/core/filter_stack.py
@@ -98,6 +98,47 @@ class HashFilter(BaseFilter, FileManagerAware):
         return "<Filter: hash {}>".format(self.filepath)
 
 
+@stack_filter("duplicate")
+class DuplicateFilter(BaseFilter, FileManagerAware):
+    def __init__(self, _):
+        self.duplicates = self.get_duplicates(self.fm.thisdir.files_all)
+
+    def __call__(self, fobj):
+        return fobj in self.duplicates
+
+    def __str__(self):
+        return "<Filter: duplicate>"
+
+    def get_duplicates(self, fsobjects):
+        hashes = {}
+        for fobj in fsobjects:
+            chunks = hash_chunks(fobj.path)
+            chunk = next(chunks)
+            while chunk in hashes:
+                for dup in hashes[chunk]:
+                    _, dup_chunks = dup
+                    try:
+                        hashes[next(dup_chunks)] = [dup]
+                        hashes[chunk].remove(dup)
+                    except StopIteration:
+                        pass
+                try:
+                    chunk = next(chunks)
+                except StopIteration:
+                    hashes[chunk].append((fobj, chunks))
+                    break
+            else:
+                hashes[chunk] = [(fobj, chunks)]
+
+        duplicates = set()
+        for dups in hashes.values():
+            if len(dups) >= 2:
+                for (dup, _) in dups:
+                    duplicates.add(dup)
+
+        return duplicates
+
+
 @stack_filter("type")
 class TypeFilter(BaseFilter):
     type_to_function = {