#
# 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
syntax highlighted by Code2HTML, v. 0.9.1