diff danboorufs.py @ 1:63ccd8b0d615 draft

Add tag exclusion support.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Thu, 02 Aug 2012 12:19:31 +0200
parents 215d51f2a82f
children 85cbd44f98b1
line wrap: on
line diff
--- a/danboorufs.py
+++ b/danboorufs.py
@@ -4,7 +4,6 @@
 from __future__ import with_statement
 
 from errno import ENOENT, ENOTDIR
-from os.path import realpath
 from sys import argv, exit
 from threading import Lock
 from time import time
@@ -41,8 +40,7 @@ class Danbooru(LoggingMixIn, Operations)
                 for line in file:
                     for tag in line.split():
                         tag = tag.decode('UTF-8')
-                        if '/' in tag:
-                            tag = tag.replace('/', u'�') #XXX
+                        tag = tag.replace('/', u'�') #XXX
                         tags.append(tag)
                         self.tags.setdefault(tag, []).append(basename)
 
@@ -55,17 +53,21 @@ class Danbooru(LoggingMixIn, Operations)
         if path == '/':
             return (None, None)
 
-        path = path[1:].split('/')
+        real_path = path[1:].split('/')
+
+        # Remove the leading - of tag exclusion.
+        path = [tag[1:] if tag[0] == '-' else tag for tag in real_path]
+
         if filter(lambda tag: tag not in self.tags, path[:-1]):
             raise FuseOSError(ENOENT)
 
         if path[-1] in self.tags:
-            return (path, None)
+            return (real_path, None)
 
         if path[-1] not in self.paths:
             raise FuseOSError(ENOENT)
 
-        return (path[:-1], self.paths[path[-1]])
+        return (real_path[:-1], self.paths[real_path[-1]])
 
     def access(self, path, mode):
         self._split_path(path)
@@ -102,8 +104,14 @@ class Danbooru(LoggingMixIn, Operations)
         if l in self.cache:
             return ['.', '..'] + self.cache[l]
 
+        inclusion_tags = set(tag for tag in tags if tag[0] != '-')
+        exclusion_tags = set(tag[1:] for tag in tags if tag[0] == '-')
+
         # Get the list of the files corresponding to those tags.
-        files = reduce((lambda s, t: s.intersection(self.tags[t])), tags, set(self.files))
+        files = reduce((lambda s, t: s.intersection(self.tags[t])), inclusion_tags, set(self.files))
+        files -= set([f for f in files if exclusion_tags.intersection(self.files[f])])
+
+        # Those next two steps are for useless tags removal.
 
         # Get the tags of those files.
         taglist = reduce((lambda s, f: s.union(self.files[f])), files, set())