#pylint: disable-msg=C0111 import os import stat import time import traceback from fms import MSG_TEMPLATE from fcpconnection import make_id def read_msg(full_path, default_sender, default_subject, default_group): article_num = os.stat(full_path)[stat.ST_MTIME] msg_id = "<fake_%s>" % str(article_num) reading_header = True blank_count = 0 headers = {} lines = [] for line in open(full_path, 'rb').readlines(): line = line.strip() #print "LINE:", line if reading_header: if line.strip() == '': blank_count += 1 if blank_count > 0: #DCI: get rid of useless code reading_header = False #print "SAW END OF HEADERS" continue else: blank_count = 0 fields = line.split(':') if len(fields) < 2: continue headers[fields[0].lower().strip()] = ':'.join(fields[1:]).strip() continue # on purpose. lines.append(line) # fake xover article tuple + group #(article number, subject, poster, date, id, references, size, lines) return (article_num, headers.get('subject', default_subject), headers.get('from', default_sender), None, # unused msg_id, (), None, # unused lines, # fms doesn't return these headers.get('newsgroups', default_group),) FAKE_TRUST = 65 # Trust value returned for all queries. class NNTPStub: def quit(self): print "NNTPStub.quit -- called." traceback.print_stack() #raise Exception("DCI: forcing stack trace") def shortcmd(self, cmd): assert cmd.startswith("XGETTRUST") return "200 %i" % FAKE_TRUST class FMSStub: def __init__(self, base_dir, group, sender_lut=None): self.base_dir = os.path.join(base_dir, '__msg_spool__') self.group = group if sender_lut is None: sender_lut = {} self.sender_lut = sender_lut if not os.path.exists(self.base_dir): os.makedirs(self.base_dir) def get_connection(self, fms_host, fms_port, user_name): """ Create a fake fms NNTP connection. """ return NNTPStub() def send_msgs(self, dummy_server, msg_tuples, send_quit=False): for msg_tuple in msg_tuples: # HACK: use lut to map partial -> full fms ids. #print "msg_tuple[0]: ", msg_tuple[0] #print "sender_lut: ", self.sender_lut sender = self.sender_lut.get(msg_tuple[0].split('@')[0], msg_tuple[0]) print "sender: ", sender if sender != msg_tuple[0]: print "fmsstub: FIXED UP %s->%s" % (msg_tuple[0], sender) assert sender.find('@') != -1 full_path = os.path.join(self.base_dir, 'out_going_%s.txt' % make_id()) out_file = open(full_path, 'wb') try: out_file.write(MSG_TEMPLATE % (sender, msg_tuple[1], msg_tuple[2], msg_tuple[3])) time.sleep(0.25) # Hack to make sure that modtimes are unique. finally: out_file.close() # OK to bend the rules a little for testing stubs. def recv_msgs(self, dummy_server, msg_sink, groups, max_articles=None, dummy_send_quit=False): #print "FMSStub.recv_msgs -- called" assert not max_articles is None assert tuple(groups) == (self.group, ) if not self.group in max_articles: max_articles[self.group] = 0 by_mtime = {} for name in os.listdir(self.base_dir): #print name mod_time = os.stat(os.path.join(self.base_dir, name))[stat.ST_MTIME] assert not mod_time in by_mtime by_mtime[mod_time] = name if len(by_mtime) < 1: #print "BAILING OUT, no files." return times = by_mtime.keys() times.sort() if times[-1] <= max_articles[self.group]: #print "BAILING OUT, no new files." return for mod_time in times: if mod_time <= max_articles[self.group]: #print "Skipping, ", mod_time continue max_articles[self.group] = max(max_articles[self.group], mod_time) items = read_msg(os.path.join(self.base_dir, by_mtime[mod_time]), 'djk@isFiaD04zgAgnrEC5XJt1i4IE7AkNPqhBG5bONi6Yks', 'unknown_subject', self.group) if items[-1] != self.group: continue if not msg_sink.wants_msg(self.group, items): print "fmsstub: Rejected by sink: %s" % by_mtime[mod_time] continue msg_sink.recv_fms_msg(self.group, items, items[-2])