|
37 | 37 | from . import pipermail |
38 | 38 | import weakref |
39 | 39 | import binascii |
| 40 | +from io import StringIO, BytesIO |
| 41 | +import pickle |
40 | 42 |
|
41 | 43 | from email.header import decode_header, make_header |
42 | 44 | from email.errors import HeaderParseError |
43 | 45 | from email.charset import Charset |
| 46 | +from email import message_from_file |
| 47 | +from email.generator import Generator |
44 | 48 |
|
45 | 49 | from Mailman import mm_cfg |
46 | 50 | from Mailman import Utils |
@@ -449,7 +453,7 @@ def decode_charset(self, field): |
449 | 453 | if cset == 'us-ascii': |
450 | 454 | cset = 'iso-8859-1' # assume this for English list |
451 | 455 | ustr = str(field, cset, 'replace') |
452 | | - return u''.join(ustr.splitlines()) |
| 456 | + return ''.join(ustr.splitlines()) |
453 | 457 |
|
454 | 458 | def as_html(self): |
455 | 459 | d = self.__dict__.copy() |
@@ -899,7 +903,9 @@ def processUnixMailbox(self, archfile): |
899 | 903 | content = archfile.read() |
900 | 904 | # Create a temporary file to store the content |
901 | 905 | import tempfile |
902 | | - with tempfile.NamedTemporaryFile(mode='w+', delete=False) as tmp: |
| 906 | + with tempfile.NamedTemporaryFile(mode='w+', encoding='utf-8', delete=False) as tmp: |
| 907 | + if isinstance(content, bytes): |
| 908 | + content = content.decode('utf-8', errors='replace') |
903 | 909 | tmp.write(content) |
904 | 910 | tmp_path = tmp.name |
905 | 911 |
|
@@ -955,3 +961,44 @@ def format_article(self, article): |
955 | 961 | article.html_body = processed_lines |
956 | 962 |
|
957 | 963 | return article |
| 964 | + |
| 965 | + def close(self): |
| 966 | + "Close an archive, save its state, and update any changed archives." |
| 967 | + self.update_dirty_archives() |
| 968 | + self.update_TOC = 0 |
| 969 | + self.write_TOC() |
| 970 | + # Save the collective state |
| 971 | + self.message(C_('Pickling archive state into ') |
| 972 | + + os.path.join(self.basedir, 'pipermail.pck')) |
| 973 | + self.database.close() |
| 974 | + del self.database |
| 975 | + |
| 976 | + omask = os.umask(0o007) |
| 977 | + try: |
| 978 | + f = open(os.path.join(self.basedir, 'pipermail.pck'), 'wb') |
| 979 | + finally: |
| 980 | + os.umask(omask) |
| 981 | + # Use protocol 4 for Python 2/3 compatibility |
| 982 | + pickle.dump(self.getstate(), f, protocol=4, fix_imports=True) |
| 983 | + f.close() |
| 984 | + |
| 985 | + def getstate(self): |
| 986 | + """Get the current state of the archive.""" |
| 987 | + try: |
| 988 | + # Use protocol 4 for Python 2/3 compatibility |
| 989 | + protocol = 4 |
| 990 | + return pickle.dumps(self.__dict__, protocol, fix_imports=True) |
| 991 | + except Exception as e: |
| 992 | + syslog('error', 'Error getting archive state: %s', e) |
| 993 | + return None |
| 994 | + |
| 995 | + def setstate(self, state): |
| 996 | + """Set the state of the archive.""" |
| 997 | + try: |
| 998 | + # Use protocol 4 for Python 2/3 compatibility |
| 999 | + protocol = 4 |
| 1000 | + self.__dict__ = pickle.loads(state, fix_imports=True, encoding='latin1') |
| 1001 | + except Exception as e: |
| 1002 | + syslog('error', 'Error setting archive state: %s', e) |
| 1003 | + return False |
| 1004 | + return True |
0 commit comments