Mercurial > danboorufs
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 |