* On 4/18/25 04:23, Mark Sapiro wrote:
On 4/17/25 11:35 AM, Mihai Moldovan wrote:New incoming messages will have the correct data, of course, but imported ones wouldn't, so I'll have to use a more sophisticated approach to handle them, probably by going through mailman's email wrapper, figuring out how to generate a msgdata object for a message, using RFC2369.process and maybe more.Here's an example script. You need to run this with /opt/mailman/mm/venv/bin/python to get access to the mailman imports. ``` from mailbox import Maildir, mbox from mailman.email.message import Message from mailman.handlers.rfc2369 import process from mailman.interfaces.listmanager import IListManager from mailman.utilities.email import add_message_hash from zope.component import getUtility mb = mbox('path/to/mbox', factory=Message, create=False) md = Maildir('path/to/maildir', create=False) mlist = getUtility(IListManager).get_by_list_id('your.list.id') for msg in mb: add_message_hash(msg) process(mlist, msg, {}) md.add(msg) mb.close() md.close() ```
Thank you.Unfortunately, I'm having a hard time getting this to work correctly. My current approach is (which is modified from yours, for instance to use Prototype.archive_message() instead of writing directly to a Maildir):
```py import copy import sys from mailbox import mbox from mailman.archiving.prototype import Prototype from mailman.core import initialize from mailman.email.message import Message from mailman.handlers.rfc_2369 import process from mailman.interfaces.listmanager import IListManager from mailman.interfaces.mailinglist import IMailingList from mailman.utilities.email import add_message_hash from zope.component import getUtility initialize.initialize() if (len(sys.argv) < 3): print('Usage: {0} <list-id> <mbox-file>'.format(sys.argv[0]), file=sys.stderr) exit(1) mb = mbox(sys.argv[2], factory=Message, create=False) mlist = getUtility(IListManager).get_by_list_id(sys.argv[1]) for msg in mb: try: add_message_hash(msg) process(mlist, msg {}) Prototype.archive_message(mlist, msg) except Exception as e:print("Error when adding {0}: {1}".format(msg['message-id'], str(e)), file=sys.stderr)
mb.close() ```This returns "Error when adding None: '_PartialFile' object has no attribute 'header_max_count'" for each message.
This, including getting None for the Message-ID, stumped me and I got on to debugging this.
Indeed, even something as simple as ```py for msg in mb: print(type(msg)) print(msg['message-id']) print(msg) exit(0) ``` results in getting a None for the Message-ID and a stack trace: <class 'mailman.email.message.Message'> None Traceback (most recent call last): File "/root/mailman3/prototype-import.py", line 29, in <module> print(msg) File "/usr/lib/python3.12/email/message.py", line 165, in __str__ return self.as_string() ^^^^^^^^^^^^^^^^File "/usr/lib/python3/dist-packages/mailman/email/message.py", line 55, in as_string
value = email.message.Message.as_string(self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/email/message.py", line 188, in as_string g.flatten(self, unixfrom=unixfrom) File "/usr/lib/python3.12/email/generator.py", line 98, in flatten policy = policy.clone(max_line_length=self.maxheaderlen) ^^^^^^^^^^^^AttributeError: '_PartialFile' object has no attribute 'clone'. Did you mean: 'close'?
This eventually led me to realize that passing mailman.email.message.Message as the factory to mbox() internally calls factory(msg), and the base class of Message (email.message.Message) has an __init__ function that takes the policy parameter, so it looks as if it's registering the mailbox message incorrectly as the policy handler, which is totally wrong of course.
If I change the call to mb = mbox(sys.argv[2], factory=None, create=False), the output looks more promising, so converting the data to mailman.email.message.Message first seems to have been the wrong idea on my part:
``` <class 'mailbox.mboxMessage'> <mailman.1.1399151409.10314.x2go-i...@lists.x2go.org> Return-Path: <mailman-boun...@lists.x2go.org> [...] ``` and indeed, if I let the import actually happen, it works.The imported messages, do have a Message-ID-Hash, but the Archived-At and List-Archive headers are empty (literally <>).
Do you have an example message that was archived through Prototype? What are the proper header values for this module? I believe that Archived-At should be the Message-ID-Hash and the List-Archive header contain... well, given that the Prototype archiver is not meant to be publicly available, probably a file:// URL?
Mihai
OpenPGP_signature.asc
Description: OpenPGP digital signature
_______________________________________________ Mailman-users mailing list -- mailman-users@mailman3.org To unsubscribe send an email to mailman-users-le...@mailman3.org https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/ Archived at: https://lists.mailman3.org/archives/list/mailman-users@mailman3.org/message/SKJKPAUH377NYHTSA3345ZGE5AQDRL3T/ This message sent to arch...@mail-archive.com