{"id":25627931,"url":"https://github.com/j6k4m8/epistolary","last_synced_at":"2025-04-14T14:10:37.648Z","repository":{"id":275859169,"uuid":"743241379","full_name":"j6k4m8/epistolary","owner":"j6k4m8","description":null,"archived":false,"fork":false,"pushed_at":"2025-02-04T23:35:54.000Z","size":145,"stargazers_count":58,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-05T00:25:10.698Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/j6k4m8.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-14T18:45:12.000Z","updated_at":"2025-02-04T23:35:55.000Z","dependencies_parsed_at":"2025-02-05T00:35:22.099Z","dependency_job_id":null,"html_url":"https://github.com/j6k4m8/epistolary","commit_stats":null,"previous_names":["j6k4m8/epistolary"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j6k4m8%2Fepistolary","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j6k4m8%2Fepistolary/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j6k4m8%2Fepistolary/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j6k4m8%2Fepistolary/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/j6k4m8","download_url":"https://codeload.github.com/j6k4m8/epistolary/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240214561,"owners_count":19766264,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-22T17:55:28.367Z","updated_at":"2025-02-22T17:55:28.847Z","avatar_url":"https://github.com/j6k4m8.png","language":"Python","funding_links":[],"categories":["Other"],"sub_categories":["Template Builders"],"readme":"\u003ch1 align=center\u003e\u003cimg width=\"315\" alt=\"image\" src=\"https://github.com/user-attachments/assets/a63afee8-a634-4a04-87d9-932f72b1dac9\"\u003e\u003c/h1\u003e\n\n\u003cp align=center\u003e\u003cimg alt=\"PyPI - Version\" src=\"https://img.shields.io/pypi/v/epistolary?style=for-the-badge\"\u003e\u0026nbsp; \u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/%F0%9F%92%8C-Epistolary-beige?style=for-the-badge\u0026label=Written%20by%20Hand\"\u003e\n\u003c/p\u003e\n\n![Epistolary user flow](docs/epistolary-user-flow@8x.png)\n\nI find writing emails to be one of the most tedious and unpleasant tasks of my day. But I find the act of handwriting to be one of the most pleasant! The reMarkable is an e-ink tablet with a very pleasant writing experience. This software allows you to respond to emails by writing on the reMarkable, and then sends an OCR'd version of your writing to the recipient.\n\n---\n\nSee [docs/Overview.md](docs/Overview.md) to see an example in action!\n\n---\n\nThis tool is designed to \"print\" emails to a PDF file (one thread per file), with a blank (ruled) page after each email.\nYou can write a reply to the email on the blank page, and Epistolary will convert your handwriting to text and send it as a reply to the email.\n\nYou can also write a new email by creating a file called `recipient@example.com:::My cool subject`, writing a letter, and then moving it to the `Outbox` folder.\n\nIt is designed to be used with the [ReMarkable](https://remarkable.com/) tablet, which is a great device for reading and annotating PDFs, but it should work with standalone PDFs, tablet devices, or scanned documents as well.\n\n## Architecture\n\nThe tool comprises three main components:\n\n-   `MailboxManager`: A class that manages the mailbox, and provides methods to get the next email to be printed, and to send a reply to an email.\n-   `DocumentManager`: A class that manages the PDF document library.\n-   `EpistolaryOrchestrator`: A class that manages the interaction between the `MailboxManager` and the `DocumentManager`, and provides OCR and main entry point functionality.\n\n## Installation\n\n### 0. Requirements\n\nIf you are using the tesseract OCR option, you must first install Tesseract for OCR. On MacOS, this can be done with `brew install tesseract`.\n\nIf you are using the OpenAI OCR option, you should configure your OpenAI API key globally, or you can pass it in a config to the TextExtractor directly.\n\nIf you are planning to use the reMarkable document management tools, you will also need to install [the `rmapi` tool](https://github.com/juruen/rmapi) and configure it with your reMarkable account.\n\n### 1. Install the package\n\nOptionally, install Python dependencies:\n\n```bash\nuv install\n```\n\n(If you do not do this explicitly, the package will install the dependencies automatically when you run the package.)\n\n### 2. Configure the package\n\nThis can be done in one of two ways: Manually, editing a config file; or by running the `init` wizard.\n\nWe STRONGLY recommend using the `init` wizard, as it will guide you through the process of setting up the config file.\n\n#### Option 1: Run the `init` wizard\n\n```bash\nuv run epistolary init\n```\n\nThis will guide you through the process of setting up the config file, passing in email credentials and the configurations for the document managers you'd like to use. You can also specify the location of a config file by passing the `--config`/`-c` flag:\n\n```bash\nuv run epistolary --config ~/.config/epistolary.json init\n```\n\n#### Option 2: Manually edit the config file\n\nCreate a `~/.config/epistolary.json` file. Here's an example of what it might look like:\n\n```jsonc\n{\n    \"email\": \"####\",\n    \"password\": \"####\",\n    \"imap\": {\n        \"host\": \"####\",\n        \"port\": 993\n    },\n    \"smtp\": {\n        \"host\": \"####\",\n        \"port\": 587\n    },\n\n    // Optional (defaults shown)\n\n    \"smtp_username\": null,\n    \"smtp_password\": null,\n\n    \"ignore_marketing_emails\": true,\n    \"document_manager\": \"epistolary.document_manager.remarkable_document_manager:RemarkableDocumentManager\",\n    \"text_extractor\": \"epistolary.text_extractor.openai_text_extractor:OpenAITextExtractor\"\n}\n```\n\n## Usage\n\nWe recommend doing this with the `epistolary` cli:\n\n```bash\n# Get new emails and \"print\" them to your device:\nuv run epistolary receive\n```\n\n```bash\n# Send the replies you've written:\nuv run epistolary send\n```\n\nAlternatively, here's an example of a Python script that does the same thing as the above commands:\n\n```python\nfrom epistolary.orchestrator import EpistolaryOrchestrator\nfrom epistolary.mailbox_manager import SMTPIMAPMailboxManager\nfrom epistolary.document_manager.remarkable_document_manager import RemarkableDocumentManager\nfrom epistolary.text_extractor.openai_text_extractor import OpenAITextExtractor\n\nEO = EpistolaryOrchestrator(\n    SMTPIMAPMailboxManager.from_file(),\n    RemarkableDocumentManager(),\n    text_extractor=OpenAITextExtractor(),\n    debug=True,\n)\n\n```\n\nTo receive emails:\n\n```python\nEO.refresh_document_mailbox()\n```\n\nAnd to send:\n\n```python\nEO.send_outbox()\n```\n\nNote that the `SMTPIMAPMailboxManager` uses the `epistolary.json` file to get the email and password, and the `RemarkableDocumentManager` uses the `rmapi` tool to manage the reMarkable documents (which depends upon a `~/.rmapi` file with your reMarkable credentials).\n\nIf you do not choose to use the `#from_file()` method, you can pass in the email, password, and other parameters directly to the `SMTPIMAPMailboxManager` constructor.\n\n## Known Limitations\n\n-   No support for inline images or attachments yet... But it should be easy to add!\n-   Spacing and formatting of the OCR'd text is not perfect, but it's usually good enough for a quick reply.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fj6k4m8%2Fepistolary","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fj6k4m8%2Fepistolary","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fj6k4m8%2Fepistolary/lists"}