# # Flat file pyne box. base64 filename of message id. # Headers marshalled first, then message body. # import marshal import os import os.path import time import binascii from base64 import encodestring from base64 import decodestring from string import find, replace from glob import glob from pyneheaders import * from superbox import superbox def id_2_hash(id): id = id[:160] x = encodestring(id) # some things are nasty in filenames.. yeah this is retarded x = replace(x, "\012", "") x = replace(x, "/", "|") # remove this junk some time return x[:255] def hash_2_id(hash): try: return decodestring(replace(hash, "|", "/")) except binascii.Error: print "Eek. Couldn't decode base64 msgid: ", hash return None class flatfilebox(superbox): # uid_prefix should be the uid normally, or if it is a # newsgroup we pass 'parent nntpbox uid/ newsgroup name' so # the newsgroup is inside the parent nntpbox. cute. def __init__(self, user, box, prefix=None): if prefix == None: prefix = box.uid self.prefix = prefix self.user = user # make sure our folder exists path = "" for i in os.path.split(self.prefix): path = os.path.join(path, i) if path == "": continue if not os.path.isdir(path): os.mkdir(path) def get_contents(self): files = glob(self.prefix+"/*") ids = [] for i in files: #ids.append(hash_2_id(os.path.basename(i))) j = hash_2_id(os.path.basename(i)) if not j: print "Erm. ",os.path.basename(i) ids.append (j) return ids def nuke(self): """ Delete database entirely. """ for i in glob(self.prefix+"/*"): os.remove(i) os.removedirs(self.prefix) def __del__(self): pass def load_header(self, msg_id): """ Return message header or None if not found. in form: (date, date_received, message-id, references, subject, from, opts (flags), senduid) """ try: f = open(self.prefix+"/"+id_2_hash(msg_id)) return marshal.load(f) except (ValueError, TypeError, IOError, EOFError): return None def _load_article(self, msg_id): """ Returm body for message 'msg_id'. """ try: f = open(self.prefix+"/"+id_2_hash(msg_id)) head = marshal.load(f) body = f.read() f.close() return (head, body) except IOError: return (None, None) def _save_article(self, headers, body_text, msg_id): """ Do not use directly. use save_article. """ s = marshal.dumps(headers) f = open(self.prefix+"/"+id_2_hash(msg_id), "w") f.write(s) f.write(body_text) def delete_article(self, msg_id): try: os.remove(self.prefix+"/"+id_2_hash(msg_id)) except OSError: pass def has_article(self, msg_id): """ Is the article cached? """ # NOTE: we check for presence of headers not bodies if os.path.isfile(self.prefix+"/"+id_2_hash(msg_id)): return 1 else: return 0