comparison 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
comparison
equal deleted inserted replaced
0:215d51f2a82f 1:63ccd8b0d615
2 # -*- encoding: utf-8 -*- 2 # -*- encoding: utf-8 -*-
3 3
4 from __future__ import with_statement 4 from __future__ import with_statement
5 5
6 from errno import ENOENT, ENOTDIR 6 from errno import ENOENT, ENOTDIR
7 from os.path import realpath
8 from sys import argv, exit 7 from sys import argv, exit
9 from threading import Lock 8 from threading import Lock
10 from time import time 9 from time import time
11 10
12 import os 11 import os
39 self.files[basename] = tags 38 self.files[basename] = tags
40 with open(name, 'r') as file: 39 with open(name, 'r') as file:
41 for line in file: 40 for line in file:
42 for tag in line.split(): 41 for tag in line.split():
43 tag = tag.decode('UTF-8') 42 tag = tag.decode('UTF-8')
44 if '/' in tag: 43 tag = tag.replace('/', u'�') #XXX
45 tag = tag.replace('/', u'�') #XXX
46 tags.append(tag) 44 tags.append(tag)
47 self.tags.setdefault(tag, []).append(basename) 45 self.tags.setdefault(tag, []).append(basename)
48 46
49 print('[%d] Index done.' % (time() - start)) 47 print('[%d] Index done.' % (time() - start))
50 48
53 51
54 def _split_path(self, path): 52 def _split_path(self, path):
55 if path == '/': 53 if path == '/':
56 return (None, None) 54 return (None, None)
57 55
58 path = path[1:].split('/') 56 real_path = path[1:].split('/')
57
58 # Remove the leading - of tag exclusion.
59 path = [tag[1:] if tag[0] == '-' else tag for tag in real_path]
60
59 if filter(lambda tag: tag not in self.tags, path[:-1]): 61 if filter(lambda tag: tag not in self.tags, path[:-1]):
60 raise FuseOSError(ENOENT) 62 raise FuseOSError(ENOENT)
61 63
62 if path[-1] in self.tags: 64 if path[-1] in self.tags:
63 return (path, None) 65 return (real_path, None)
64 66
65 if path[-1] not in self.paths: 67 if path[-1] not in self.paths:
66 raise FuseOSError(ENOENT) 68 raise FuseOSError(ENOENT)
67 69
68 return (path[:-1], self.paths[path[-1]]) 70 return (real_path[:-1], self.paths[real_path[-1]])
69 71
70 def access(self, path, mode): 72 def access(self, path, mode):
71 self._split_path(path) 73 self._split_path(path)
72 74
73 def getattr(self, path, fh=None): 75 def getattr(self, path, fh=None):
100 102
101 l = ' '.join(tags) 103 l = ' '.join(tags)
102 if l in self.cache: 104 if l in self.cache:
103 return ['.', '..'] + self.cache[l] 105 return ['.', '..'] + self.cache[l]
104 106
107 inclusion_tags = set(tag for tag in tags if tag[0] != '-')
108 exclusion_tags = set(tag[1:] for tag in tags if tag[0] == '-')
109
105 # Get the list of the files corresponding to those tags. 110 # Get the list of the files corresponding to those tags.
106 files = reduce((lambda s, t: s.intersection(self.tags[t])), tags, set(self.files)) 111 files = reduce((lambda s, t: s.intersection(self.tags[t])), inclusion_tags, set(self.files))
112 files -= set([f for f in files if exclusion_tags.intersection(self.files[f])])
113
114 # Those next two steps are for useless tags removal.
107 115
108 # Get the tags of those files. 116 # Get the tags of those files.
109 taglist = reduce((lambda s, f: s.union(self.files[f])), files, set()) 117 taglist = reduce((lambda s, f: s.union(self.files[f])), files, set())
110 taglist -= tags 118 taglist -= tags
111 119