2023-05-30T16:46:11,555 Created temporary directory: /tmp/pip-build-tracker-fvnytcuv 2023-05-30T16:46:11,558 Initialized build tracking at /tmp/pip-build-tracker-fvnytcuv 2023-05-30T16:46:11,559 Created build tracker: /tmp/pip-build-tracker-fvnytcuv 2023-05-30T16:46:11,559 Entered build tracker: /tmp/pip-build-tracker-fvnytcuv 2023-05-30T16:46:11,560 Created temporary directory: /tmp/pip-wheel-thfxmtv1 2023-05-30T16:46:11,569 Created temporary directory: /tmp/pip-ephem-wheel-cache-mrkerkll 2023-05-30T16:46:11,621 Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple 2023-05-30T16:46:11,629 2 location(s) to search for versions of mbox2m365: 2023-05-30T16:46:11,629 * https://pypi.org/simple/mbox2m365/ 2023-05-30T16:46:11,629 * https://www.piwheels.org/simple/mbox2m365/ 2023-05-30T16:46:11,630 Fetching project page and analyzing links: https://pypi.org/simple/mbox2m365/ 2023-05-30T16:46:11,631 Getting page https://pypi.org/simple/mbox2m365/ 2023-05-30T16:46:11,635 Found index url https://pypi.org/simple/ 2023-05-30T16:46:11,834 Fetched page https://pypi.org/simple/mbox2m365/ as application/vnd.pypi.simple.v1+json 2023-05-30T16:46:11,838 Found link https://files.pythonhosted.org/packages/6c/31/171401930c8923f943a1ea671a726209113bdb0759b36af9716eb61eaa12/mbox2m365-3.0.6.tar.gz (from https://pypi.org/simple/mbox2m365/), version: 3.0.6 2023-05-30T16:46:11,839 Found link https://files.pythonhosted.org/packages/93/dd/07f5465ee90fb81b7f6df237ecb0abefefecf0c984adef70730493503804/mbox2m365-3.0.8.tar.gz (from https://pypi.org/simple/mbox2m365/), version: 3.0.8 2023-05-30T16:46:11,840 Found link https://files.pythonhosted.org/packages/7f/96/ebd03ef2d3be45b7fcdcbf603cfe23fcbd4db15135dd4d9a1dd7b389281e/mbox2m365-3.0.10.tar.gz (from https://pypi.org/simple/mbox2m365/), version: 3.0.10 2023-05-30T16:46:11,840 Found link https://files.pythonhosted.org/packages/4d/6a/5547755d2f0ffd2898dfea194692fa316f3ae928e023c53e68180ba014d0/mbox2m365-3.0.12.tar.gz (from https://pypi.org/simple/mbox2m365/), version: 3.0.12 2023-05-30T16:46:11,841 Found link https://files.pythonhosted.org/packages/24/48/5765400ed318e16ce6a1f901a7e1e39efe14da6f6e16baba3bc7970f5be4/mbox2m365-3.0.14.tar.gz (from https://pypi.org/simple/mbox2m365/), version: 3.0.14 2023-05-30T16:46:11,842 Fetching project page and analyzing links: https://www.piwheels.org/simple/mbox2m365/ 2023-05-30T16:46:11,843 Getting page https://www.piwheels.org/simple/mbox2m365/ 2023-05-30T16:46:11,845 Found index url https://www.piwheels.org/simple/ 2023-05-30T16:46:12,073 Fetched page https://www.piwheels.org/simple/mbox2m365/ as text/html 2023-05-30T16:46:12,076 Skipping link: No binaries permitted for mbox2m365: https://www.piwheels.org/simple/mbox2m365/mbox2m365-3.0.12-py3-none-any.whl#sha256=11f16b89a6d1dd91415a578920301907c064002e897d0bf22ded4af66a001441 (from https://www.piwheels.org/simple/mbox2m365/) 2023-05-30T16:46:12,077 Skipping link: not a file: https://www.piwheels.org/simple/mbox2m365/ 2023-05-30T16:46:12,077 Skipping link: not a file: https://pypi.org/simple/mbox2m365/ 2023-05-30T16:46:12,112 Given no hashes to check 1 links for project 'mbox2m365': discarding no candidates 2023-05-30T16:46:12,142 Collecting mbox2m365==3.0.14 2023-05-30T16:46:12,147 Created temporary directory: /tmp/pip-unpack-x5w_sipw 2023-05-30T16:46:12,318 Downloading mbox2m365-3.0.14.tar.gz (22 kB) 2023-05-30T16:46:12,426 Added mbox2m365==3.0.14 from https://files.pythonhosted.org/packages/24/48/5765400ed318e16ce6a1f901a7e1e39efe14da6f6e16baba3bc7970f5be4/mbox2m365-3.0.14.tar.gz to build tracker '/tmp/pip-build-tracker-fvnytcuv' 2023-05-30T16:46:12,439 Created temporary directory: /tmp/pip-build-env-9on6lzu3 2023-05-30T16:46:12,459 Installing build dependencies: started 2023-05-30T16:46:12,462 Running command pip subprocess to install build dependencies 2023-05-30T16:46:15,172 Using pip 23.1.2 from /home/piwheels/.local/lib/python3.7/site-packages/pip (python 3.7) 2023-05-30T16:46:15,946 Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple 2023-05-30T16:46:19,872 Collecting setuptools>=42 2023-05-30T16:46:20,129 Using cached https://www.piwheels.org/simple/setuptools/setuptools-67.8.0-py3-none-any.whl (1.1 MB) 2023-05-30T16:46:20,771 Collecting wheel 2023-05-30T16:46:20,808 Using cached https://www.piwheels.org/simple/wheel/wheel-0.40.0-py3-none-any.whl (64 kB) 2023-05-30T16:46:25,734 Installing collected packages: wheel, setuptools 2023-05-30T16:46:26,186 Creating /tmp/pip-build-env-9on6lzu3/overlay/bin 2023-05-30T16:46:26,191 changing mode of /tmp/pip-build-env-9on6lzu3/overlay/bin/wheel to 755 2023-05-30T16:46:30,500 Successfully installed setuptools-67.8.0 wheel-0.40.0 2023-05-30T16:46:30,951 Installing build dependencies: finished with status 'done' 2023-05-30T16:46:30,963 Getting requirements to build wheel: started 2023-05-30T16:46:30,965 Running command Getting requirements to build wheel 2023-05-30T16:46:32,372 /tmp/pip-build-env-9on6lzu3/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `description` defined outside of `pyproject.toml` would be ignored. 2023-05-30T16:46:32,374 !! 2023-05-30T16:46:32,374 ******************************************************************************** 2023-05-30T16:46:32,375 ########################################################################## 2023-05-30T16:46:32,375 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-05-30T16:46:32,375 ########################################################################## 2023-05-30T16:46:32,376 The following seems to be defined outside of `pyproject.toml`: 2023-05-30T16:46:32,377 `description = "'Send a message stored within an mbox using m365 (Office365)'"` 2023-05-30T16:46:32,378 According to the spec (see the link below), however, setuptools CANNOT 2023-05-30T16:46:32,378 consider this value unless `description` is listed as `dynamic`. 2023-05-30T16:46:32,379 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-05-30T16:46:32,379 For the time being, `setuptools` will still consider the given value (as a 2023-05-30T16:46:32,379 **transitional** measure), but please note that future releases of setuptools will 2023-05-30T16:46:32,380 follow strictly the standard. 2023-05-30T16:46:32,380 To prevent this warning, you can list `description` under `dynamic` or alternatively 2023-05-30T16:46:32,381 remove the `[project]` table from your file and rely entirely on other means of 2023-05-30T16:46:32,381 configuration. 2023-05-30T16:46:32,382 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-05-30T16:46:32,382 or your builds will no longer be supported. 2023-05-30T16:46:32,382 ******************************************************************************** 2023-05-30T16:46:32,383 !! 2023-05-30T16:46:32,383 _handle_missing_dynamic(dist, project_table) 2023-05-30T16:46:32,384 /tmp/pip-build-env-9on6lzu3/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `readme` defined outside of `pyproject.toml` would be ignored. 2023-05-30T16:46:32,384 !! 2023-05-30T16:46:32,385 ******************************************************************************** 2023-05-30T16:46:32,385 ########################################################################## 2023-05-30T16:46:32,385 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-05-30T16:46:32,386 ########################################################################## 2023-05-30T16:46:32,386 The following seems to be defined outside of `pyproject.toml`: 2023-05-30T16:46:32,387 `readme = '# Abstract\n\nThis repository contains a simple python script that (1) processes an\n`mbox` style mailbox file, (2) parses out (typically) the last message\nand then (3) re-transmits this using the CLI `m365` toolset. While this\nscript can be used in a completely stand-alone manner to extract a\nmessage from an `mbox` and then *send* using `m365`, it’s main utility\nis when used in a full ecosystem including an email client and `postfix`\nserver.\n\nThe CLI `m365` offers the ability to use Outlook/Office365 to send\nemails. However, this tool is not suited to use as a mail client\u2009—\u2009it\nmerely offers a means to transmit a message from the command line. More\nuseful would be if existing mail clients could leverage `m365` natively.\nCurrently, however, this is not available. Therefore, `mbox2m365` was\ncreated to complete a "missing link" in a full email experience. Using\nthis tool in a configured environment, it is now possible to use *any*\nemail client to transmit messages using Outlook/Office365.\n\n# TL;DR\n\nEven if you’re impatient, it’s a good idea to read this document.\nHowever, assuming you’ve already built the infrastructure, assuming you\nhave installed `m365` (and logged into your Institution from `m365`),\nhave assuming you have setup your email client to email to a dummy local\npostfix account, then you can install `mbox2m365` with a simple\n\n``` bash\npip install mbox2m365\n```\n\nnote at time of writing the PyPI install might not be available. In that\ncase, simply clone this repo and do a\n\n``` bash\n# From the repo root dir\npip install -U .\n```\n\nand fire it off by setting up the monitor on the `mbox` file (here we\nassume the mbox belongs to `rudolph`)\n\n``` bash\ncd /var/mail\nfind . | entr mbox2m365 --mbox rudolph --b64_encode \\\n --sendFromFile --cleanUp \\\n --waitForStragglers 5\n```\n\n(Clearly the above relies on [`entr`](https://github.com/eradman/entr).\nConsult your distro’s repos for the appropriate install. In arch, this\nis `yay -S entr`, in Ubuntu, this is `sudo apt install entr`)\n\n# Security alert!\n\nWait! **Danger, Will Robinson**! Doesn’t this violate security policies?\nI was told my Institution does *not* allow clients like thunderbird to\nconnect to the Outlook server to send emails!\n\nWell, the devil is in the details as the saying goes. This solution does\n*not* violate policy since the "unauthenticated" email client is *not*\never connecting/authenticating to the Outlook server. Rather, the\n"unauthenticated" email client sends messages to a specially configured\nserver that "saves" the emails to a file. Then, a separate program\nteases out the new arrivals and uses the **authenticated** `m365`\nprogram to actually talk to and leverage Outlook to send the email. This\n*separate program* that bridges the mail file to `m365` is none other\nthan this python module.\n\nSo to be pendantic: all credentialing and authentication is handled by\n`m365` and *not* this tool. The end user is still required to\nlogin/authenticate using `m365`. If this has not happened, then\n`mbox2m365` will not work.\n\nAgain, this repo contains **no** authentication tokens/passwords/etc.\n\n# Limitations\n\nLet’s get these out of the way first. This is *not* a full solution for\nlinking a third party email client to Outlook. It gets *close*, IMHO.\nThe limitations are:\n\n- This is not a multi-user solution. All email transmitted to the\n intermediate helper server is added to a single user `mbox` which when\n processed by this script means **all** email in that `mbox` will\n appear to have been transmitted by that user. While in theory it\n should be possible to support multiple users, either by having a\n separate helper server per user or by having multiple local users on\n the mail server and separate `mbox` files, the current solution is\n clearly not scalable. It is decent though for the single user case.\n\n- Fundmanentally, this solution is limited first and foremost by the\n capabilities of the CLI `m365 outlook mail send` functionality. Recent\n updates to `m365` have expanded functionality of this bridge\u2009—\u2009most\n notably attachments are now supported. Still pending is full `bcc`\n support\u2009—\u2009currently all `bcc` recipients are switched to `cc`.\n\nOther limitations stem from the fact the bridge needs to process the\n`mbox` file *de novo* each time mail is received by the helper server.\nThis means that time to process will increase linearly with `mbox` size.\nThe real world implications of this are still being explored.\n\nFinally, the bridge does make a best effort attempt to *wait* until the\n`mbox` has stabilized before analyzing it. When sending emails to\nmultiple recipients, *each* recipient gets a single complete copy in the\n`mbox` with a single address (the multiple recipient addresses are not\nconserved in the `mbox` but *are* processed by this bridge). While\narguably wasteful, the implication is that while all these recipient\ncopies are appended to the `mbox`, the bridge should wait until all have\nbeen added before processing. Currently the bridge attempts this by\nexamining the `mbox` file size when called, and waiting a small delta\ntime interval and checking if the size has changed again. It will wait\nuntil the size is stable before continuing. The TL;DR is this could\nresult in a processing delay.\n\n# Introduction\n\nThe migration/adoption of Office365 by institutions often poses issues\nand problems for users wishing to use different tools for email\ntransmission, particularly on platforms such as Linux.\n\nWhile it is possible to access various Office365 applications,\nparticularly Outlook, via a web interface, this is often not sufficient\nfor several classes of users, particularly those who find the web\ninterface cumbersome (for instance, the web interface has no (or\nlimited) support for keyboard shortcuts, it is cumbersome if not\nimpossible to automate tasks involving event-driven email) and/or for\nusers who have an existing and efficient email workflow using clients\nsuch as `thunderbird` or `mutt`.\n\nThis small repo houses a small and simple python application with some\nsupporting documentation that provides a solution to the problem of\nsending email from an instituion’s managed domain by leveraging\n`postfix` and some `mbox` processing and then using the CLI tool `m365`.\n\n# Method Summary\n\nThe solution requires some seemingly contortuous steps, but in reality\nis rather simple and can be summarized as follows:\n\n## Reading email\n\nReading emails that are locked away in an Outlook server is best\neffected by simply adding a forward incoming email rule from your\nInstitution Outlook Server (IOS) to an externally accessible email\nprovider (such as `gmail`), allowing this email to be read easily by\ntools such as `thunderbird` or `mutt`.\n\n ┌─────────────────────────────────┐\n │IOS that receives incoming email │\n └┬────────────────────────────────┘\n │\n └─────┐\n │\n ┌O─────────────────────┐\n │forwardRule()│\n └┬─────────────────────┘\n ┌─────┘\n │\n ┌O────┐\n │gmail│\n └┬────┘\n └─────┐\n │\n ┌O──────────────────────┐\n │clientAccess()│\n └O──────────────────────┘\n ┌─────┘\n │\n ┌┴───────────────────────┐\n │thunderbird / mutt / etc│\n └────────────────────────┘\n\n## Sending email\n\nThe message is now outside of Outlook, and if the Institution does not\nallow non-authorized clients (often this means they only allow Microsoft\ntools) to connect to the Outlook server, the following work around will\nhelp. Essentially, the outside client should be configured to send email\nusing a properly setup `postfix` server that simply copies the target\nemail to an `mbox` file.\n\nThis `mbox` file is then monitored for any changes, and on a change\n(assumed to mean a new email message has been appended), a new process\nis fired off to parse off the latest message and then use the command\nline `m365` CLI tool to have the IOS send the email.\n\n ┌───────────────────────┐\n │thundebird / mutt /etc │\n └┬──────────────────────┘\n │\n └─────┐\n │\n ┌O────────────────────────────┐\n │sendmail() (postfix)│\n └┬────────────────────────────┘\n ┌─────┘\n │\n ┌O────┐\n │mbox │\n └┬────┘\n └─────┐\n │\n ┌O────────┐\n │mbox2m365│ <--- this repo!\n └┬────────┘\n ┌─────┘\n │\n ┌O─────────────┐\n │m365 │\n └┬─────────────┘\n │\n ┌O────────────────────────────────┐\n │IOS that transmits outgoing email│\n └─────────────────────────────────┘\n\n# `mbox2m365`\n\nWhile all the building blocks to effect the solution exist, the one\nmissing piece is the `mbox` to `m365` block, which is provided for by\nthis rather simple python script.\n\n# Setup your helper mail server, `postfix`\n\nFirst, install `postfix`\n\n## Arch\n\n``` bash\nyay -S postfix\n```\n\n## Ubuntu\n\n``` bash\nsudo apt install postfix\n```\n\n# `transport`\n\nNow, edit the `transport` file.\n\n``` bash\nsudo bash\ncd /etc/postfix\ncp transport transport.orig\necho "* local:rudolph" >> transport\n```\n\n# `main.cf`\n\nFor the `main.cf` file, do\n\n``` bash\n# Assuming you are still in the /etc/postfix dir in a sudo bash shell...\ncp main.cf main.cf.orig\necho "mydomain = pangea.net" >> main.cf\necho "luser_relay = rudolph@pangea.net"\necho "transport_maps = hash:/etc/postfix/transport" >> main.cf\n```\n\n# enable/restart the services\n\n``` bash\nsudo systemctl enable postfix.service\nsudo systemctl restart postfix.service\n```\n\n# Email client\n\nSimply configure your email client to use the machine running `postfix`\nas your email server. All emails will be appended to the `transport`\nuser’s `mbox` file.\n\n# Fire up `mbox2m365`\n\nThe final piece of the puzzle:\n\n``` bash\ncd /var/mail\nfind . | entr mbox2m365 --mbox rudolph --b64_encode \\\n --sendFromFile --cleanUp \\\n --waitForStragglers 5\n```\n\n*-30-*\n'` 2023-05-30T16:46:32,389 According to the spec (see the link below), however, setuptools CANNOT 2023-05-30T16:46:32,389 consider this value unless `readme` is listed as `dynamic`. 2023-05-30T16:46:32,390 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-05-30T16:46:32,390 For the time being, `setuptools` will still consider the given value (as a 2023-05-30T16:46:32,391 **transitional** measure), but please note that future releases of setuptools will 2023-05-30T16:46:32,391 follow strictly the standard. 2023-05-30T16:46:32,392 To prevent this warning, you can list `readme` under `dynamic` or alternatively 2023-05-30T16:46:32,392 remove the `[project]` table from your file and rely entirely on other means of 2023-05-30T16:46:32,392 configuration. 2023-05-30T16:46:32,393 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-05-30T16:46:32,393 or your builds will no longer be supported. 2023-05-30T16:46:32,394 ******************************************************************************** 2023-05-30T16:46:32,394 !! 2023-05-30T16:46:32,395 _handle_missing_dynamic(dist, project_table) 2023-05-30T16:46:33,046 running egg_info 2023-05-30T16:46:33,057 writing mbox2m365.egg-info/PKG-INFO 2023-05-30T16:46:33,062 writing dependency_links to mbox2m365.egg-info/dependency_links.txt 2023-05-30T16:46:33,067 writing entry points to mbox2m365.egg-info/entry_points.txt 2023-05-30T16:46:33,070 writing requirements to mbox2m365.egg-info/requires.txt 2023-05-30T16:46:33,072 writing top-level names to mbox2m365.egg-info/top_level.txt 2023-05-30T16:46:33,109 reading manifest file 'mbox2m365.egg-info/SOURCES.txt' 2023-05-30T16:46:33,113 reading manifest template 'MANIFEST.in' 2023-05-30T16:46:33,115 adding license file 'LICENSE' 2023-05-30T16:46:33,120 writing manifest file 'mbox2m365.egg-info/SOURCES.txt' 2023-05-30T16:46:33,124 /tmp/pip-build-env-9on6lzu3/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `license` defined outside of `pyproject.toml` would be ignored. 2023-05-30T16:46:33,125 !! 2023-05-30T16:46:33,125 ******************************************************************************** 2023-05-30T16:46:33,126 ########################################################################## 2023-05-30T16:46:33,126 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-05-30T16:46:33,127 ########################################################################## 2023-05-30T16:46:33,128 The following seems to be defined outside of `pyproject.toml`: 2023-05-30T16:46:33,129 `license = 'MIT'` 2023-05-30T16:46:33,130 According to the spec (see the link below), however, setuptools CANNOT 2023-05-30T16:46:33,130 consider this value unless `license` is listed as `dynamic`. 2023-05-30T16:46:33,131 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-05-30T16:46:33,132 For the time being, `setuptools` will still consider the given value (as a 2023-05-30T16:46:33,133 **transitional** measure), but please note that future releases of setuptools will 2023-05-30T16:46:33,133 follow strictly the standard. 2023-05-30T16:46:33,134 To prevent this warning, you can list `license` under `dynamic` or alternatively 2023-05-30T16:46:33,134 remove the `[project]` table from your file and rely entirely on other means of 2023-05-30T16:46:33,135 configuration. 2023-05-30T16:46:33,136 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-05-30T16:46:33,136 or your builds will no longer be supported. 2023-05-30T16:46:33,137 ******************************************************************************** 2023-05-30T16:46:33,138 !! 2023-05-30T16:46:33,138 _handle_missing_dynamic(dist, project_table) 2023-05-30T16:46:33,139 /tmp/pip-build-env-9on6lzu3/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `authors` defined outside of `pyproject.toml` would be ignored. 2023-05-30T16:46:33,139 !! 2023-05-30T16:46:33,140 ******************************************************************************** 2023-05-30T16:46:33,140 ########################################################################## 2023-05-30T16:46:33,141 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-05-30T16:46:33,141 ########################################################################## 2023-05-30T16:46:33,142 The following seems to be defined outside of `pyproject.toml`: 2023-05-30T16:46:33,143 `authors = 'Rudolph Pienaar'` 2023-05-30T16:46:33,144 According to the spec (see the link below), however, setuptools CANNOT 2023-05-30T16:46:33,144 consider this value unless `authors` is listed as `dynamic`. 2023-05-30T16:46:33,145 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-05-30T16:46:33,146 For the time being, `setuptools` will still consider the given value (as a 2023-05-30T16:46:33,146 **transitional** measure), but please note that future releases of setuptools will 2023-05-30T16:46:33,146 follow strictly the standard. 2023-05-30T16:46:33,147 To prevent this warning, you can list `authors` under `dynamic` or alternatively 2023-05-30T16:46:33,148 remove the `[project]` table from your file and rely entirely on other means of 2023-05-30T16:46:33,148 configuration. 2023-05-30T16:46:33,149 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-05-30T16:46:33,149 or your builds will no longer be supported. 2023-05-30T16:46:33,150 ******************************************************************************** 2023-05-30T16:46:33,150 !! 2023-05-30T16:46:33,151 _handle_missing_dynamic(dist, project_table) 2023-05-30T16:46:33,302 Getting requirements to build wheel: finished with status 'done' 2023-05-30T16:46:33,321 Created temporary directory: /tmp/pip-modern-metadata-q4hnsdph 2023-05-30T16:46:33,327 Preparing metadata (pyproject.toml): started 2023-05-30T16:46:33,330 Running command Preparing metadata (pyproject.toml) 2023-05-30T16:46:34,606 /tmp/pip-build-env-9on6lzu3/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `description` defined outside of `pyproject.toml` would be ignored. 2023-05-30T16:46:34,607 !! 2023-05-30T16:46:34,608 ******************************************************************************** 2023-05-30T16:46:34,608 ########################################################################## 2023-05-30T16:46:34,609 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-05-30T16:46:34,609 ########################################################################## 2023-05-30T16:46:34,610 The following seems to be defined outside of `pyproject.toml`: 2023-05-30T16:46:34,610 `description = "'Send a message stored within an mbox using m365 (Office365)'"` 2023-05-30T16:46:34,611 According to the spec (see the link below), however, setuptools CANNOT 2023-05-30T16:46:34,611 consider this value unless `description` is listed as `dynamic`. 2023-05-30T16:46:34,612 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-05-30T16:46:34,613 For the time being, `setuptools` will still consider the given value (as a 2023-05-30T16:46:34,613 **transitional** measure), but please note that future releases of setuptools will 2023-05-30T16:46:34,613 follow strictly the standard. 2023-05-30T16:46:34,614 To prevent this warning, you can list `description` under `dynamic` or alternatively 2023-05-30T16:46:34,614 remove the `[project]` table from your file and rely entirely on other means of 2023-05-30T16:46:34,614 configuration. 2023-05-30T16:46:34,615 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-05-30T16:46:34,615 or your builds will no longer be supported. 2023-05-30T16:46:34,616 ******************************************************************************** 2023-05-30T16:46:34,616 !! 2023-05-30T16:46:34,617 _handle_missing_dynamic(dist, project_table) 2023-05-30T16:46:34,617 /tmp/pip-build-env-9on6lzu3/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `readme` defined outside of `pyproject.toml` would be ignored. 2023-05-30T16:46:34,617 !! 2023-05-30T16:46:34,618 ******************************************************************************** 2023-05-30T16:46:34,618 ########################################################################## 2023-05-30T16:46:34,619 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-05-30T16:46:34,619 ########################################################################## 2023-05-30T16:46:34,620 The following seems to be defined outside of `pyproject.toml`: 2023-05-30T16:46:34,621 `readme = '# Abstract\n\nThis repository contains a simple python script that (1) processes an\n`mbox` style mailbox file, (2) parses out (typically) the last message\nand then (3) re-transmits this using the CLI `m365` toolset. While this\nscript can be used in a completely stand-alone manner to extract a\nmessage from an `mbox` and then *send* using `m365`, it’s main utility\nis when used in a full ecosystem including an email client and `postfix`\nserver.\n\nThe CLI `m365` offers the ability to use Outlook/Office365 to send\nemails. However, this tool is not suited to use as a mail client\u2009—\u2009it\nmerely offers a means to transmit a message from the command line. More\nuseful would be if existing mail clients could leverage `m365` natively.\nCurrently, however, this is not available. Therefore, `mbox2m365` was\ncreated to complete a "missing link" in a full email experience. Using\nthis tool in a configured environment, it is now possible to use *any*\nemail client to transmit messages using Outlook/Office365.\n\n# TL;DR\n\nEven if you’re impatient, it’s a good idea to read this document.\nHowever, assuming you’ve already built the infrastructure, assuming you\nhave installed `m365` (and logged into your Institution from `m365`),\nhave assuming you have setup your email client to email to a dummy local\npostfix account, then you can install `mbox2m365` with a simple\n\n``` bash\npip install mbox2m365\n```\n\nnote at time of writing the PyPI install might not be available. In that\ncase, simply clone this repo and do a\n\n``` bash\n# From the repo root dir\npip install -U .\n```\n\nand fire it off by setting up the monitor on the `mbox` file (here we\nassume the mbox belongs to `rudolph`)\n\n``` bash\ncd /var/mail\nfind . | entr mbox2m365 --mbox rudolph --b64_encode \\\n --sendFromFile --cleanUp \\\n --waitForStragglers 5\n```\n\n(Clearly the above relies on [`entr`](https://github.com/eradman/entr).\nConsult your distro’s repos for the appropriate install. In arch, this\nis `yay -S entr`, in Ubuntu, this is `sudo apt install entr`)\n\n# Security alert!\n\nWait! **Danger, Will Robinson**! Doesn’t this violate security policies?\nI was told my Institution does *not* allow clients like thunderbird to\nconnect to the Outlook server to send emails!\n\nWell, the devil is in the details as the saying goes. This solution does\n*not* violate policy since the "unauthenticated" email client is *not*\never connecting/authenticating to the Outlook server. Rather, the\n"unauthenticated" email client sends messages to a specially configured\nserver that "saves" the emails to a file. Then, a separate program\nteases out the new arrivals and uses the **authenticated** `m365`\nprogram to actually talk to and leverage Outlook to send the email. This\n*separate program* that bridges the mail file to `m365` is none other\nthan this python module.\n\nSo to be pendantic: all credentialing and authentication is handled by\n`m365` and *not* this tool. The end user is still required to\nlogin/authenticate using `m365`. If this has not happened, then\n`mbox2m365` will not work.\n\nAgain, this repo contains **no** authentication tokens/passwords/etc.\n\n# Limitations\n\nLet’s get these out of the way first. This is *not* a full solution for\nlinking a third party email client to Outlook. It gets *close*, IMHO.\nThe limitations are:\n\n- This is not a multi-user solution. All email transmitted to the\n intermediate helper server is added to a single user `mbox` which when\n processed by this script means **all** email in that `mbox` will\n appear to have been transmitted by that user. While in theory it\n should be possible to support multiple users, either by having a\n separate helper server per user or by having multiple local users on\n the mail server and separate `mbox` files, the current solution is\n clearly not scalable. It is decent though for the single user case.\n\n- Fundmanentally, this solution is limited first and foremost by the\n capabilities of the CLI `m365 outlook mail send` functionality. Recent\n updates to `m365` have expanded functionality of this bridge\u2009—\u2009most\n notably attachments are now supported. Still pending is full `bcc`\n support\u2009—\u2009currently all `bcc` recipients are switched to `cc`.\n\nOther limitations stem from the fact the bridge needs to process the\n`mbox` file *de novo* each time mail is received by the helper server.\nThis means that time to process will increase linearly with `mbox` size.\nThe real world implications of this are still being explored.\n\nFinally, the bridge does make a best effort attempt to *wait* until the\n`mbox` has stabilized before analyzing it. When sending emails to\nmultiple recipients, *each* recipient gets a single complete copy in the\n`mbox` with a single address (the multiple recipient addresses are not\nconserved in the `mbox` but *are* processed by this bridge). While\narguably wasteful, the implication is that while all these recipient\ncopies are appended to the `mbox`, the bridge should wait until all have\nbeen added before processing. Currently the bridge attempts this by\nexamining the `mbox` file size when called, and waiting a small delta\ntime interval and checking if the size has changed again. It will wait\nuntil the size is stable before continuing. The TL;DR is this could\nresult in a processing delay.\n\n# Introduction\n\nThe migration/adoption of Office365 by institutions often poses issues\nand problems for users wishing to use different tools for email\ntransmission, particularly on platforms such as Linux.\n\nWhile it is possible to access various Office365 applications,\nparticularly Outlook, via a web interface, this is often not sufficient\nfor several classes of users, particularly those who find the web\ninterface cumbersome (for instance, the web interface has no (or\nlimited) support for keyboard shortcuts, it is cumbersome if not\nimpossible to automate tasks involving event-driven email) and/or for\nusers who have an existing and efficient email workflow using clients\nsuch as `thunderbird` or `mutt`.\n\nThis small repo houses a small and simple python application with some\nsupporting documentation that provides a solution to the problem of\nsending email from an instituion’s managed domain by leveraging\n`postfix` and some `mbox` processing and then using the CLI tool `m365`.\n\n# Method Summary\n\nThe solution requires some seemingly contortuous steps, but in reality\nis rather simple and can be summarized as follows:\n\n## Reading email\n\nReading emails that are locked away in an Outlook server is best\neffected by simply adding a forward incoming email rule from your\nInstitution Outlook Server (IOS) to an externally accessible email\nprovider (such as `gmail`), allowing this email to be read easily by\ntools such as `thunderbird` or `mutt`.\n\n ┌─────────────────────────────────┐\n │IOS that receives incoming email │\n └┬────────────────────────────────┘\n │\n └─────┐\n │\n ┌O─────────────────────┐\n │forwardRule()│\n └┬─────────────────────┘\n ┌─────┘\n │\n ┌O────┐\n │gmail│\n └┬────┘\n └─────┐\n │\n ┌O──────────────────────┐\n │clientAccess()│\n └O──────────────────────┘\n ┌─────┘\n │\n ┌┴───────────────────────┐\n │thunderbird / mutt / etc│\n └────────────────────────┘\n\n## Sending email\n\nThe message is now outside of Outlook, and if the Institution does not\nallow non-authorized clients (often this means they only allow Microsoft\ntools) to connect to the Outlook server, the following work around will\nhelp. Essentially, the outside client should be configured to send email\nusing a properly setup `postfix` server that simply copies the target\nemail to an `mbox` file.\n\nThis `mbox` file is then monitored for any changes, and on a change\n(assumed to mean a new email message has been appended), a new process\nis fired off to parse off the latest message and then use the command\nline `m365` CLI tool to have the IOS send the email.\n\n ┌───────────────────────┐\n │thundebird / mutt /etc │\n └┬──────────────────────┘\n │\n └─────┐\n │\n ┌O────────────────────────────┐\n │sendmail() (postfix)│\n └┬────────────────────────────┘\n ┌─────┘\n │\n ┌O────┐\n │mbox │\n └┬────┘\n └─────┐\n │\n ┌O────────┐\n │mbox2m365│ <--- this repo!\n └┬────────┘\n ┌─────┘\n │\n ┌O─────────────┐\n │m365 │\n └┬─────────────┘\n │\n ┌O────────────────────────────────┐\n │IOS that transmits outgoing email│\n └─────────────────────────────────┘\n\n# `mbox2m365`\n\nWhile all the building blocks to effect the solution exist, the one\nmissing piece is the `mbox` to `m365` block, which is provided for by\nthis rather simple python script.\n\n# Setup your helper mail server, `postfix`\n\nFirst, install `postfix`\n\n## Arch\n\n``` bash\nyay -S postfix\n```\n\n## Ubuntu\n\n``` bash\nsudo apt install postfix\n```\n\n# `transport`\n\nNow, edit the `transport` file.\n\n``` bash\nsudo bash\ncd /etc/postfix\ncp transport transport.orig\necho "* local:rudolph" >> transport\n```\n\n# `main.cf`\n\nFor the `main.cf` file, do\n\n``` bash\n# Assuming you are still in the /etc/postfix dir in a sudo bash shell...\ncp main.cf main.cf.orig\necho "mydomain = pangea.net" >> main.cf\necho "luser_relay = rudolph@pangea.net"\necho "transport_maps = hash:/etc/postfix/transport" >> main.cf\n```\n\n# enable/restart the services\n\n``` bash\nsudo systemctl enable postfix.service\nsudo systemctl restart postfix.service\n```\n\n# Email client\n\nSimply configure your email client to use the machine running `postfix`\nas your email server. All emails will be appended to the `transport`\nuser’s `mbox` file.\n\n# Fire up `mbox2m365`\n\nThe final piece of the puzzle:\n\n``` bash\ncd /var/mail\nfind . | entr mbox2m365 --mbox rudolph --b64_encode \\\n --sendFromFile --cleanUp \\\n --waitForStragglers 5\n```\n\n*-30-*\n'` 2023-05-30T16:46:34,622 According to the spec (see the link below), however, setuptools CANNOT 2023-05-30T16:46:34,622 consider this value unless `readme` is listed as `dynamic`. 2023-05-30T16:46:34,623 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-05-30T16:46:34,624 For the time being, `setuptools` will still consider the given value (as a 2023-05-30T16:46:34,624 **transitional** measure), but please note that future releases of setuptools will 2023-05-30T16:46:34,624 follow strictly the standard. 2023-05-30T16:46:34,625 To prevent this warning, you can list `readme` under `dynamic` or alternatively 2023-05-30T16:46:34,625 remove the `[project]` table from your file and rely entirely on other means of 2023-05-30T16:46:34,626 configuration. 2023-05-30T16:46:34,626 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-05-30T16:46:34,627 or your builds will no longer be supported. 2023-05-30T16:46:34,627 ******************************************************************************** 2023-05-30T16:46:34,627 !! 2023-05-30T16:46:34,628 _handle_missing_dynamic(dist, project_table) 2023-05-30T16:46:35,252 running dist_info 2023-05-30T16:46:35,269 creating /tmp/pip-modern-metadata-q4hnsdph/mbox2m365.egg-info 2023-05-30T16:46:35,278 writing /tmp/pip-modern-metadata-q4hnsdph/mbox2m365.egg-info/PKG-INFO 2023-05-30T16:46:35,284 writing dependency_links to /tmp/pip-modern-metadata-q4hnsdph/mbox2m365.egg-info/dependency_links.txt 2023-05-30T16:46:35,289 writing entry points to /tmp/pip-modern-metadata-q4hnsdph/mbox2m365.egg-info/entry_points.txt 2023-05-30T16:46:35,292 writing requirements to /tmp/pip-modern-metadata-q4hnsdph/mbox2m365.egg-info/requires.txt 2023-05-30T16:46:35,294 writing top-level names to /tmp/pip-modern-metadata-q4hnsdph/mbox2m365.egg-info/top_level.txt 2023-05-30T16:46:35,296 writing manifest file '/tmp/pip-modern-metadata-q4hnsdph/mbox2m365.egg-info/SOURCES.txt' 2023-05-30T16:46:35,329 reading manifest file '/tmp/pip-modern-metadata-q4hnsdph/mbox2m365.egg-info/SOURCES.txt' 2023-05-30T16:46:35,334 reading manifest template 'MANIFEST.in' 2023-05-30T16:46:35,336 adding license file 'LICENSE' 2023-05-30T16:46:35,341 writing manifest file '/tmp/pip-modern-metadata-q4hnsdph/mbox2m365.egg-info/SOURCES.txt' 2023-05-30T16:46:35,343 creating '/tmp/pip-modern-metadata-q4hnsdph/mbox2m365-3.0.14.dist-info' 2023-05-30T16:46:35,420 /tmp/pip-build-env-9on6lzu3/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `license` defined outside of `pyproject.toml` would be ignored. 2023-05-30T16:46:35,421 !! 2023-05-30T16:46:35,422 ******************************************************************************** 2023-05-30T16:46:35,422 ########################################################################## 2023-05-30T16:46:35,423 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-05-30T16:46:35,423 ########################################################################## 2023-05-30T16:46:35,424 The following seems to be defined outside of `pyproject.toml`: 2023-05-30T16:46:35,425 `license = 'MIT'` 2023-05-30T16:46:35,426 According to the spec (see the link below), however, setuptools CANNOT 2023-05-30T16:46:35,427 consider this value unless `license` is listed as `dynamic`. 2023-05-30T16:46:35,428 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-05-30T16:46:35,429 For the time being, `setuptools` will still consider the given value (as a 2023-05-30T16:46:35,429 **transitional** measure), but please note that future releases of setuptools will 2023-05-30T16:46:35,429 follow strictly the standard. 2023-05-30T16:46:35,430 To prevent this warning, you can list `license` under `dynamic` or alternatively 2023-05-30T16:46:35,431 remove the `[project]` table from your file and rely entirely on other means of 2023-05-30T16:46:35,431 configuration. 2023-05-30T16:46:35,432 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-05-30T16:46:35,433 or your builds will no longer be supported. 2023-05-30T16:46:35,433 ******************************************************************************** 2023-05-30T16:46:35,434 !! 2023-05-30T16:46:35,435 _handle_missing_dynamic(dist, project_table) 2023-05-30T16:46:35,435 /tmp/pip-build-env-9on6lzu3/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `authors` defined outside of `pyproject.toml` would be ignored. 2023-05-30T16:46:35,436 !! 2023-05-30T16:46:35,436 ******************************************************************************** 2023-05-30T16:46:35,437 ########################################################################## 2023-05-30T16:46:35,437 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-05-30T16:46:35,438 ########################################################################## 2023-05-30T16:46:35,438 The following seems to be defined outside of `pyproject.toml`: 2023-05-30T16:46:35,439 `authors = 'Rudolph Pienaar'` 2023-05-30T16:46:35,440 According to the spec (see the link below), however, setuptools CANNOT 2023-05-30T16:46:35,441 consider this value unless `authors` is listed as `dynamic`. 2023-05-30T16:46:35,442 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-05-30T16:46:35,442 For the time being, `setuptools` will still consider the given value (as a 2023-05-30T16:46:35,443 **transitional** measure), but please note that future releases of setuptools will 2023-05-30T16:46:35,443 follow strictly the standard. 2023-05-30T16:46:35,444 To prevent this warning, you can list `authors` under `dynamic` or alternatively 2023-05-30T16:46:35,444 remove the `[project]` table from your file and rely entirely on other means of 2023-05-30T16:46:35,445 configuration. 2023-05-30T16:46:35,446 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-05-30T16:46:35,446 or your builds will no longer be supported. 2023-05-30T16:46:35,446 ******************************************************************************** 2023-05-30T16:46:35,447 !! 2023-05-30T16:46:35,448 _handle_missing_dynamic(dist, project_table) 2023-05-30T16:46:35,598 Preparing metadata (pyproject.toml): finished with status 'done' 2023-05-30T16:46:35,615 Source in /tmp/pip-wheel-thfxmtv1/mbox2m365_076d68e182cf4e538da7a222222f9ca0 has version 3.0.14, which satisfies requirement mbox2m365==3.0.14 from https://files.pythonhosted.org/packages/24/48/5765400ed318e16ce6a1f901a7e1e39efe14da6f6e16baba3bc7970f5be4/mbox2m365-3.0.14.tar.gz 2023-05-30T16:46:35,616 Removed mbox2m365==3.0.14 from https://files.pythonhosted.org/packages/24/48/5765400ed318e16ce6a1f901a7e1e39efe14da6f6e16baba3bc7970f5be4/mbox2m365-3.0.14.tar.gz from build tracker '/tmp/pip-build-tracker-fvnytcuv' 2023-05-30T16:46:35,627 Created temporary directory: /tmp/pip-unpack-whw9g0_w 2023-05-30T16:46:35,629 Building wheels for collected packages: mbox2m365 2023-05-30T16:46:35,638 Created temporary directory: /tmp/pip-wheel-v327tj9l 2023-05-30T16:46:35,638 Destination directory: /tmp/pip-wheel-v327tj9l 2023-05-30T16:46:35,643 Building wheel for mbox2m365 (pyproject.toml): started 2023-05-30T16:46:35,645 Running command Building wheel for mbox2m365 (pyproject.toml) 2023-05-30T16:46:36,877 /tmp/pip-build-env-9on6lzu3/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `description` defined outside of `pyproject.toml` would be ignored. 2023-05-30T16:46:36,878 !! 2023-05-30T16:46:36,879 ******************************************************************************** 2023-05-30T16:46:36,880 ########################################################################## 2023-05-30T16:46:36,880 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-05-30T16:46:36,880 ########################################################################## 2023-05-30T16:46:36,881 The following seems to be defined outside of `pyproject.toml`: 2023-05-30T16:46:36,882 `description = "'Send a message stored within an mbox using m365 (Office365)'"` 2023-05-30T16:46:36,882 According to the spec (see the link below), however, setuptools CANNOT 2023-05-30T16:46:36,883 consider this value unless `description` is listed as `dynamic`. 2023-05-30T16:46:36,883 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-05-30T16:46:36,884 For the time being, `setuptools` will still consider the given value (as a 2023-05-30T16:46:36,884 **transitional** measure), but please note that future releases of setuptools will 2023-05-30T16:46:36,885 follow strictly the standard. 2023-05-30T16:46:36,885 To prevent this warning, you can list `description` under `dynamic` or alternatively 2023-05-30T16:46:36,886 remove the `[project]` table from your file and rely entirely on other means of 2023-05-30T16:46:36,886 configuration. 2023-05-30T16:46:36,886 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-05-30T16:46:36,887 or your builds will no longer be supported. 2023-05-30T16:46:36,887 ******************************************************************************** 2023-05-30T16:46:36,888 !! 2023-05-30T16:46:36,888 _handle_missing_dynamic(dist, project_table) 2023-05-30T16:46:36,888 /tmp/pip-build-env-9on6lzu3/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `readme` defined outside of `pyproject.toml` would be ignored. 2023-05-30T16:46:36,889 !! 2023-05-30T16:46:36,889 ******************************************************************************** 2023-05-30T16:46:36,890 ########################################################################## 2023-05-30T16:46:36,890 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-05-30T16:46:36,890 ########################################################################## 2023-05-30T16:46:36,891 The following seems to be defined outside of `pyproject.toml`: 2023-05-30T16:46:36,892 `readme = '# Abstract\n\nThis repository contains a simple python script that (1) processes an\n`mbox` style mailbox file, (2) parses out (typically) the last message\nand then (3) re-transmits this using the CLI `m365` toolset. While this\nscript can be used in a completely stand-alone manner to extract a\nmessage from an `mbox` and then *send* using `m365`, it’s main utility\nis when used in a full ecosystem including an email client and `postfix`\nserver.\n\nThe CLI `m365` offers the ability to use Outlook/Office365 to send\nemails. However, this tool is not suited to use as a mail client\u2009—\u2009it\nmerely offers a means to transmit a message from the command line. More\nuseful would be if existing mail clients could leverage `m365` natively.\nCurrently, however, this is not available. Therefore, `mbox2m365` was\ncreated to complete a "missing link" in a full email experience. Using\nthis tool in a configured environment, it is now possible to use *any*\nemail client to transmit messages using Outlook/Office365.\n\n# TL;DR\n\nEven if you’re impatient, it’s a good idea to read this document.\nHowever, assuming you’ve already built the infrastructure, assuming you\nhave installed `m365` (and logged into your Institution from `m365`),\nhave assuming you have setup your email client to email to a dummy local\npostfix account, then you can install `mbox2m365` with a simple\n\n``` bash\npip install mbox2m365\n```\n\nnote at time of writing the PyPI install might not be available. In that\ncase, simply clone this repo and do a\n\n``` bash\n# From the repo root dir\npip install -U .\n```\n\nand fire it off by setting up the monitor on the `mbox` file (here we\nassume the mbox belongs to `rudolph`)\n\n``` bash\ncd /var/mail\nfind . | entr mbox2m365 --mbox rudolph --b64_encode \\\n --sendFromFile --cleanUp \\\n --waitForStragglers 5\n```\n\n(Clearly the above relies on [`entr`](https://github.com/eradman/entr).\nConsult your distro’s repos for the appropriate install. In arch, this\nis `yay -S entr`, in Ubuntu, this is `sudo apt install entr`)\n\n# Security alert!\n\nWait! **Danger, Will Robinson**! Doesn’t this violate security policies?\nI was told my Institution does *not* allow clients like thunderbird to\nconnect to the Outlook server to send emails!\n\nWell, the devil is in the details as the saying goes. This solution does\n*not* violate policy since the "unauthenticated" email client is *not*\never connecting/authenticating to the Outlook server. Rather, the\n"unauthenticated" email client sends messages to a specially configured\nserver that "saves" the emails to a file. Then, a separate program\nteases out the new arrivals and uses the **authenticated** `m365`\nprogram to actually talk to and leverage Outlook to send the email. This\n*separate program* that bridges the mail file to `m365` is none other\nthan this python module.\n\nSo to be pendantic: all credentialing and authentication is handled by\n`m365` and *not* this tool. The end user is still required to\nlogin/authenticate using `m365`. If this has not happened, then\n`mbox2m365` will not work.\n\nAgain, this repo contains **no** authentication tokens/passwords/etc.\n\n# Limitations\n\nLet’s get these out of the way first. This is *not* a full solution for\nlinking a third party email client to Outlook. It gets *close*, IMHO.\nThe limitations are:\n\n- This is not a multi-user solution. All email transmitted to the\n intermediate helper server is added to a single user `mbox` which when\n processed by this script means **all** email in that `mbox` will\n appear to have been transmitted by that user. While in theory it\n should be possible to support multiple users, either by having a\n separate helper server per user or by having multiple local users on\n the mail server and separate `mbox` files, the current solution is\n clearly not scalable. It is decent though for the single user case.\n\n- Fundmanentally, this solution is limited first and foremost by the\n capabilities of the CLI `m365 outlook mail send` functionality. Recent\n updates to `m365` have expanded functionality of this bridge\u2009—\u2009most\n notably attachments are now supported. Still pending is full `bcc`\n support\u2009—\u2009currently all `bcc` recipients are switched to `cc`.\n\nOther limitations stem from the fact the bridge needs to process the\n`mbox` file *de novo* each time mail is received by the helper server.\nThis means that time to process will increase linearly with `mbox` size.\nThe real world implications of this are still being explored.\n\nFinally, the bridge does make a best effort attempt to *wait* until the\n`mbox` has stabilized before analyzing it. When sending emails to\nmultiple recipients, *each* recipient gets a single complete copy in the\n`mbox` with a single address (the multiple recipient addresses are not\nconserved in the `mbox` but *are* processed by this bridge). While\narguably wasteful, the implication is that while all these recipient\ncopies are appended to the `mbox`, the bridge should wait until all have\nbeen added before processing. Currently the bridge attempts this by\nexamining the `mbox` file size when called, and waiting a small delta\ntime interval and checking if the size has changed again. It will wait\nuntil the size is stable before continuing. The TL;DR is this could\nresult in a processing delay.\n\n# Introduction\n\nThe migration/adoption of Office365 by institutions often poses issues\nand problems for users wishing to use different tools for email\ntransmission, particularly on platforms such as Linux.\n\nWhile it is possible to access various Office365 applications,\nparticularly Outlook, via a web interface, this is often not sufficient\nfor several classes of users, particularly those who find the web\ninterface cumbersome (for instance, the web interface has no (or\nlimited) support for keyboard shortcuts, it is cumbersome if not\nimpossible to automate tasks involving event-driven email) and/or for\nusers who have an existing and efficient email workflow using clients\nsuch as `thunderbird` or `mutt`.\n\nThis small repo houses a small and simple python application with some\nsupporting documentation that provides a solution to the problem of\nsending email from an instituion’s managed domain by leveraging\n`postfix` and some `mbox` processing and then using the CLI tool `m365`.\n\n# Method Summary\n\nThe solution requires some seemingly contortuous steps, but in reality\nis rather simple and can be summarized as follows:\n\n## Reading email\n\nReading emails that are locked away in an Outlook server is best\neffected by simply adding a forward incoming email rule from your\nInstitution Outlook Server (IOS) to an externally accessible email\nprovider (such as `gmail`), allowing this email to be read easily by\ntools such as `thunderbird` or `mutt`.\n\n ┌─────────────────────────────────┐\n │IOS that receives incoming email │\n └┬────────────────────────────────┘\n │\n └─────┐\n │\n ┌O─────────────────────┐\n │forwardRule()│\n └┬─────────────────────┘\n ┌─────┘\n │\n ┌O────┐\n │gmail│\n └┬────┘\n └─────┐\n │\n ┌O──────────────────────┐\n │clientAccess()│\n └O──────────────────────┘\n ┌─────┘\n │\n ┌┴───────────────────────┐\n │thunderbird / mutt / etc│\n └────────────────────────┘\n\n## Sending email\n\nThe message is now outside of Outlook, and if the Institution does not\nallow non-authorized clients (often this means they only allow Microsoft\ntools) to connect to the Outlook server, the following work around will\nhelp. Essentially, the outside client should be configured to send email\nusing a properly setup `postfix` server that simply copies the target\nemail to an `mbox` file.\n\nThis `mbox` file is then monitored for any changes, and on a change\n(assumed to mean a new email message has been appended), a new process\nis fired off to parse off the latest message and then use the command\nline `m365` CLI tool to have the IOS send the email.\n\n ┌───────────────────────┐\n │thundebird / mutt /etc │\n └┬──────────────────────┘\n │\n └─────┐\n │\n ┌O────────────────────────────┐\n │sendmail() (postfix)│\n └┬────────────────────────────┘\n ┌─────┘\n │\n ┌O────┐\n │mbox │\n └┬────┘\n └─────┐\n │\n ┌O────────┐\n │mbox2m365│ <--- this repo!\n └┬────────┘\n ┌─────┘\n │\n ┌O─────────────┐\n │m365 │\n └┬─────────────┘\n │\n ┌O────────────────────────────────┐\n │IOS that transmits outgoing email│\n └─────────────────────────────────┘\n\n# `mbox2m365`\n\nWhile all the building blocks to effect the solution exist, the one\nmissing piece is the `mbox` to `m365` block, which is provided for by\nthis rather simple python script.\n\n# Setup your helper mail server, `postfix`\n\nFirst, install `postfix`\n\n## Arch\n\n``` bash\nyay -S postfix\n```\n\n## Ubuntu\n\n``` bash\nsudo apt install postfix\n```\n\n# `transport`\n\nNow, edit the `transport` file.\n\n``` bash\nsudo bash\ncd /etc/postfix\ncp transport transport.orig\necho "* local:rudolph" >> transport\n```\n\n# `main.cf`\n\nFor the `main.cf` file, do\n\n``` bash\n# Assuming you are still in the /etc/postfix dir in a sudo bash shell...\ncp main.cf main.cf.orig\necho "mydomain = pangea.net" >> main.cf\necho "luser_relay = rudolph@pangea.net"\necho "transport_maps = hash:/etc/postfix/transport" >> main.cf\n```\n\n# enable/restart the services\n\n``` bash\nsudo systemctl enable postfix.service\nsudo systemctl restart postfix.service\n```\n\n# Email client\n\nSimply configure your email client to use the machine running `postfix`\nas your email server. All emails will be appended to the `transport`\nuser’s `mbox` file.\n\n# Fire up `mbox2m365`\n\nThe final piece of the puzzle:\n\n``` bash\ncd /var/mail\nfind . | entr mbox2m365 --mbox rudolph --b64_encode \\\n --sendFromFile --cleanUp \\\n --waitForStragglers 5\n```\n\n*-30-*\n'` 2023-05-30T16:46:36,894 According to the spec (see the link below), however, setuptools CANNOT 2023-05-30T16:46:36,894 consider this value unless `readme` is listed as `dynamic`. 2023-05-30T16:46:36,895 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-05-30T16:46:36,895 For the time being, `setuptools` will still consider the given value (as a 2023-05-30T16:46:36,895 **transitional** measure), but please note that future releases of setuptools will 2023-05-30T16:46:36,896 follow strictly the standard. 2023-05-30T16:46:36,896 To prevent this warning, you can list `readme` under `dynamic` or alternatively 2023-05-30T16:46:36,897 remove the `[project]` table from your file and rely entirely on other means of 2023-05-30T16:46:36,897 configuration. 2023-05-30T16:46:36,898 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-05-30T16:46:36,898 or your builds will no longer be supported. 2023-05-30T16:46:36,898 ******************************************************************************** 2023-05-30T16:46:36,899 !! 2023-05-30T16:46:36,899 _handle_missing_dynamic(dist, project_table) 2023-05-30T16:46:37,498 running bdist_wheel 2023-05-30T16:46:37,535 running build 2023-05-30T16:46:37,535 running build_py 2023-05-30T16:46:37,547 creating build 2023-05-30T16:46:37,548 creating build/lib 2023-05-30T16:46:37,549 creating build/lib/mbox2m365 2023-05-30T16:46:37,552 copying mbox2m365/__init__.py -> build/lib/mbox2m365 2023-05-30T16:46:37,556 copying mbox2m365/mbox2m365.py -> build/lib/mbox2m365 2023-05-30T16:46:37,561 copying mbox2m365/__main__.py -> build/lib/mbox2m365 2023-05-30T16:46:37,567 creating build/lib/jobber 2023-05-30T16:46:37,568 copying jobber/jobber.py -> build/lib/jobber 2023-05-30T16:46:37,573 running egg_info 2023-05-30T16:46:37,592 writing mbox2m365.egg-info/PKG-INFO 2023-05-30T16:46:37,596 writing dependency_links to mbox2m365.egg-info/dependency_links.txt 2023-05-30T16:46:37,600 writing entry points to mbox2m365.egg-info/entry_points.txt 2023-05-30T16:46:37,602 writing requirements to mbox2m365.egg-info/requires.txt 2023-05-30T16:46:37,604 writing top-level names to mbox2m365.egg-info/top_level.txt 2023-05-30T16:46:37,621 reading manifest file 'mbox2m365.egg-info/SOURCES.txt' 2023-05-30T16:46:37,625 reading manifest template 'MANIFEST.in' 2023-05-30T16:46:37,627 adding license file 'LICENSE' 2023-05-30T16:46:37,632 writing manifest file 'mbox2m365.egg-info/SOURCES.txt' 2023-05-30T16:46:37,654 installing to build/bdist.linux-armv7l/wheel 2023-05-30T16:46:37,655 running install 2023-05-30T16:46:37,716 running install_lib 2023-05-30T16:46:37,727 creating build/bdist.linux-armv7l 2023-05-30T16:46:37,728 creating build/bdist.linux-armv7l/wheel 2023-05-30T16:46:37,731 creating build/bdist.linux-armv7l/wheel/mbox2m365 2023-05-30T16:46:37,733 copying build/lib/mbox2m365/__init__.py -> build/bdist.linux-armv7l/wheel/mbox2m365 2023-05-30T16:46:37,738 copying build/lib/mbox2m365/mbox2m365.py -> build/bdist.linux-armv7l/wheel/mbox2m365 2023-05-30T16:46:37,743 copying build/lib/mbox2m365/__main__.py -> build/bdist.linux-armv7l/wheel/mbox2m365 2023-05-30T16:46:37,749 creating build/bdist.linux-armv7l/wheel/jobber 2023-05-30T16:46:37,751 copying build/lib/jobber/jobber.py -> build/bdist.linux-armv7l/wheel/jobber 2023-05-30T16:46:37,756 running install_egg_info 2023-05-30T16:46:37,765 Copying mbox2m365.egg-info to build/bdist.linux-armv7l/wheel/mbox2m365-3.0.14-py3.7.egg-info 2023-05-30T16:46:37,791 running install_scripts 2023-05-30T16:46:37,831 creating build/bdist.linux-armv7l/wheel/mbox2m365-3.0.14.dist-info/WHEEL 2023-05-30T16:46:37,836 creating '/tmp/pip-wheel-v327tj9l/.tmp-kae7z6hd/mbox2m365-3.0.14-py3-none-any.whl' and adding 'build/bdist.linux-armv7l/wheel' to it 2023-05-30T16:46:37,842 adding 'jobber/jobber.py' 2023-05-30T16:46:37,846 adding 'mbox2m365/__init__.py' 2023-05-30T16:46:37,850 adding 'mbox2m365/__main__.py' 2023-05-30T16:46:37,860 adding 'mbox2m365/mbox2m365.py' 2023-05-30T16:46:37,865 adding 'mbox2m365-3.0.14.dist-info/LICENSE' 2023-05-30T16:46:37,870 adding 'mbox2m365-3.0.14.dist-info/METADATA' 2023-05-30T16:46:37,872 adding 'mbox2m365-3.0.14.dist-info/WHEEL' 2023-05-30T16:46:37,874 adding 'mbox2m365-3.0.14.dist-info/entry_points.txt' 2023-05-30T16:46:37,876 adding 'mbox2m365-3.0.14.dist-info/top_level.txt' 2023-05-30T16:46:37,878 adding 'mbox2m365-3.0.14.dist-info/RECORD' 2023-05-30T16:46:37,881 removing build/bdist.linux-armv7l/wheel 2023-05-30T16:46:37,896 /tmp/pip-build-env-9on6lzu3/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `license` defined outside of `pyproject.toml` would be ignored. 2023-05-30T16:46:37,896 !! 2023-05-30T16:46:37,897 ******************************************************************************** 2023-05-30T16:46:37,897 ########################################################################## 2023-05-30T16:46:37,898 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-05-30T16:46:37,898 ########################################################################## 2023-05-30T16:46:37,899 The following seems to be defined outside of `pyproject.toml`: 2023-05-30T16:46:37,900 `license = 'MIT'` 2023-05-30T16:46:37,901 According to the spec (see the link below), however, setuptools CANNOT 2023-05-30T16:46:37,902 consider this value unless `license` is listed as `dynamic`. 2023-05-30T16:46:37,903 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-05-30T16:46:37,904 For the time being, `setuptools` will still consider the given value (as a 2023-05-30T16:46:37,904 **transitional** measure), but please note that future releases of setuptools will 2023-05-30T16:46:37,904 follow strictly the standard. 2023-05-30T16:46:37,905 To prevent this warning, you can list `license` under `dynamic` or alternatively 2023-05-30T16:46:37,906 remove the `[project]` table from your file and rely entirely on other means of 2023-05-30T16:46:37,906 configuration. 2023-05-30T16:46:37,907 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-05-30T16:46:37,908 or your builds will no longer be supported. 2023-05-30T16:46:37,908 ******************************************************************************** 2023-05-30T16:46:37,909 !! 2023-05-30T16:46:37,909 _handle_missing_dynamic(dist, project_table) 2023-05-30T16:46:37,910 /tmp/pip-build-env-9on6lzu3/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `authors` defined outside of `pyproject.toml` would be ignored. 2023-05-30T16:46:37,910 !! 2023-05-30T16:46:37,911 ******************************************************************************** 2023-05-30T16:46:37,912 ########################################################################## 2023-05-30T16:46:37,912 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-05-30T16:46:37,912 ########################################################################## 2023-05-30T16:46:37,913 The following seems to be defined outside of `pyproject.toml`: 2023-05-30T16:46:37,914 `authors = 'Rudolph Pienaar'` 2023-05-30T16:46:37,915 According to the spec (see the link below), however, setuptools CANNOT 2023-05-30T16:46:37,915 consider this value unless `authors` is listed as `dynamic`. 2023-05-30T16:46:37,916 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-05-30T16:46:37,917 For the time being, `setuptools` will still consider the given value (as a 2023-05-30T16:46:37,917 **transitional** measure), but please note that future releases of setuptools will 2023-05-30T16:46:37,918 follow strictly the standard. 2023-05-30T16:46:37,918 To prevent this warning, you can list `authors` under `dynamic` or alternatively 2023-05-30T16:46:37,919 remove the `[project]` table from your file and rely entirely on other means of 2023-05-30T16:46:37,919 configuration. 2023-05-30T16:46:37,920 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-05-30T16:46:37,921 or your builds will no longer be supported. 2023-05-30T16:46:37,921 ******************************************************************************** 2023-05-30T16:46:37,922 !! 2023-05-30T16:46:37,922 _handle_missing_dynamic(dist, project_table) 2023-05-30T16:46:38,074 Building wheel for mbox2m365 (pyproject.toml): finished with status 'done' 2023-05-30T16:46:38,089 Created wheel for mbox2m365: filename=mbox2m365-3.0.14-py3-none-any.whl size=19424 sha256=63fec01e1f79300cc926e7d89e60e23181f7209ee44f7f69d109591b67548b0e 2023-05-30T16:46:38,091 Stored in directory: /tmp/pip-ephem-wheel-cache-mrkerkll/wheels/1a/1f/c8/26bafdfbcdc5fe94da6e2a83c95652442ca397a303f01d3bf9 2023-05-30T16:46:38,118 Successfully built mbox2m365 2023-05-30T16:46:38,126 Removed build tracker: '/tmp/pip-build-tracker-fvnytcuv'