<!-- Inspired by https://github.com/othneildrew/Best-README-Template/blob/master/BLANK_README.md -->
<a name="readme-top"></a>
<!-- SHIELDS HEADER -->
<div align="center">
[![Current Release][release-shield]][release-url] [![Contributors][contributors-shield]][contributors-url] [![Forks][forks-shield]][forks-url] [![Stargazers][stars-shield]][stars-url] [![Issues][issues-shield]][issues-url] [![MIT License][license-shield]][license-url] [![LinkedIn][linkedin-shield]][linkedin-url]
![PyPI - Python Version][pypi-python-shield]
![PyPi - Package Version][pypi-version-shield]
[![PyPi - License][pypi-license-shield]][license-url]
[release-shield]:https://img.shields.io/github/release/EJOOSTEROP/crewcal.svg
[release-url]:https://github.com/EJOOSTEROP/crewcal/releases
[contributors-shield]: https://img.shields.io/github/contributors/EJOOSTEROP/crewcal.svg?logo=github
[contributors-url]: https://github.com/EJOOSTEROP/crewcal/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/EJOOSTEROP/crewcal.svg?logo=github
[forks-url]: https://github.com/EJOOSTEROP/crewcal/network/members
[stars-shield]: https://img.shields.io/github/stars/EJOOSTEROP/crewcal.svg?logo=github
[stars-url]: https://github.com/EJOOSTEROP/crewcal/stargazers
[issues-shield]: https://img.shields.io/github/issues/EJOOSTEROP/crewcal.svg?logo=github
[issues-url]: https://github.com/EJOOSTEROP/crewcal/issues
[license-shield]: https://img.shields.io/github/license/EJOOSTEROP/crewcal.svg
[license-url]: https://github.com/EJOOSTEROP/crewcal/blob/main/LICENSE.txt
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?logo=linkedin&colorB=555
[linkedin-url]: https://linkedin.com/in/erik-oosterop-9505a21
[pypi-python-shield]: https://img.shields.io/pypi/pyversions/crewcal?logo=python
[pypi-version-shield]: https://img.shields.io/pypi/v/crewcal?logo=python
[pypi-license-shield]: https://img.shields.io/pypi/l/crewcal?logo=python
</div>
<!-- PROJECT SUMMARY AND LOGO -->
<div align="center">
<a href="https://github.com/EJOOSTEROP/crewcal">
<img src="https://github.com/EJOOSTEROP/crewcal/blob/main/etc/logo.png?raw=true" alt="Logo" width="180" height="180">
</a>
<h3 align="center">crewcal</h3>
<p align="center">
Convert an airline crew schedule pdf into iCalendar format using a Large Language Model.
<br />
<a href="https://github.com/EJOOSTEROP/crewcal"><strong>Explore the docs »</strong></a>
<br />
<br />
<!--
<a href="https://github.com/EJOOSTEROP/crewcal">View Demo</a>
·
-->
<a href="https://github.com/EJOOSTEROP/crewcal/issues">Report Bug</a>
·
<a href="https://github.com/EJOOSTEROP/crewcal/issues">Request Feature</a>
</p>
</div>
<!-- TABLE OF CONTENTS -->
<br />
<details>
<summary>Table of Contents</summary>
<ol>
<li>
<a href="#about-the-project">About the Project</a>
<!-- <ul>
<li><a href="#built-with">Built With</a></li>
</ul> -->
</li>
<li>
<a href="#getting-started">Getting Started</a>
<ul>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#installation">Installation</a></li>
</ul>
</li>
<li><a href="#usage">Usage</a></li>
<li><a href="#roadmap">Roadmap</a></li>
<li><a href="#contributing">Contributing</a></li>
<!-- <li><a href="#license">License</a></li> -->
<li><a href="#contact">Contact</a></li>
<!-- <li><a href="#acknowledgments">Acknowledgments</a></li> -->
</ol>
</details>
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- ABOUT THE PROJECT -->
## About the Project
<div align="center">
<a href="https://github.com/EJOOSTEROP/crewcal">
<img src="https://github.com/EJOOSTEROP/crewcal/blob/main/etc/intro_image.jpg?raw=true" alt="intro_image" width="75%" height="75%">
</a>
<br>
</div>
<div>
<br>
Convert an airline crew schedule pdf into iCalendar format using a Large Language Model. OpenAI's gpt-4o-mini is used to extract the schedule information. iCalender files are recognized by most calendar systems (iOS, Android, Google, ++) and will create the flights on your phone/device calendar.
The PDF schedule does not need to follow a very prescribed structured format.
Development performed mostly using AIMS eCrew <a href="https://github.com/EJOOSTEROP/crewcal/blob/main/etc/schedule_sample.png?raw=true">pdf schedules</a>. It may work on other systems' schedules. Feel free to <a href="#roadmap">suggest</a> other systems.
</div>
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- BUILT WITH -->
<!--
### Built With
<p align="right">(<a href="#readme-top">back to top</a>)</p>
-->
<!-- GETTING STARTED -->
## Getting Started
<!--To get a local copy up and running follow these simple example steps.
-->
### Prerequisites
Obtain an OpenAI API key.
Make this available as an environment variable:
```shell
export OPENAI_API_KEY=YOUR_KEY
```
Alternatively specify the API key in a .env file.
<p align="right">(<a href="#readme-top">back to top</a>)</p>
### Installation
Strongly consider using pipx or a virtual environment depending on your needs.
```shell
pip install crewcal
```
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- USAGE EXAMPLES -->
## Usage
### CLI
To create the calendar file (schedule.ics) from a pdf schedule file (schedule.pdf):
```shell
crewcal extract schedule.pdf schedule.ics
```
`crewcal --help` shows a brief manual page.
### Python Package
The following sript extracts the schedule from `schedule.pdf` and stores the icalendar file in `schedule.ics` file.
```python
from crewcal.llm_extract import OpenAISchedule
sched = OpenAISchedule(schedule_path='schedule.pdf', to_icalendar_file='schedule.ics')
```
The resulting .ics file can be read by most calendar software.
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- ROADMAP -->
## Roadmap
- [ ] Add support for schedules from systems in addition to AIMS. I would be happy to look at suggestions, especially if you can provide sample schedules. Create a new <a href="https://github.com/EJOOSTEROP/crewcal/issues">issue</a> to initiate a new request.
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- CONTRIBUTING -->
## Contributing
<!-- Contributions are what make the open source community such an amazing place to learn, inspire, and create. -->
Any contributions you make are **greatly appreciated**.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also [open](https://github.com/EJOOSTEROP/crewcal/issues/new/choose) a feature request or bug report.
Don't forget to give the project a star! Thanks again!
1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- LICENSE -->
<!--
## License
Distributed under the MIT License. See `LICENSE.txt` for more information. The tools and the sample data are subject to their own respective licenses.
<p align="right">(<a href="#readme-top">back to top</a>)</p>
-->
<!-- CONTACT -->
## Contact
<!--
Your Name - [@twitter_handle](https://twitter.com/twitter_handle) - email@email_client.com
-->
Project Link: [crewcal](https://github.com/EJOOSTEROP/crewcal)
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- ACKNOWLEDGMENTS -->
<!--
## Acknowledgments
* []()
* []()
* []()
<p align="right">(<a href="#readme-top">back to top</a>)</p>
-->
<!-- MARKDOWN LINKS & IMAGES -->
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
Raw data
{
"_id": null,
"home_page": "https://github.com/EJOOSTEROP/crewcal",
"name": "crewcal",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.11",
"maintainer_email": null,
"keywords": "x, y, z",
"author": "Erik Oosterop",
"author_email": "ni7h4txi@duck.com",
"download_url": "https://files.pythonhosted.org/packages/32/f3/a5e5c488d8ec548526291f2857550d245bf519edc869524ccd2b206c2986/crewcal-0.9.0.tar.gz",
"platform": null,
"description": "<!-- Inspired by https://github.com/othneildrew/Best-README-Template/blob/master/BLANK_README.md -->\n\n<a name=\"readme-top\"></a>\n\n<!-- SHIELDS HEADER -->\n<div align=\"center\">\n\n[![Current Release][release-shield]][release-url] [![Contributors][contributors-shield]][contributors-url] [![Forks][forks-shield]][forks-url] [![Stargazers][stars-shield]][stars-url] [![Issues][issues-shield]][issues-url] [![MIT License][license-shield]][license-url] [![LinkedIn][linkedin-shield]][linkedin-url]\n\n![PyPI - Python Version][pypi-python-shield]\n![PyPi - Package Version][pypi-version-shield]\n\n[![PyPi - License][pypi-license-shield]][license-url]\n\n[release-shield]:https://img.shields.io/github/release/EJOOSTEROP/crewcal.svg\n[release-url]:https://github.com/EJOOSTEROP/crewcal/releases\n\n[contributors-shield]: https://img.shields.io/github/contributors/EJOOSTEROP/crewcal.svg?logo=github\n[contributors-url]: https://github.com/EJOOSTEROP/crewcal/graphs/contributors\n\n[forks-shield]: https://img.shields.io/github/forks/EJOOSTEROP/crewcal.svg?logo=github\n[forks-url]: https://github.com/EJOOSTEROP/crewcal/network/members\n\n[stars-shield]: https://img.shields.io/github/stars/EJOOSTEROP/crewcal.svg?logo=github\n[stars-url]: https://github.com/EJOOSTEROP/crewcal/stargazers\n\n[issues-shield]: https://img.shields.io/github/issues/EJOOSTEROP/crewcal.svg?logo=github\n[issues-url]: https://github.com/EJOOSTEROP/crewcal/issues\n\n[license-shield]: https://img.shields.io/github/license/EJOOSTEROP/crewcal.svg\n[license-url]: https://github.com/EJOOSTEROP/crewcal/blob/main/LICENSE.txt\n\n[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?logo=linkedin&colorB=555\n[linkedin-url]: https://linkedin.com/in/erik-oosterop-9505a21\n\n[pypi-python-shield]: https://img.shields.io/pypi/pyversions/crewcal?logo=python\n[pypi-version-shield]: https://img.shields.io/pypi/v/crewcal?logo=python\n[pypi-license-shield]: https://img.shields.io/pypi/l/crewcal?logo=python\n</div>\n\n\n<!-- PROJECT SUMMARY AND LOGO -->\n<div align=\"center\">\n <a href=\"https://github.com/EJOOSTEROP/crewcal\">\n <img src=\"https://github.com/EJOOSTEROP/crewcal/blob/main/etc/logo.png?raw=true\" alt=\"Logo\" width=\"180\" height=\"180\">\n </a>\n\n<h3 align=\"center\">crewcal</h3>\n\n <p align=\"center\">\n Convert an airline crew schedule pdf into iCalendar format using a Large Language Model.\n <br />\n <a href=\"https://github.com/EJOOSTEROP/crewcal\"><strong>Explore the docs \u00bb</strong></a>\n <br />\n <br />\n <!--\n <a href=\"https://github.com/EJOOSTEROP/crewcal\">View Demo</a>\n \u00b7\n -->\n <a href=\"https://github.com/EJOOSTEROP/crewcal/issues\">Report Bug</a>\n \u00b7\n <a href=\"https://github.com/EJOOSTEROP/crewcal/issues\">Request Feature</a>\n </p>\n</div>\n\n\n<!-- TABLE OF CONTENTS -->\n<br />\n<details>\n <summary>Table of Contents</summary>\n <ol>\n <li>\n <a href=\"#about-the-project\">About the Project</a>\n <!-- <ul>\n <li><a href=\"#built-with\">Built With</a></li>\n </ul> -->\n </li>\n <li>\n <a href=\"#getting-started\">Getting Started</a>\n <ul>\n <li><a href=\"#prerequisites\">Prerequisites</a></li>\n <li><a href=\"#installation\">Installation</a></li>\n </ul>\n </li>\n <li><a href=\"#usage\">Usage</a></li>\n <li><a href=\"#roadmap\">Roadmap</a></li>\n <li><a href=\"#contributing\">Contributing</a></li>\n <!-- <li><a href=\"#license\">License</a></li> -->\n <li><a href=\"#contact\">Contact</a></li>\n <!-- <li><a href=\"#acknowledgments\">Acknowledgments</a></li> -->\n </ol>\n</details>\n\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n\n\n<!-- ABOUT THE PROJECT -->\n## About the Project\n\n<div align=\"center\">\n <a href=\"https://github.com/EJOOSTEROP/crewcal\">\n <img src=\"https://github.com/EJOOSTEROP/crewcal/blob/main/etc/intro_image.jpg?raw=true\" alt=\"intro_image\" width=\"75%\" height=\"75%\">\n </a>\n <br>\n</div>\n\n<div>\n <br>\n Convert an airline crew schedule pdf into iCalendar format using a Large Language Model. OpenAI's gpt-4o-mini is used to extract the schedule information. iCalender files are recognized by most calendar systems (iOS, Android, Google, ++) and will create the flights on your phone/device calendar.\n\n The PDF schedule does not need to follow a very prescribed structured format.\n\n Development performed mostly using AIMS eCrew <a href=\"https://github.com/EJOOSTEROP/crewcal/blob/main/etc/schedule_sample.png?raw=true\">pdf schedules</a>. It may work on other systems' schedules. Feel free to <a href=\"#roadmap\">suggest</a> other systems.\n\n</div>\n\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n\n\n<!-- BUILT WITH -->\n<!--\n### Built With\n\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n-->\n\n\n<!-- GETTING STARTED -->\n## Getting Started\n\n<!--To get a local copy up and running follow these simple example steps.\n-->\n\n### Prerequisites\n\nObtain an OpenAI API key.\n\nMake this available as an environment variable:\n```shell\nexport OPENAI_API_KEY=YOUR_KEY\n```\nAlternatively specify the API key in a .env file.\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n\n### Installation\nStrongly consider using pipx or a virtual environment depending on your needs.\n```shell\npip install crewcal\n```\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n\n\n<!-- USAGE EXAMPLES -->\n## Usage\n### CLI\nTo create the calendar file (schedule.ics) from a pdf schedule file (schedule.pdf):\n```shell\ncrewcal extract schedule.pdf schedule.ics\n```\n\n`crewcal --help` shows a brief manual page.\n\n\n### Python Package\nThe following sript extracts the schedule from `schedule.pdf` and stores the icalendar file in `schedule.ics` file.\n\n```python\nfrom crewcal.llm_extract import OpenAISchedule\n\nsched = OpenAISchedule(schedule_path='schedule.pdf', to_icalendar_file='schedule.ics')\n```\n\nThe resulting .ics file can be read by most calendar software.\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n\n\n<!-- ROADMAP -->\n## Roadmap\n\n- [ ] Add support for schedules from systems in addition to AIMS. I would be happy to look at suggestions, especially if you can provide sample schedules. Create a new <a href=\"https://github.com/EJOOSTEROP/crewcal/issues\">issue</a> to initiate a new request.\n\n\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n\n\n<!-- CONTRIBUTING -->\n## Contributing\n\n<!-- Contributions are what make the open source community such an amazing place to learn, inspire, and create. -->\nAny contributions you make are **greatly appreciated**.\n\nIf you have a suggestion that would make this better, please fork the repo and create a pull request. You can also [open](https://github.com/EJOOSTEROP/crewcal/issues/new/choose) a feature request or bug report.\nDon't forget to give the project a star! Thanks again!\n\n1. Fork the Project\n2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the Branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n\n\n<!-- LICENSE -->\n<!--\n## License\n\nDistributed under the MIT License. See `LICENSE.txt` for more information. The tools and the sample data are subject to their own respective licenses.\n\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n-->\n\n\n<!-- CONTACT -->\n## Contact\n\n<!--\nYour Name - [@twitter_handle](https://twitter.com/twitter_handle) - email@email_client.com\n-->\n\nProject Link: [crewcal](https://github.com/EJOOSTEROP/crewcal)\n\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n\n\n<!-- ACKNOWLEDGMENTS -->\n<!--\n## Acknowledgments\n\n* []()\n* []()\n* []()\n\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n\n-->\n\n<!-- MARKDOWN LINKS & IMAGES -->\n<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Convert an airline crew schedule pdf into iCalendar format.",
"version": "0.9.0",
"project_urls": {
"Documentation": "https://github.com/EJOOSTEROP/crewcal",
"Homepage": "https://github.com/EJOOSTEROP/crewcal",
"Repository": "https://github.com/EJOOSTEROP/crewcal"
},
"split_keywords": [
"x",
" y",
" z"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "8193ce05b97fc8d90b822f541968289c93cba4710a4462a06e6b14dfb23025bb",
"md5": "326afbc2b9eb788602c10588c96253f7",
"sha256": "2f59c928ec256aac28b0ccb800a8bf2d34390a292bbc289041e35b511c892354"
},
"downloads": -1,
"filename": "crewcal-0.9.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "326afbc2b9eb788602c10588c96253f7",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.11",
"size": 13284,
"upload_time": "2024-07-20T01:14:59",
"upload_time_iso_8601": "2024-07-20T01:14:59.316142Z",
"url": "https://files.pythonhosted.org/packages/81/93/ce05b97fc8d90b822f541968289c93cba4710a4462a06e6b14dfb23025bb/crewcal-0.9.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "32f3a5e5c488d8ec548526291f2857550d245bf519edc869524ccd2b206c2986",
"md5": "5d72ab5151dc249a569d6e7c9ac7461d",
"sha256": "9b41c3ab416a3428f860b6afe8d59f537f77ca11f65c73f160909d8e67ba4ef4"
},
"downloads": -1,
"filename": "crewcal-0.9.0.tar.gz",
"has_sig": false,
"md5_digest": "5d72ab5151dc249a569d6e7c9ac7461d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.11",
"size": 14673,
"upload_time": "2024-07-20T01:15:00",
"upload_time_iso_8601": "2024-07-20T01:15:00.615464Z",
"url": "https://files.pythonhosted.org/packages/32/f3/a5e5c488d8ec548526291f2857550d245bf519edc869524ccd2b206c2986/crewcal-0.9.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-07-20 01:15:00",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "EJOOSTEROP",
"github_project": "crewcal",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "crewcal"
}