* 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'> <[email protected]> Return-Path: <[email protected]> [...] ``` 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 -- [email protected] To unsubscribe send an email to [email protected] https://lists.mailman3.org/mailman3/lists/mailman-users.mailman3.org/ Archived at: https://lists.mailman3.org/archives/list/[email protected]/message/SKJKPAUH377NYHTSA3345ZGE5AQDRL3T/ This message sent to [email protected]
