comparison taginthemiddle/model.py @ 17:c85d42296c06

make the model almost be real
author Jeff Hammel <jhammel@mozilla.com>
date Mon, 24 May 2010 07:44:39 -0700
parents 12344c001831
children 57ca873ed9bf
comparison
equal deleted inserted replaced
16:5f492a6fbdd1 17:c85d42296c06
1 """ 1 """
2 tags have: 2 Tags models. Tags have:
3 - a list of resources they're applied to 3 - a list of resources they're applied to
4 - a time they're applied 4 - a time they're applied
5 - for multi-user tags, the author should be passed (fudge for now) 5 - someone that tagged the resource
6 for now just assume auth is on and that anyone authenticated may tag
7 e.g. a tags file
8
9 foo = /bar:1273023556 /fleem/baz:1273023556 etc
10 cats = /cats:1273023556 /blog/mycat:1273023556
11
12 Ideally, the form of tags would be something like a table
13
14 Tag | URL | Author | Date [seconds since epoch]
15 """ 6 """
16 7
17 import os 8 import os
18 import time 9 import time
19 10
20 class Tags(object): 11 class Tags(object):
21 """file (e.g. .ini) based tagging scheme""" 12 """
13 abstract base class for tagging
14 """
22 15
23 def __init__(self, path): 16 def add(self, tag, url, author):
17 """add a tag to a URL"""
18 raise NotImplementedError
19
20 def remove(self, tag, url):
21 """remove a tag from a URL"""
22 raise NotImplementedError
23
24 def tags(self, url):
25 """
26 get the tags for a URL
27 """
28
29 def urls(self, *tags):
30 """
31 get the URLs for a set of tags
32 """
33
34 class FileTags(Tags):
35 """
36 file (e.g. .ini) based tagging scheme
37
38 File format:
39 foo = /bar:1273023556 /fleem/baz:1273023556 etc
40 cats = /cats:1273023556 /blog/mycat:1273023556
41 """
42 # XXX TODO: store user; currently this is not stored
43
44 def __init__(self, path, author):
24 """ 45 """
25 - path: path to file 46 - path: path to file
47 - author: who tagged the resource (fudge for now)
26 """ 48 """
27 self.path = path 49 self.path = path
28 if not os.path.exists(path): 50 if not os.path.exists(path):
29 f = file(path, 'w') 51 f = file(path, 'w')
30 f.close() 52 f.close()
31 self.tags = {} 53 self._tags = {}
32 self.urls = {} 54 self._urls = {}
33 self.times = {} 55 self.times = {}
34 self.read() 56 self.read()
35 57
36 def read(self): 58 def read(self):
37 for line in file(self.path).readlines(): 59 for line in file(self.path).readlines():
39 if not line: 61 if not line:
40 continue 62 continue
41 tag, urls = line.split('=', 1) # asserts '=' in line 63 tag, urls = line.split('=', 1) # asserts '=' in line
42 tag = tag.strip() 64 tag = tag.strip()
43 urls = urls.strip() 65 urls = urls.strip()
44 self.tags[tag] = set([urls]) 66 self._tags[tag] = set([urls])
45 for url in urls: 67 for url in urls:
46 url, time = url.rsplit(':', 1) 68 url, time = url.rsplit(':', 1)
47 self.urls.setdefault(url, set()).add(tag) 69 self._urls.setdefault(url, set()).add(tag)
48 self.times[(tag, url)] = int(time) 70 self.times[(tag, url)] = int(time)
49 71
50 def write(self): 72 def write(self):
51 f = file(self.path, 'w') 73 f = file(self.path, 'w')
52 for tag in sorted(self.tags.keys()): 74 for tag in sorted(self.tags.keys()):
53 print >> f, '%s = %s' % (tag, ' '.join(['%s:%s' % (url, self.times(tag, url)) 75 print >> f, '%s = %s' % (tag, ' '.join(['%s:%s' % (url, self.times(tag, url))
54 for url in self.tags[tag]])) 76 for url in self.tags[tag]]))
55 f.close() 77 f.close()
56 78
57 def add(self, tag, url): 79 ### implementation of Tags interface
58 if url in self.tags[tag]: 80
81 def add(self, tag, url, author):
82 if url in self._tags[tag]:
59 return 83 return
60 self.tags[tag].add(url) 84 self._tags[tag].add(url)
61 self.urls[url].add(tag) 85 self._urls[url].add(tag)
62 self.times[(tag, url)] = int(time.time()) 86 self.times[(tag, url)] = int(time.time())
63 self.write() 87 self.write()
64 88
65 def remove(self, tag, url): 89 def remove(self, tag, url):
66 if url not in self.tags[tag]: 90 if url not in self._tags[tag]:
67 return 91 return
68 self.tags[tag].remove(url) 92 self._tags[tag].remove(url)
69 self.urls[url].remove(tag) 93 self._urls[url].remove(tag)
70 del self.times[(tag, url)] 94 del self.times[(tag, url)]
71 self.write() 95 self.write()
96
97 def tags(self, url):
98 raise NotImplementedError
99
100 def urls(self, *tags):
101 raise NotImplementedError
102
103 class SQLiteTags(Tags):
104 """
105 Tags model using SQLite
106
107 Tags are relational data stored in a table
108 Tag | URL | Author | Date [seconds since epoch]
109 """
110
111 def __init__(self, path):
112 """
113 - path: path to SQLite file
114 """
115
116 def add(self, tag, url, author):
117 raise NotImplementedError
118
119 def remove(self, tag, url):
120 raise NotImplementedError
121
122 def tags(self, url):
123 """
124 select * from tags where url='url'
125 """
126
127 def urls(self, *tags):
128 """
129 select * from tags where tag=''
130 """