1
2
3
4
5
6
7
8
9
10
11 """
12 This module contains the base class for all the Entry classes. The
13 EntryBase class is essentially the API for entries in PyBlosxom. Reading
14 through the comments for this class will walk you through building your
15 own EntryBase derivatives.
16
17 This module also holds a generic generate_entry function which will generate
18 a BaseEntry with data that you provide for it.
19 """
20
21 __revision__ = "$Revision: 935 $"
22
23 import time, locale
24 from Pyblosxom import tools
25
26 BIGNUM = 2000000000
27 CONTENT_KEY = "body"
28 DOESNOTEXIST = "THISKEYDOESNOTEXIST"
29 DOESNOTEXIST2 = "THISKEYDOESNOTEXIST2"
30
32 """
33 EntryBase is the base class for all the Entry classes. Each
34 instance of an Entry class represents a single entry in the weblog,
35 whether it came from a file, or a database, or even somewhere off
36 the InterWeeb.
37 """
38 - def __init__(self, request):
39 self._data = None
40 self._metadata = tools.VariableDict()
41 self._id = ""
42 self._mtime = BIGNUM
43 self._request = request
44
46 """
47 Returns a friendly debuggable representation of self. Useful to know on
48 what entry pyblosxom fails on you (though unlikely)
49
50 returns: Identifiable representation of object
51 rtype: string
52 """
53 return "<Entry instance: %s>\n" % self.getId()
54
56 """
57 This should return an id that's unique enough for caching
58 purposes.
59
60 Override this.
61
62 @returns: string id
63 @rtype: string
64 """
65 return self._id
66
68 """
69 Returns the data string. This method should be overridden to
70 provide from pulling the data from other places.
71
72 Override this.
73
74 @returns: the data as a string
75 @rtype: string
76 """
77 return str(self._data)
78
79 - def setData(self, data):
80 """
81 Sets the data content for this entry. If you are not
82 creating the entry, then you have no right to set the data
83 of the entry. Doing so could be hazardous depending on what
84 EntryBase subclass you're dealing with.
85
86 Override this.
87
88 @param data: the data
89 @type data: string
90 """
91 self._data = data
92
94 """
95 Returns a given piece of metadata.
96
97 Override this.
98
99 @param key: the key being sought
100 @type key: varies
101
102 @param default: the default to return if the key does not
103 exist
104 @type default: varies
105
106 @return: either the default (if the key did not exist) or the
107 value of the key in the metadata dict
108 @rtype: varies
109 """
110 return self._metadata.get(key, default)
111
113 """
114 Sets a key/value pair in the metadata dict.
115
116 Override this.
117
118 @param key: the key string
119 @type key: string
120
121 @param value: the value string
122 @type value: string (or an object with a __str__ method)
123 """
124 self._metadata[key] = value
125
127 """
128 Returns the list of keys for which we have values in our
129 stored metadata.
130
131 Note: This list gets modified later downstream. If you
132 cache your list of metadata keys, then this method should
133 return a copy of that list and not the list itself
134 lest it get adjusted.
135
136 Override this.
137
138 @returns: list of metadata keys
139 @rtype: list of strings
140 """
141 return self._metadata.keys()
142
143 - def getFromCache(self, entryid):
144 """
145 Retrieves information from the cache that pertains to this
146 specific entryid.
147
148 This is a helper method--call this to get data from the cache.
149 Do not override it.
150
151 @param entryid: a unique key for the information you're retrieving
152 @type entryid: string
153
154 @returns: dict with the values or None if there's nothing for that
155 entryid
156 @rtype: dict or None
157 """
158 cache = tools.get_cache(self._request)
159
160
161 if cache.has_key(entryid):
162 return cache[entryid]
163
164 return None
165
166 - def addToCache(self, entryid, data):
167 """
168 Over-writes the cached dict for key entryid with the data dict.
169
170 This is a helper method--call this to add data to the cache.
171 Do not override it.
172
173 @param entryid: a unique key for the information you're storing
174 @type entryid: string
175
176 @param data: the data to store--this should probably be a dict
177 @type data: dict
178 """
179 mycache = tools.get_cache(self._request)
180 if mycache:
181 mycache[entryid] = data
182
183
184
185
186 - def setTime(self, timetuple):
187 """
188 This takes in a given time tuple and sets all the magic metadata
189 variables we have according to the items in the time tuple.
190
191 @param timetuple: the timetuple to use to set the data with--this
192 is the same thing as the mtime/atime portions of an os.stat.
193 @type timetuple: tuple of ints
194 """
195 self['timetuple'] = timetuple
196 self._mtime = time.mktime(timetuple)
197 gmtimetuple = time.gmtime(self._mtime)
198 self['mtime'] = self._mtime
199 self['ti'] = time.strftime('%H:%M', timetuple)
200 self['mo'] = time.strftime('%b', timetuple)
201 self['mo_num'] = time.strftime('%m', timetuple)
202 self['da'] = time.strftime('%d', timetuple)
203 self['dw'] = time.strftime('%A', timetuple)
204 self['yr'] = time.strftime('%Y', timetuple)
205 self['fulltime'] = time.strftime('%Y%m%d%H%M%S', timetuple)
206 self['date'] = time.strftime('%a, %d %b %Y', timetuple)
207
208
209
210 loc = locale.getlocale(locale.LC_ALL)
211 locale.setlocale(locale.LC_ALL, 'C')
212
213
214 self['w3cdate'] = time.strftime('%Y-%m-%dT%H:%M:%SZ', gmtimetuple)
215 self['rfc822date'] = time.strftime('%a, %d %b %Y %H:%M GMT', \
216 gmtimetuple)
217
218
219 locale.setlocale(locale.LC_ALL, loc)
220
221 - def __getitem__(self, key, default=None):
222 """
223 Retrieves an item from this dict based on the key given. If
224 the item does not exist, then we return the default.
225
226 If the item is CONTENT_KEY then we return the result from
227 self.getData().
228
229 This is just a convenience method for getData(...) and
230 getMetadata(...).
231
232 There's no reason to override this--override getData and
233 getMetadata instead.
234
235 @param key: the key being sought
236 @type key: varies
237
238 @param default: the default to return if the key does not
239 exist
240 @type default: varies
241
242 @returns: the value of self._metadata.get(key, default) or
243 self.getData()
244 @rtype: varies
245 """
246 if key == CONTENT_KEY:
247 return self.getData()
248
249 if key == CONTENT_KEY + "_escaped":
250 return tools.escape_text(self.getData())
251
252 return self.getMetadata(key, default)
253
254 - def get(self, key, default=None):
255 """
256 Retrieves an item from the internal dict based on the key
257 given.
258
259 All this does is turn aroun and call __getitem__.
260
261 There's no reason to override this--override getData and
262 getMetadata instead.
263
264 @param key: the key being sought
265 @type key: varies
266
267 @param default: the default to return if the key does not
268 exist
269 @type default: varies
270
271 @returns: the value of self._metadata.get(key, default) or
272 self.getData() (through __getitem__)
273 @rtype: varies
274 """
275 return self.__getitem__(key, default)
276
277 - def __setitem__(self, key, value):
278 """
279 Sets the metadata[key] to the given value.
280
281 This is a convenience method for setData(...) and setMetadata(...).
282
283 There's no reason to override this. Override setData and
284 setMetadata.
285
286 @param key: the given key name
287 @type key: varies
288
289 @param value: the given value
290 @type value: varies
291 """
292 if key == CONTENT_KEY:
293 self.setData(value)
294 else:
295 self.setMetadata(key, value)
296
297 - def update(self, newdict):
298 """
299 Updates the contents in this entry with the contents in the
300 dict. It does so by calling setData and setMetadata.
301
302 @param newdict: the dict we're updating this one with
303 @type newdict: dict
304 """
305 for mem in newdict.keys():
306 if mem == CONTENT_KEY:
307 self.setData(newdict[mem])
308 else:
309 self.setMetadata(mem, newdict[mem])
310
311 - def has_key(self, key):
312 """
313 Returns whether a given key is in the metadata dict. If the key
314 is the CONTENT_KEY, then we automatically return true.
315
316 @param key: the key to check in the metadata dict for
317 @type key: varies
318
319 @returns: whether (1) or not (0) the key exists
320 @rtype: boolean
321 """
322 if key == CONTENT_KEY or key == CONTENT_KEY + "_escaped":
323 return 1
324
325 value = self.getMetadata(key, DOESNOTEXIST)
326 if value == DOESNOTEXIST:
327 value = self.getMetadata(key, DOESNOTEXIST2)
328 if value == DOESNOTEXIST2:
329 return 0
330
331 return 1
332
334 """
335 Returns a list of the keys that can be accessed through
336 __getitem__.
337
338 @returns: list of key names
339 @rtype: list of varies
340 """
341 keys = self.getMetadataKeys()
342 if CONTENT_KEY not in keys:
343 keys.append(CONTENT_KEY)
344 keys.append(CONTENT_KEY + "_escaped")
345 return keys
346
347
348 -def generate_entry(request, properties, data, mtime):
349 """
350 Takes a properties dict and a data string and generates a generic
351 entry using the data you provided.
352
353 @param request: the Request object
354 @type request: Request
355
356 @param properties: the dict of properties for the entry
357 @type properties: dict
358
359 @param data: the data content for the entry
360 @type data: string
361
362 @param mtime: the mtime tuple (as given by time.localtime()).
363 if you pass in None, then we'll use localtime.
364 @type mtime: tuple of ints
365 """
366 entry = EntryBase(request)
367
368 entry.update(properties)
369 entry.setData(data)
370 if mtime:
371 entry.setTime(mtime)
372 else:
373 entry.setTime(time.localtime())
374 return entry
375
376
377