# File: superbox.py
# Purpose: Message box superclass.
OPT_THREAD = 1 # sort messages into threads
OPT_HEADERS_ONLY = 2 # only collect headers (without body text)
# Flags the various box types have
BOX_ISDELETEABLE = 0x01 # Can delete box
BOX_MAKE_NEW_MSG = 0x02 # Can compose new messages from it
BOX_REPLY_SINGLE = 0x04
BOX_REPLY_GROUP = 0x08
BOX_REPLY_FORWARD= 0x10
BOX_DEL_MESSAGE = 0x20 # allow deletion of messages
BOX_UPDATE_METHOD= 0x40 # there is an update method
BOX_IMPORT_TO = 0x80 # may import ascii or unix messages to box
import os
import time
import threading
import cPickle
from boxtypes.net_exceptions import *
from pyneheaders import *
class superbox:
"""
Message box superclass.
"""
def load_box (self, user, uid):
self.__dict__ = {}
version = ver_stamp
try:
f = open(uid+".fol", "r")
except IOError:
# Creating new folder
pass
else:
try:
version = cPickle.load(f)
type = cPickle.load(f)
self.__dict__ = cPickle.load(f)
except Exception,e:
print "Error loading box '"+uid+"': "+str(e)
print "Restoring defaults..."
f.close()
def delete_article(self, msg_id):
self._io.delete_article(msg_id)
self.messages.remove(msg_id)
def save_article(self, msg):
self._io.save_article(msg)
def save_new_article(self, msg):
self._io.save_article(msg)
msg_id = msg.headers["message-id"]
if not (msg_id in self.messages):
self.messages.append(msg_id)
def move_article(self, user, msg_id, folder_uid):
to_folder = user.get_folder_by_uid (folder_uid)
msg = self.load_article (msg_id)
to_folder.save_new_article (msg)
to_folder.changed = 1
self.delete_article (msg_id)
self.changed = 1
def load_article(self, msg_id):
return self._io.load_article(msg_id)
def load_header(self, msg_id):
return self._io.load_header(msg_id)
def get_default_personality(self, user):
return user.get_personality( self.default_personality )
def nuke_storage(self):
"""
Delete all messages in folder and lose io reference.
Also delete folder .fol settings file.
Do this before deleting a folder.
"""
if self.__dict__.has_key("_io"):
self._io.nuke()
try:
os.remove(self.uid+".fol")
except OSError:
pass
# If you want to do remote send/recv implement these in
# derived class (or override):
# (Pass verbose=1 to logfunc when giving verbose info)
#
# Return list of messages available for collection
# def recv_get_pending(self, servers, logfunc)
#
def recv_collect_threaded(self, user, servers, recvfunc, logfunc, incfunc, articles):
"""
Collect articles in this list using all servers, threaded.
Calling incfunc each time a message has been collected.
Pass just one server in servers if multi-threaded collection
not desired.
"""
def _collect_thread(self, user, servers, server_num, recvfunc, logfunc, incfunc, articles):
import msgfilter
# make sure the connection has not died
if len(articles) != 0:
try:
servers[server_num].check_renew_connection()
except (connect_exception, auth_exception):
return
server = servers[server_num]
# download the articles
while 1:
try:
x = articles.pop()
except IndexError:
return
# if the article isn't already cached get it
if not x in self.messages:
try:
# Let recvfunc do what it wants with message id 'x'
status_msg = recvfunc(user, self, server, x)
if status_msg != "":
logfunc(status_msg)
except timeout_exception:
# Failed to collect message. shove back on pending
articles.append(x)
# update progress bar
num_left = len(articles)
incfunc()
# start collection threads
threads = []
for i in range(1, len(servers)):
t = threading.Thread(target=_collect_thread, args=(self, user, servers, i, recvfunc, logfunc, incfunc, articles))
t.start()
threads.append(t)
_collect_thread(self, user, servers, 0, recvfunc, logfunc, incfunc, articles)
# wait till threads are finished executing
while 1:
finished = 1
for i in threads:
if i.isAlive():
finished = 0
if finished:
break
time.sleep(1)
def shutdown(self, user):
if self.__dict__.has_key("_io"):
del self._io
syntax highlighted by Code2HTML, v. 0.9.1