2023-06-19T23:26:32,501 Created temporary directory: /tmp/pip-build-tracker-b0blhhsh 2023-06-19T23:26:32,504 Initialized build tracking at /tmp/pip-build-tracker-b0blhhsh 2023-06-19T23:26:32,505 Created build tracker: /tmp/pip-build-tracker-b0blhhsh 2023-06-19T23:26:32,505 Entered build tracker: /tmp/pip-build-tracker-b0blhhsh 2023-06-19T23:26:32,506 Created temporary directory: /tmp/pip-wheel-00171i84 2023-06-19T23:26:32,514 Created temporary directory: /tmp/pip-ephem-wheel-cache-yhzm78hd 2023-06-19T23:26:32,569 Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple 2023-06-19T23:26:32,577 2 location(s) to search for versions of mbox2m365: 2023-06-19T23:26:32,577 * https://pypi.org/simple/mbox2m365/ 2023-06-19T23:26:32,577 * https://www.piwheels.org/simple/mbox2m365/ 2023-06-19T23:26:32,578 Fetching project page and analyzing links: https://pypi.org/simple/mbox2m365/ 2023-06-19T23:26:32,579 Getting page https://pypi.org/simple/mbox2m365/ 2023-06-19T23:26:32,584 Found index url https://pypi.org/simple/ 2023-06-19T23:26:32,779 Fetched page https://pypi.org/simple/mbox2m365/ as application/vnd.pypi.simple.v1+json 2023-06-19T23:26:32,783 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-06-19T23:26:32,784 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-06-19T23:26:32,785 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-06-19T23:26:32,786 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-06-19T23:26:32,787 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-06-19T23:26:32,787 Found link https://files.pythonhosted.org/packages/65/c6/9490d087c5f5c65e12e7a9c483c2fe53ac3d9a6cb1491d4295908f889867/mbox2m365-3.0.16.tar.gz (from https://pypi.org/simple/mbox2m365/), version: 3.0.16 2023-06-19T23:26:32,788 Found link https://files.pythonhosted.org/packages/45/69/737b97ff918c42a5455925b30d09ef252a748326e6922bf78e381a52caea/mbox2m365-3.2.0.tar.gz (from https://pypi.org/simple/mbox2m365/), version: 3.2.0 2023-06-19T23:26:32,789 Fetching project page and analyzing links: https://www.piwheels.org/simple/mbox2m365/ 2023-06-19T23:26:32,790 Getting page https://www.piwheels.org/simple/mbox2m365/ 2023-06-19T23:26:32,792 Found index url https://www.piwheels.org/simple/ 2023-06-19T23:26:33,012 Fetched page https://www.piwheels.org/simple/mbox2m365/ as text/html 2023-06-19T23:26:33,017 Skipping link: No binaries permitted for mbox2m365: https://www.piwheels.org/simple/mbox2m365/mbox2m365-3.0.16-py3-none-any.whl#sha256=568f57fcd89807e61a8fc09c23259f313f8d280c51b7a18ebd42ed73fecfd38c (from https://www.piwheels.org/simple/mbox2m365/) 2023-06-19T23:26:33,017 Skipping link: No binaries permitted for mbox2m365: https://www.piwheels.org/simple/mbox2m365/mbox2m365-3.0.14-py3-none-any.whl#sha256=63fec01e1f79300cc926e7d89e60e23181f7209ee44f7f69d109591b67548b0e (from https://www.piwheels.org/simple/mbox2m365/) 2023-06-19T23:26:33,018 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-06-19T23:26:33,018 Skipping link: not a file: https://www.piwheels.org/simple/mbox2m365/ 2023-06-19T23:26:33,019 Skipping link: not a file: https://pypi.org/simple/mbox2m365/ 2023-06-19T23:26:33,053 Given no hashes to check 1 links for project 'mbox2m365': discarding no candidates 2023-06-19T23:26:33,084 Collecting mbox2m365==3.2.0 2023-06-19T23:26:33,089 Created temporary directory: /tmp/pip-unpack-7wz58cd_ 2023-06-19T23:26:33,286 Downloading mbox2m365-3.2.0.tar.gz (23 kB) 2023-06-19T23:26:33,398 Added mbox2m365==3.2.0 from https://files.pythonhosted.org/packages/45/69/737b97ff918c42a5455925b30d09ef252a748326e6922bf78e381a52caea/mbox2m365-3.2.0.tar.gz to build tracker '/tmp/pip-build-tracker-b0blhhsh' 2023-06-19T23:26:33,411 Created temporary directory: /tmp/pip-build-env-1cb8t47m 2023-06-19T23:26:33,432 Installing build dependencies: started 2023-06-19T23:26:33,434 Running command pip subprocess to install build dependencies 2023-06-19T23:26:36,157 Using pip 23.1.2 from /home/piwheels/.local/lib/python3.7/site-packages/pip (python 3.7) 2023-06-19T23:26:36,926 Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple 2023-06-19T23:26:40,983 Collecting setuptools>=42 2023-06-19T23:26:41,173 Using cached https://www.piwheels.org/simple/setuptools/setuptools-68.0.0-py3-none-any.whl (804 kB) 2023-06-19T23:26:41,805 Collecting wheel 2023-06-19T23:26:41,842 Using cached https://www.piwheels.org/simple/wheel/wheel-0.40.0-py3-none-any.whl (64 kB) 2023-06-19T23:26:46,887 Installing collected packages: wheel, setuptools 2023-06-19T23:26:47,340 Creating /tmp/pip-build-env-1cb8t47m/overlay/bin 2023-06-19T23:26:47,344 changing mode of /tmp/pip-build-env-1cb8t47m/overlay/bin/wheel to 755 2023-06-19T23:26:51,604 Successfully installed setuptools-68.0.0 wheel-0.40.0 2023-06-19T23:26:52,055 Installing build dependencies: finished with status 'done' 2023-06-19T23:26:52,067 Getting requirements to build wheel: started 2023-06-19T23:26:52,069 Running command Getting requirements to build wheel 2023-06-19T23:26:53,446 /tmp/pip-build-env-1cb8t47m/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `description` defined outside of `pyproject.toml` would be ignored. 2023-06-19T23:26:53,448 !! 2023-06-19T23:26:53,448 ******************************************************************************** 2023-06-19T23:26:53,449 ########################################################################## 2023-06-19T23:26:53,449 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-06-19T23:26:53,450 ########################################################################## 2023-06-19T23:26:53,450 The following seems to be defined outside of `pyproject.toml`: 2023-06-19T23:26:53,451 `description = "'Send a message stored within an mbox using m365 (Office365)'"` 2023-06-19T23:26:53,452 According to the spec (see the link below), however, setuptools CANNOT 2023-06-19T23:26:53,452 consider this value unless `description` is listed as `dynamic`. 2023-06-19T23:26:53,452 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-06-19T23:26:53,453 For the time being, `setuptools` will still consider the given value (as a 2023-06-19T23:26:53,453 **transitional** measure), but please note that future releases of setuptools will 2023-06-19T23:26:53,454 follow strictly the standard. 2023-06-19T23:26:53,454 To prevent this warning, you can list `description` under `dynamic` or alternatively 2023-06-19T23:26:53,455 remove the `[project]` table from your file and rely entirely on other means of 2023-06-19T23:26:53,455 configuration. 2023-06-19T23:26:53,456 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-06-19T23:26:53,456 or your builds will no longer be supported. 2023-06-19T23:26:53,456 ******************************************************************************** 2023-06-19T23:26:53,457 !! 2023-06-19T23:26:53,457 _handle_missing_dynamic(dist, project_table) 2023-06-19T23:26:53,458 /tmp/pip-build-env-1cb8t47m/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `readme` defined outside of `pyproject.toml` would be ignored. 2023-06-19T23:26:53,458 !! 2023-06-19T23:26:53,459 ******************************************************************************** 2023-06-19T23:26:53,459 ########################################################################## 2023-06-19T23:26:53,459 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-06-19T23:26:53,460 ########################################################################## 2023-06-19T23:26:53,460 The following seems to be defined outside of `pyproject.toml`: 2023-06-19T23:26:53,461 `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-06-19T23:26:53,463 According to the spec (see the link below), however, setuptools CANNOT 2023-06-19T23:26:53,463 consider this value unless `readme` is listed as `dynamic`. 2023-06-19T23:26:53,464 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-06-19T23:26:53,464 For the time being, `setuptools` will still consider the given value (as a 2023-06-19T23:26:53,465 **transitional** measure), but please note that future releases of setuptools will 2023-06-19T23:26:53,465 follow strictly the standard. 2023-06-19T23:26:53,466 To prevent this warning, you can list `readme` under `dynamic` or alternatively 2023-06-19T23:26:53,466 remove the `[project]` table from your file and rely entirely on other means of 2023-06-19T23:26:53,466 configuration. 2023-06-19T23:26:53,467 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-06-19T23:26:53,467 or your builds will no longer be supported. 2023-06-19T23:26:53,468 ******************************************************************************** 2023-06-19T23:26:53,468 !! 2023-06-19T23:26:53,469 _handle_missing_dynamic(dist, project_table) 2023-06-19T23:26:54,130 running egg_info 2023-06-19T23:26:54,141 writing mbox2m365.egg-info/PKG-INFO 2023-06-19T23:26:54,146 writing dependency_links to mbox2m365.egg-info/dependency_links.txt 2023-06-19T23:26:54,150 writing entry points to mbox2m365.egg-info/entry_points.txt 2023-06-19T23:26:54,153 writing requirements to mbox2m365.egg-info/requires.txt 2023-06-19T23:26:54,155 writing top-level names to mbox2m365.egg-info/top_level.txt 2023-06-19T23:26:54,192 reading manifest file 'mbox2m365.egg-info/SOURCES.txt' 2023-06-19T23:26:54,197 reading manifest template 'MANIFEST.in' 2023-06-19T23:26:54,199 adding license file 'LICENSE' 2023-06-19T23:26:54,204 writing manifest file 'mbox2m365.egg-info/SOURCES.txt' 2023-06-19T23:26:54,208 /tmp/pip-build-env-1cb8t47m/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `license` defined outside of `pyproject.toml` would be ignored. 2023-06-19T23:26:54,208 !! 2023-06-19T23:26:54,209 ******************************************************************************** 2023-06-19T23:26:54,209 ########################################################################## 2023-06-19T23:26:54,210 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-06-19T23:26:54,210 ########################################################################## 2023-06-19T23:26:54,211 The following seems to be defined outside of `pyproject.toml`: 2023-06-19T23:26:54,212 `license = 'MIT'` 2023-06-19T23:26:54,213 According to the spec (see the link below), however, setuptools CANNOT 2023-06-19T23:26:54,214 consider this value unless `license` is listed as `dynamic`. 2023-06-19T23:26:54,215 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-06-19T23:26:54,216 For the time being, `setuptools` will still consider the given value (as a 2023-06-19T23:26:54,216 **transitional** measure), but please note that future releases of setuptools will 2023-06-19T23:26:54,216 follow strictly the standard. 2023-06-19T23:26:54,217 To prevent this warning, you can list `license` under `dynamic` or alternatively 2023-06-19T23:26:54,218 remove the `[project]` table from your file and rely entirely on other means of 2023-06-19T23:26:54,218 configuration. 2023-06-19T23:26:54,219 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-06-19T23:26:54,220 or your builds will no longer be supported. 2023-06-19T23:26:54,220 ******************************************************************************** 2023-06-19T23:26:54,221 !! 2023-06-19T23:26:54,221 _handle_missing_dynamic(dist, project_table) 2023-06-19T23:26:54,222 /tmp/pip-build-env-1cb8t47m/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `authors` defined outside of `pyproject.toml` would be ignored. 2023-06-19T23:26:54,222 !! 2023-06-19T23:26:54,223 ******************************************************************************** 2023-06-19T23:26:54,224 ########################################################################## 2023-06-19T23:26:54,224 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-06-19T23:26:54,224 ########################################################################## 2023-06-19T23:26:54,225 The following seems to be defined outside of `pyproject.toml`: 2023-06-19T23:26:54,226 `authors = 'Rudolph Pienaar'` 2023-06-19T23:26:54,227 According to the spec (see the link below), however, setuptools CANNOT 2023-06-19T23:26:54,228 consider this value unless `authors` is listed as `dynamic`. 2023-06-19T23:26:54,228 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-06-19T23:26:54,229 For the time being, `setuptools` will still consider the given value (as a 2023-06-19T23:26:54,230 **transitional** measure), but please note that future releases of setuptools will 2023-06-19T23:26:54,230 follow strictly the standard. 2023-06-19T23:26:54,231 To prevent this warning, you can list `authors` under `dynamic` or alternatively 2023-06-19T23:26:54,231 remove the `[project]` table from your file and rely entirely on other means of 2023-06-19T23:26:54,232 configuration. 2023-06-19T23:26:54,232 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-06-19T23:26:54,233 or your builds will no longer be supported. 2023-06-19T23:26:54,233 ******************************************************************************** 2023-06-19T23:26:54,234 !! 2023-06-19T23:26:54,234 _handle_missing_dynamic(dist, project_table) 2023-06-19T23:26:54,385 Getting requirements to build wheel: finished with status 'done' 2023-06-19T23:26:54,405 Created temporary directory: /tmp/pip-modern-metadata-k13z9xcw 2023-06-19T23:26:54,412 Preparing metadata (pyproject.toml): started 2023-06-19T23:26:54,414 Running command Preparing metadata (pyproject.toml) 2023-06-19T23:26:55,661 /tmp/pip-build-env-1cb8t47m/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `description` defined outside of `pyproject.toml` would be ignored. 2023-06-19T23:26:55,662 !! 2023-06-19T23:26:55,663 ******************************************************************************** 2023-06-19T23:26:55,663 ########################################################################## 2023-06-19T23:26:55,663 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-06-19T23:26:55,664 ########################################################################## 2023-06-19T23:26:55,665 The following seems to be defined outside of `pyproject.toml`: 2023-06-19T23:26:55,665 `description = "'Send a message stored within an mbox using m365 (Office365)'"` 2023-06-19T23:26:55,666 According to the spec (see the link below), however, setuptools CANNOT 2023-06-19T23:26:55,667 consider this value unless `description` is listed as `dynamic`. 2023-06-19T23:26:55,667 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-06-19T23:26:55,668 For the time being, `setuptools` will still consider the given value (as a 2023-06-19T23:26:55,668 **transitional** measure), but please note that future releases of setuptools will 2023-06-19T23:26:55,669 follow strictly the standard. 2023-06-19T23:26:55,669 To prevent this warning, you can list `description` under `dynamic` or alternatively 2023-06-19T23:26:55,670 remove the `[project]` table from your file and rely entirely on other means of 2023-06-19T23:26:55,670 configuration. 2023-06-19T23:26:55,670 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-06-19T23:26:55,671 or your builds will no longer be supported. 2023-06-19T23:26:55,671 ******************************************************************************** 2023-06-19T23:26:55,672 !! 2023-06-19T23:26:55,672 _handle_missing_dynamic(dist, project_table) 2023-06-19T23:26:55,672 /tmp/pip-build-env-1cb8t47m/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `readme` defined outside of `pyproject.toml` would be ignored. 2023-06-19T23:26:55,673 !! 2023-06-19T23:26:55,673 ******************************************************************************** 2023-06-19T23:26:55,674 ########################################################################## 2023-06-19T23:26:55,674 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-06-19T23:26:55,675 ########################################################################## 2023-06-19T23:26:55,675 The following seems to be defined outside of `pyproject.toml`: 2023-06-19T23:26:55,676 `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-06-19T23:26:55,678 According to the spec (see the link below), however, setuptools CANNOT 2023-06-19T23:26:55,678 consider this value unless `readme` is listed as `dynamic`. 2023-06-19T23:26:55,679 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-06-19T23:26:55,679 For the time being, `setuptools` will still consider the given value (as a 2023-06-19T23:26:55,680 **transitional** measure), but please note that future releases of setuptools will 2023-06-19T23:26:55,680 follow strictly the standard. 2023-06-19T23:26:55,681 To prevent this warning, you can list `readme` under `dynamic` or alternatively 2023-06-19T23:26:55,681 remove the `[project]` table from your file and rely entirely on other means of 2023-06-19T23:26:55,681 configuration. 2023-06-19T23:26:55,682 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-06-19T23:26:55,682 or your builds will no longer be supported. 2023-06-19T23:26:55,683 ******************************************************************************** 2023-06-19T23:26:55,683 !! 2023-06-19T23:26:55,684 _handle_missing_dynamic(dist, project_table) 2023-06-19T23:26:56,300 running dist_info 2023-06-19T23:26:56,317 creating /tmp/pip-modern-metadata-k13z9xcw/mbox2m365.egg-info 2023-06-19T23:26:56,326 writing /tmp/pip-modern-metadata-k13z9xcw/mbox2m365.egg-info/PKG-INFO 2023-06-19T23:26:56,332 writing dependency_links to /tmp/pip-modern-metadata-k13z9xcw/mbox2m365.egg-info/dependency_links.txt 2023-06-19T23:26:56,336 writing entry points to /tmp/pip-modern-metadata-k13z9xcw/mbox2m365.egg-info/entry_points.txt 2023-06-19T23:26:56,339 writing requirements to /tmp/pip-modern-metadata-k13z9xcw/mbox2m365.egg-info/requires.txt 2023-06-19T23:26:56,341 writing top-level names to /tmp/pip-modern-metadata-k13z9xcw/mbox2m365.egg-info/top_level.txt 2023-06-19T23:26:56,343 writing manifest file '/tmp/pip-modern-metadata-k13z9xcw/mbox2m365.egg-info/SOURCES.txt' 2023-06-19T23:26:56,376 reading manifest file '/tmp/pip-modern-metadata-k13z9xcw/mbox2m365.egg-info/SOURCES.txt' 2023-06-19T23:26:56,381 reading manifest template 'MANIFEST.in' 2023-06-19T23:26:56,382 adding license file 'LICENSE' 2023-06-19T23:26:56,388 writing manifest file '/tmp/pip-modern-metadata-k13z9xcw/mbox2m365.egg-info/SOURCES.txt' 2023-06-19T23:26:56,390 creating '/tmp/pip-modern-metadata-k13z9xcw/mbox2m365-3.2.0.dist-info' 2023-06-19T23:26:56,467 /tmp/pip-build-env-1cb8t47m/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `license` defined outside of `pyproject.toml` would be ignored. 2023-06-19T23:26:56,468 !! 2023-06-19T23:26:56,468 ******************************************************************************** 2023-06-19T23:26:56,469 ########################################################################## 2023-06-19T23:26:56,469 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-06-19T23:26:56,470 ########################################################################## 2023-06-19T23:26:56,471 The following seems to be defined outside of `pyproject.toml`: 2023-06-19T23:26:56,472 `license = 'MIT'` 2023-06-19T23:26:56,473 According to the spec (see the link below), however, setuptools CANNOT 2023-06-19T23:26:56,473 consider this value unless `license` is listed as `dynamic`. 2023-06-19T23:26:56,474 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-06-19T23:26:56,475 For the time being, `setuptools` will still consider the given value (as a 2023-06-19T23:26:56,476 **transitional** measure), but please note that future releases of setuptools will 2023-06-19T23:26:56,477 follow strictly the standard. 2023-06-19T23:26:56,477 To prevent this warning, you can list `license` under `dynamic` or alternatively 2023-06-19T23:26:56,478 remove the `[project]` table from your file and rely entirely on other means of 2023-06-19T23:26:56,478 configuration. 2023-06-19T23:26:56,479 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-06-19T23:26:56,480 or your builds will no longer be supported. 2023-06-19T23:26:56,480 ******************************************************************************** 2023-06-19T23:26:56,481 !! 2023-06-19T23:26:56,482 _handle_missing_dynamic(dist, project_table) 2023-06-19T23:26:56,482 /tmp/pip-build-env-1cb8t47m/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `authors` defined outside of `pyproject.toml` would be ignored. 2023-06-19T23:26:56,483 !! 2023-06-19T23:26:56,483 ******************************************************************************** 2023-06-19T23:26:56,484 ########################################################################## 2023-06-19T23:26:56,484 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-06-19T23:26:56,485 ########################################################################## 2023-06-19T23:26:56,486 The following seems to be defined outside of `pyproject.toml`: 2023-06-19T23:26:56,486 `authors = 'Rudolph Pienaar'` 2023-06-19T23:26:56,487 According to the spec (see the link below), however, setuptools CANNOT 2023-06-19T23:26:56,487 consider this value unless `authors` is listed as `dynamic`. 2023-06-19T23:26:56,488 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-06-19T23:26:56,489 For the time being, `setuptools` will still consider the given value (as a 2023-06-19T23:26:56,489 **transitional** measure), but please note that future releases of setuptools will 2023-06-19T23:26:56,490 follow strictly the standard. 2023-06-19T23:26:56,491 To prevent this warning, you can list `authors` under `dynamic` or alternatively 2023-06-19T23:26:56,491 remove the `[project]` table from your file and rely entirely on other means of 2023-06-19T23:26:56,491 configuration. 2023-06-19T23:26:56,492 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-06-19T23:26:56,493 or your builds will no longer be supported. 2023-06-19T23:26:56,493 ******************************************************************************** 2023-06-19T23:26:56,494 !! 2023-06-19T23:26:56,494 _handle_missing_dynamic(dist, project_table) 2023-06-19T23:26:56,648 Preparing metadata (pyproject.toml): finished with status 'done' 2023-06-19T23:26:56,664 Source in /tmp/pip-wheel-00171i84/mbox2m365_fde1d90dc9194c9da47fdee43b8abbf2 has version 3.2.0, which satisfies requirement mbox2m365==3.2.0 from https://files.pythonhosted.org/packages/45/69/737b97ff918c42a5455925b30d09ef252a748326e6922bf78e381a52caea/mbox2m365-3.2.0.tar.gz 2023-06-19T23:26:56,666 Removed mbox2m365==3.2.0 from https://files.pythonhosted.org/packages/45/69/737b97ff918c42a5455925b30d09ef252a748326e6922bf78e381a52caea/mbox2m365-3.2.0.tar.gz from build tracker '/tmp/pip-build-tracker-b0blhhsh' 2023-06-19T23:26:56,677 Created temporary directory: /tmp/pip-unpack-xqeh_uw0 2023-06-19T23:26:56,678 Building wheels for collected packages: mbox2m365 2023-06-19T23:26:56,687 Created temporary directory: /tmp/pip-wheel-yua2ccx0 2023-06-19T23:26:56,687 Destination directory: /tmp/pip-wheel-yua2ccx0 2023-06-19T23:26:56,692 Building wheel for mbox2m365 (pyproject.toml): started 2023-06-19T23:26:56,694 Running command Building wheel for mbox2m365 (pyproject.toml) 2023-06-19T23:26:57,932 /tmp/pip-build-env-1cb8t47m/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `description` defined outside of `pyproject.toml` would be ignored. 2023-06-19T23:26:57,933 !! 2023-06-19T23:26:57,934 ******************************************************************************** 2023-06-19T23:26:57,934 ########################################################################## 2023-06-19T23:26:57,935 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-06-19T23:26:57,935 ########################################################################## 2023-06-19T23:26:57,936 The following seems to be defined outside of `pyproject.toml`: 2023-06-19T23:26:57,936 `description = "'Send a message stored within an mbox using m365 (Office365)'"` 2023-06-19T23:26:57,937 According to the spec (see the link below), however, setuptools CANNOT 2023-06-19T23:26:57,937 consider this value unless `description` is listed as `dynamic`. 2023-06-19T23:26:57,938 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-06-19T23:26:57,939 For the time being, `setuptools` will still consider the given value (as a 2023-06-19T23:26:57,939 **transitional** measure), but please note that future releases of setuptools will 2023-06-19T23:26:57,939 follow strictly the standard. 2023-06-19T23:26:57,940 To prevent this warning, you can list `description` under `dynamic` or alternatively 2023-06-19T23:26:57,940 remove the `[project]` table from your file and rely entirely on other means of 2023-06-19T23:26:57,940 configuration. 2023-06-19T23:26:57,941 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-06-19T23:26:57,941 or your builds will no longer be supported. 2023-06-19T23:26:57,942 ******************************************************************************** 2023-06-19T23:26:57,942 !! 2023-06-19T23:26:57,943 _handle_missing_dynamic(dist, project_table) 2023-06-19T23:26:57,943 /tmp/pip-build-env-1cb8t47m/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `readme` defined outside of `pyproject.toml` would be ignored. 2023-06-19T23:26:57,943 !! 2023-06-19T23:26:57,944 ******************************************************************************** 2023-06-19T23:26:57,944 ########################################################################## 2023-06-19T23:26:57,945 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-06-19T23:26:57,945 ########################################################################## 2023-06-19T23:26:57,946 The following seems to be defined outside of `pyproject.toml`: 2023-06-19T23:26:57,947 `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-06-19T23:26:57,948 According to the spec (see the link below), however, setuptools CANNOT 2023-06-19T23:26:57,949 consider this value unless `readme` is listed as `dynamic`. 2023-06-19T23:26:57,949 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-06-19T23:26:57,950 For the time being, `setuptools` will still consider the given value (as a 2023-06-19T23:26:57,950 **transitional** measure), but please note that future releases of setuptools will 2023-06-19T23:26:57,951 follow strictly the standard. 2023-06-19T23:26:57,951 To prevent this warning, you can list `readme` under `dynamic` or alternatively 2023-06-19T23:26:57,952 remove the `[project]` table from your file and rely entirely on other means of 2023-06-19T23:26:57,952 configuration. 2023-06-19T23:26:57,953 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-06-19T23:26:57,953 or your builds will no longer be supported. 2023-06-19T23:26:57,953 ******************************************************************************** 2023-06-19T23:26:57,954 !! 2023-06-19T23:26:57,954 _handle_missing_dynamic(dist, project_table) 2023-06-19T23:26:58,556 running bdist_wheel 2023-06-19T23:26:58,588 running build 2023-06-19T23:26:58,589 running build_py 2023-06-19T23:26:58,601 creating build 2023-06-19T23:26:58,602 creating build/lib 2023-06-19T23:26:58,603 creating build/lib/mbox2m365 2023-06-19T23:26:58,606 copying mbox2m365/mbox2m365.py -> build/lib/mbox2m365 2023-06-19T23:26:58,612 copying mbox2m365/__init__.py -> build/lib/mbox2m365 2023-06-19T23:26:58,616 copying mbox2m365/__main__.py -> build/lib/mbox2m365 2023-06-19T23:26:58,620 copying mbox2m365/mailSink.py -> build/lib/mbox2m365 2023-06-19T23:26:58,624 creating build/lib/jobber 2023-06-19T23:26:58,626 copying jobber/jobber.py -> build/lib/jobber 2023-06-19T23:26:58,631 running egg_info 2023-06-19T23:26:58,649 writing mbox2m365.egg-info/PKG-INFO 2023-06-19T23:26:58,653 writing dependency_links to mbox2m365.egg-info/dependency_links.txt 2023-06-19T23:26:58,657 writing entry points to mbox2m365.egg-info/entry_points.txt 2023-06-19T23:26:58,660 writing requirements to mbox2m365.egg-info/requires.txt 2023-06-19T23:26:58,662 writing top-level names to mbox2m365.egg-info/top_level.txt 2023-06-19T23:26:58,679 reading manifest file 'mbox2m365.egg-info/SOURCES.txt' 2023-06-19T23:26:58,683 reading manifest template 'MANIFEST.in' 2023-06-19T23:26:58,684 adding license file 'LICENSE' 2023-06-19T23:26:58,690 writing manifest file 'mbox2m365.egg-info/SOURCES.txt' 2023-06-19T23:26:58,713 installing to build/bdist.linux-armv7l/wheel 2023-06-19T23:26:58,713 running install 2023-06-19T23:26:58,774 running install_lib 2023-06-19T23:26:58,784 creating build/bdist.linux-armv7l 2023-06-19T23:26:58,785 creating build/bdist.linux-armv7l/wheel 2023-06-19T23:26:58,789 creating build/bdist.linux-armv7l/wheel/mbox2m365 2023-06-19T23:26:58,791 copying build/lib/mbox2m365/mbox2m365.py -> build/bdist.linux-armv7l/wheel/mbox2m365 2023-06-19T23:26:58,798 copying build/lib/mbox2m365/__init__.py -> build/bdist.linux-armv7l/wheel/mbox2m365 2023-06-19T23:26:58,802 copying build/lib/mbox2m365/__main__.py -> build/bdist.linux-armv7l/wheel/mbox2m365 2023-06-19T23:26:58,807 copying build/lib/mbox2m365/mailSink.py -> build/bdist.linux-armv7l/wheel/mbox2m365 2023-06-19T23:26:58,812 creating build/bdist.linux-armv7l/wheel/jobber 2023-06-19T23:26:58,814 copying build/lib/jobber/jobber.py -> build/bdist.linux-armv7l/wheel/jobber 2023-06-19T23:26:58,818 running install_egg_info 2023-06-19T23:26:58,828 Copying mbox2m365.egg-info to build/bdist.linux-armv7l/wheel/mbox2m365-3.2.0-py3.7.egg-info 2023-06-19T23:26:58,854 running install_scripts 2023-06-19T23:26:58,894 creating build/bdist.linux-armv7l/wheel/mbox2m365-3.2.0.dist-info/WHEEL 2023-06-19T23:26:58,899 creating '/tmp/pip-wheel-yua2ccx0/.tmp-t1trqnr9/mbox2m365-3.2.0-py3-none-any.whl' and adding 'build/bdist.linux-armv7l/wheel' to it 2023-06-19T23:26:58,905 adding 'jobber/jobber.py' 2023-06-19T23:26:58,909 adding 'mbox2m365/__init__.py' 2023-06-19T23:26:58,913 adding 'mbox2m365/__main__.py' 2023-06-19T23:26:58,916 adding 'mbox2m365/mailSink.py' 2023-06-19T23:26:58,925 adding 'mbox2m365/mbox2m365.py' 2023-06-19T23:26:58,931 adding 'mbox2m365-3.2.0.dist-info/LICENSE' 2023-06-19T23:26:58,936 adding 'mbox2m365-3.2.0.dist-info/METADATA' 2023-06-19T23:26:58,938 adding 'mbox2m365-3.2.0.dist-info/WHEEL' 2023-06-19T23:26:58,940 adding 'mbox2m365-3.2.0.dist-info/entry_points.txt' 2023-06-19T23:26:58,942 adding 'mbox2m365-3.2.0.dist-info/top_level.txt' 2023-06-19T23:26:58,944 adding 'mbox2m365-3.2.0.dist-info/RECORD' 2023-06-19T23:26:58,947 removing build/bdist.linux-armv7l/wheel 2023-06-19T23:26:58,960 /tmp/pip-build-env-1cb8t47m/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `license` defined outside of `pyproject.toml` would be ignored. 2023-06-19T23:26:58,961 !! 2023-06-19T23:26:58,962 ******************************************************************************** 2023-06-19T23:26:58,962 ########################################################################## 2023-06-19T23:26:58,963 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-06-19T23:26:58,963 ########################################################################## 2023-06-19T23:26:58,964 The following seems to be defined outside of `pyproject.toml`: 2023-06-19T23:26:58,965 `license = 'MIT'` 2023-06-19T23:26:58,966 According to the spec (see the link below), however, setuptools CANNOT 2023-06-19T23:26:58,967 consider this value unless `license` is listed as `dynamic`. 2023-06-19T23:26:58,968 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-06-19T23:26:58,969 For the time being, `setuptools` will still consider the given value (as a 2023-06-19T23:26:58,969 **transitional** measure), but please note that future releases of setuptools will 2023-06-19T23:26:58,970 follow strictly the standard. 2023-06-19T23:26:58,970 To prevent this warning, you can list `license` under `dynamic` or alternatively 2023-06-19T23:26:58,971 remove the `[project]` table from your file and rely entirely on other means of 2023-06-19T23:26:58,971 configuration. 2023-06-19T23:26:58,972 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-06-19T23:26:58,973 or your builds will no longer be supported. 2023-06-19T23:26:58,973 ******************************************************************************** 2023-06-19T23:26:58,974 !! 2023-06-19T23:26:58,975 _handle_missing_dynamic(dist, project_table) 2023-06-19T23:26:58,975 /tmp/pip-build-env-1cb8t47m/overlay/lib/python3.7/site-packages/setuptools/config/_apply_pyprojecttoml.py:62: _WouldIgnoreField: `authors` defined outside of `pyproject.toml` would be ignored. 2023-06-19T23:26:58,976 !! 2023-06-19T23:26:58,976 ******************************************************************************** 2023-06-19T23:26:58,977 ########################################################################## 2023-06-19T23:26:58,977 # configuration would be ignored/result in error due to `pyproject.toml` # 2023-06-19T23:26:58,978 ########################################################################## 2023-06-19T23:26:58,979 The following seems to be defined outside of `pyproject.toml`: 2023-06-19T23:26:58,979 `authors = 'Rudolph Pienaar'` 2023-06-19T23:26:58,980 According to the spec (see the link below), however, setuptools CANNOT 2023-06-19T23:26:58,981 consider this value unless `authors` is listed as `dynamic`. 2023-06-19T23:26:58,981 https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ 2023-06-19T23:26:58,982 For the time being, `setuptools` will still consider the given value (as a 2023-06-19T23:26:58,983 **transitional** measure), but please note that future releases of setuptools will 2023-06-19T23:26:58,983 follow strictly the standard. 2023-06-19T23:26:58,984 To prevent this warning, you can list `authors` under `dynamic` or alternatively 2023-06-19T23:26:58,984 remove the `[project]` table from your file and rely entirely on other means of 2023-06-19T23:26:58,985 configuration. 2023-06-19T23:26:58,985 By 2023-Oct-30, you need to update your project and remove deprecated calls 2023-06-19T23:26:58,986 or your builds will no longer be supported. 2023-06-19T23:26:58,986 ******************************************************************************** 2023-06-19T23:26:58,987 !! 2023-06-19T23:26:58,987 _handle_missing_dynamic(dist, project_table) 2023-06-19T23:26:59,140 Building wheel for mbox2m365 (pyproject.toml): finished with status 'done' 2023-06-19T23:26:59,154 Created wheel for mbox2m365: filename=mbox2m365-3.2.0-py3-none-any.whl size=20177 sha256=02fe06096835ddba745923b0bd1ad6eaff5c54fe01c2414c1e1d8b6d6fc87f9b 2023-06-19T23:26:59,156 Stored in directory: /tmp/pip-ephem-wheel-cache-yhzm78hd/wheels/2e/93/5c/78952bc6c1d30c49c6b1607a22148163effecf75133264d2d5 2023-06-19T23:26:59,185 Successfully built mbox2m365 2023-06-19T23:26:59,194 Removed build tracker: '/tmp/pip-build-tracker-b0blhhsh'