Submit
Path:
~
/
/
opt
/
psa
/
admin
/
plib
/
modules
/
site-import
/
backend
/
lib
/
python
/
parallels
/
plesk
/
source
/
confixx
/
content
/
File Content:
mail.py
import os import re import posixpath from parallels.core.content.mail.rsync import CopyMailRsync from parallels.core.content.mail.rsync import SourceMailDirectory from parallels.core.runners.base import BaseRunner from parallels.core.utils.paths.mail_paths import MailboxDirectory class ConfixxCopyMailContentSourceDirectory(SourceMailDirectory): def __init__(self, subscription, domain, confixx_configuration, agent_dir, mailmapping_tool): super(ConfixxCopyMailContentSourceDirectory, self).__init__(subscription, domain) self.confixx_configuration = confixx_configuration self.agent_dir = agent_dir self.mailmapping_tool = mailmapping_tool self.temporary_directory = None def prepare(self): source_server = self.subscription.mail_source_server self.temporary_directory = None if self.confixx_configuration.is_maildir_used(): # copy maildir content as-is maildir_pair = self._get_maildir_mapping( self.domain, self.subscription ) else: # Run 'mailbox -> maildir' conversion on source server self.temporary_directory = source_server.get_session_file_path( posixpath.join('mail', self.domain.name) ) with source_server.runner() as runner_source: runner_source.mkdir(self.temporary_directory) maildir_pair = self._get_mailbox_maildir_mapping( self.subscription, self.domain, self.temporary_directory ) return list(maildir_pair) def cleanup(self): source_server = self.subscription.mail_source_server if self.temporary_directory is not None: with source_server.runner() as runner: assert isinstance(runner, BaseRunner) runner.execute_command( u'rm -rf {directory}', dict(directory=self.temporary_directory) ) def _get_maildir_mapping(self, domain, subscription): """For each maildir, return a pair of source, destination paths.""" confixx_mailhome = self.confixx_configuration.get_config_var('pop_homeDir') for mailbox, user_maildir in self._get_domain_mailboxes(subscription, domain): source_maildir = posixpath.join(confixx_mailhome, user_maildir) yield (source_maildir, MailboxDirectory(mailbox.name)) def _get_mailbox_maildir_mapping(self, subscription, domain, maildir_home): """Convert mailboxes to maildir; put them in a temporary directory. Return a pair of source, destination paths. """ domain_mailboxes = self._get_domain_mailboxes(subscription, domain) for mailbox, mailbox_filename in domain_mailboxes: source_maildir = self._mailbox_to_maildir( subscription.mail_source_server, mailbox, mailbox_filename, maildir_home ) yield (source_maildir, MailboxDirectory(mailbox.name)) def _mailbox_to_maildir( self, source_server, mailbox, mailbox_filename, maildir_home ): """Convert mailbox to maildir; return path to the generated Maildir.""" mailbox_path = self.confixx_configuration.get_mailbox_path( mailbox_filename ) maildir = posixpath.join(maildir_home, mailbox.name) with source_server.runner() as runner_source: assert isinstance(runner_source, BaseRunner) runner_source.mkdir(maildir) runner_source.execute_command( u'cd {mbox2maildir_path}; ' u'perl mb2md.pl -s {mailbox} -d {maildir}', dict( mbox2maildir_path=os.path.join( self.agent_dir, 'shared_legacy' ), mailbox=mailbox_path, maildir=posixpath.join(maildir, 'Maildir') ) ) return maildir def _get_domain_mailboxes(self, subscription, domain): """Iterate over domain mail users; return Mailbox objects. Skip mail users that have no mailboxes associated. Note: 'Mailbox' object also represents Maildir. """ mailmap = self._get_subscription_mailmapping(subscription) for mailbox in domain.iter_mailboxes(): if mailbox.full_name in mailmap: filename = mailmap[mailbox.full_name] yield (mailbox, filename) def _get_subscription_mailmapping(self, subscription): """Convert Confixx mail model to a [simpler] Plesk one. In Confixx, email and mailbox are two separate entities. In particular, there can be mailboxes without email and mailboxes with more than one email address associated with them. To be able to transfer that structure to Plesk, mail box should be associated with one email. This mapping is done by the migration agent on source panel side. Return a dict with '{<email>: <mailbox filename>, ...}' mapping. Emails without mailboxes (forwarding), are not included in the list. """ source_server = subscription.mail_source_server with source_server.runner() as runner_source: assert isinstance(runner_source, BaseRunner) mailmap_str = runner_source.execute_command( u'cd {agent_dir}; echo {client_name} | perl {mailmapping_tool}', dict( agent_dir=self.agent_dir, mailmapping_tool=self.mailmapping_tool, client_name=subscription.raw_dump.owner_login ) ).stdout mailmap = {} for line in mailmap_str.split('\n'): rx = re.match('^(\S+@\S+)\s+(\S+)$', line) if rx: (email, mailbox) = rx.groups() mailmap[email] = mailbox return mailmap class ConfixxCopyMailContent(CopyMailRsync): """Transfer mail content from Confixx to Plesk server Confixx mail content format can be Maildir or mailbox. In case of Maildir, the content is transferred as-is. Mailboxes are converted to Maildirs on Confixx side before transfer is started. """ def __init__(self, confixx_configuration, agent_dir, mailmapping_tool): class SourceDirectory(ConfixxCopyMailContentSourceDirectory): def __init__(self, subscription, domain): super(SourceDirectory, self).__init__( subscription, domain, confixx_configuration, agent_dir, mailmapping_tool ) super(ConfixxCopyMailContent, self).__init__(SourceDirectory)
Edit
Rename
Chmod
Delete
FILE
FOLDER
INFO
Name
Size
Permission
Action
__init__.py
0 bytes
0644
mail.py
6782 bytes
0644
N4ST4R_ID | Naxtarrr