1
2 """
3
4 @author: Fabio Erculiani <lxnay@sabayonlinux.org>
5 @contact: lxnay@sabayonlinux.org
6 @copyright: Fabio Erculiani
7 @license: GPL-2
8
9 B{Entropy Package Manager Client Notice Board functions Interface}.
10
11 """
12 from __future__ import with_statement
13 import os
14 from entropy.misc import RSS
15 from entropy.dump import loadobj as dump_loadobj, dumpobj as dump_dumpobj
16 from entropy.exceptions import RepositoryError
17
19
20 """
21 Main interface for handling Repository Notice Board user data,
22 such as notice board items status, metadata retrieval, etc.
23 """
24
26 """
27 Return noticeboard RSS metadata (dict form) for given repository
28 identifier.
29 This method is fault tolerant, except for invalid repoid given,
30 if repository notice board file is broken or not found an empty dict
31 is returned.
32
33 @param repoid: repository identifier
34 @type repoid: string
35 @return: repository metadata
36 @rtype: dict
37 @raise KeyError: if given repository identifier is not available
38 """
39 repo_data = self.SystemSettings['repositories']['available'][repoid]
40 nb_path = repo_data['local_notice_board']
41
42 if not os.access(nb_path, os.F_OK | os.R_OK):
43 return {}
44
45
46 myrss = RSS(nb_path, '', '')
47 data, data_len = myrss.get_entries()
48
49 if data is None:
50 return {}
51 return data
52
54 """
55 Return noticeboard user metadata dict for given repository identifier.
56 This dictionary contains misc noticeboard information for given
57 repository, like (at the moment) items read status.
58
59 @param repoid: repository identifier
60 @type repoid: string
61 @return: repository user metadata
62 @rtype: dict
63 @raise KeyError: if given repository identifier is not available
64 """
65 repo_data = self.SystemSettings['repositories']['available'][repoid]
66 nb_path = repo_data['local_notice_board_userdata']
67
68 if not os.access(nb_path, os.F_OK | os.R_OK):
69 return {}
70
71
72 data = dump_loadobj(nb_path, complete_path = True) or {}
73 return data
74
76 """
77 Store given noticeboard metadata for given repository to disk.
78
79 @param repoid: repository identifier
80 @type repoid: string
81 @param metadata: repository user metadata to store
82 @type metadata: dict
83 @raise KeyError: if given repository identifier is not available
84 @raise RepositoryError: if given repository directory is not available
85 """
86 repo_data = self.SystemSettings['repositories']['available'][repoid]
87 nb_path = repo_data['local_notice_board_userdata']
88
89
90 nb_dir = os.path.dirname(nb_path)
91 if not (os.path.isdir(nb_dir) and os.access(nb_dir, os.W_OK)):
92 raise RepositoryError(
93 "repository directory not available for %s" % (repoid,))
94
95 return dump_dumpobj(nb_path, metadata, complete_path = True)
96
98 """
99 Set given noticeboard item read status.
100 This method also handles repository user metadata on-disk storage,
101 this is a "one-shot" function, no need to call anything else.
102
103 @param repoid: repository identifier
104 @type repoid: string
105 @param item_id: repository noticeboard item identifier
106 @type item_id: int
107 @param read_status: read status (True if read, False if not)
108 @type read_status: bool
109 @raise KeyError: if given repository identifier is not valid
110 """
111 data = self.get_noticeboard_userdata(repoid)
112 obj = data.setdefault('read_items', set())
113 if read_status:
114 obj.add(item_id)
115 else:
116 obj.discard(item_id)
117
118 return self.store_noticeboard_userdata(repoid, data)
119
121 """
122 Return noticeboard items read status for given repository identifier.
123
124 @param repoid: repository identifier
125 @type repoid: string
126 @return: item identifiers marked as "read"
127 @rtype: set
128 """
129 data = self.get_noticeboard_userdata(repoid)
130 return data.get('read_items', set())
131
133 """
134 Return noticeboard hash data.
135
136 @param repoid: repository identifier
137 @type repoid: string
138 """
139 nb_data = self.get_noticeboard(repoid)
140
141 mystr = ''
142 for key in ("description", "pubDate", "title", "link", "id",):
143 if key not in nb_data:
144 continue
145 elem = nb_data[key]
146 if not isinstance(elem, basestring):
147 continue
148 mystr += elem
149
150 return self.entropyTools.md5string(mystr)
151
153 """
154 Mark noticeboard items for given repository as "read". "read" status
155 will be automatically tainted when noticeboard changes.
156
157 @param repoid: repository identifier
158 @type repoid: string
159 """
160 data = self.get_noticeboard_userdata(repoid)
161 data['as_read'] = self._get_noticeboard_hash(repoid)
162
163 return self.store_noticeboard_userdata(repoid, data)
164
166 """
167 Unmark noticeboard items for given repository as "read". "read" status
168 will be automatically tainted when noticeboard changes.
169
170 @param repoid: repository identifier
171 @type repoid: string
172 """
173 data = self.get_noticeboard_userdata(repoid)
174 data['as_read'] = "0000"
175
176 return self.store_noticeboard_userdata(repoid, data)
177
179 """
180 Return whether noticeboard for given repository has been marked as
181 "read" by user.
182
183 @param repoid: repository identifier
184 @type repoid: string
185 """
186 data = self.get_noticeboard_userdata(repoid)
187 if not data.has_key('as_read'):
188 return False
189 nb_hash = self._get_noticeboard_hash(repoid)
190 return nb_hash == data['as_read']
191
193 """
194 Return whether all available repository noticeboards are marked as
195 read.
196
197 @return: read status
198 @rtype: bool
199 """
200 for repoid in self.validRepositories:
201 if not self.is_noticeboard_marked_as_read(repoid):
202 return False
203 return True
204