# LocalLeaf
This tool provides an easy way to synchronize Overleaf projects from and to your local computer. No paid account necessary.
## Features
- Sync your locally modified `.tex` (and other) files to your Overleaf projects
- Sync your remotely modified `.tex` (and other) files to computer
- Works with free Overleaf account
- No Git or Dropbox required
- Does not steal or store your login credentials (works with a persisted cookie, logging in is done on the original Overleaf website)
## How To Use
### Install
The package is available via [PyPI](https://pypi.org/project/localleaf/). Just run:
```
pip3 install localleaf
```
That's it! Depending on your local Python installation, you might need to use `pip` instead of `pip3`.
### Prerequisites
- Create your project on [Overleaf](https://www.overleaf.com/project), for example a project named `test`. localleaf is not able to create projects (yet).
- Create a folder, preferably with the same name as the project (`test`) on your computer.
- Execute the script from that folder (`test`).
- If you do not specify the project name, localleaf uses the current folder's name as the project name.
### Usage
#### Login
```
lleaf [--cookie-path -v/--verbose] login
```
Logging in will be handled by a mini web browser opening on your device (using Qt5). You can then enter your username and password securely on the official Overleaf website. You might get asked to solve a CAPTCHA in the process. Your credentials are sent to Overleaf over HTTPS.
It then stores your *cookie* (**not** your login credentials) in a hidden file called `.olauth` in your system configuration directory. It is possible to store the cookie elsewhere using the `--cookie-path` option. The cookie file will not be synced to or from Overleaf.
Keep the `.olauth` file save, as it can be used to log in into your account.
### Listing all projects
```
lleaf [--cookie-path -v/--verbose] list
```
Use `lleaf list` to conveniently list all projects in your account available for syncing.
### Downloading project's PDF
```
lleaf [--cookie-path -v/--verbose] download [-n/--name --download-path]
```
Use `lleaf download` to compile and download your project's PDF. Specify a download path if you do not want to store the PDF file in the current folder. Currently only downloads the first PDF file it finds. Using the `-n/--name` option allows you to specify a different Overleaf project name than the name of the folder you're calling `lleaf` from.
### Pulling and pushing changes
```
lleaf [--cookie-path -v/--verbose] pull [-n/--name -p/--path -i/--olignore]
```
```
lleaf [--cookie-path -v/--verbose] push [-n/--name -p/--path -i/--olignore]
```
Use `lleaf pull` to pull your Overleaf project files to your local project and `lleaf push` to push your local project files to your Overleaf project. When there are changes both locally, and remotely you will be asked which file to keep. If a file has been deleted on the source it can either be deleted on the target as well, restored on the source or ignored.
The `-n/--name` option allows you to specify a different Overleaf project name than the name of the folder you're calling `lleaf` from. The `-p/--path` option allows you to specify a different sync folder than the one you're calling `lleaf` from. The `-i/--olignore` option allows you to specify the path of an `.olignore` file. It uses `fnmatch` internally, so it may have some similarity to `.gitignore` but doesn't work exactly the same. For example, if you wish to exclude a specific folder named `out`, you need to specify it as `out/*`. See [here](https://docs.python.org/3/library/fnmatch.html) for more information.
## Known Bugs
- When modifying a file on Overleaf and immediately syncing afterwards, the tool might not detect the changes. Please allow 1-2 minutes after modifying a file on Overleaf before syncing it to your local computer.
## Contributing
All pull requests and change/feature requests are welcome.
## Disclaimer
THE AUTHOR OF THIS SOFTWARE AND THIS SOFTWARE IS NOT ENDORSED BY, DIRECTLY AFFILIATED WITH, MAINTAINED, AUTHORIZED, OR SPONSORED BY OVERLEAF OR WRITELATEX LIMITED. ALL PRODUCT AND COMPANY NAMES ARE THE REGISTERED TRADEMARKS OF THEIR ORIGINAL OWNERS. THE USE OF ANY TRADE NAME OR TRADEMARK IS FOR IDENTIFICATION AND REFERENCE PURPOSES ONLY AND DOES NOT IMPLY ANY ASSOCIATION WITH THE TRADEMARK HOLDER OF THEIR PRODUCT BRAND.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THIS SOFTWARE WAS DESIGNED TO BE USED ONLY FOR RESEARCH PURPOSES. THIS SOFTWARE COMES WITH NO WARRANTIES OF ANY KIND WHATSOEVER. USE IT AT YOUR OWN RISK! IF THESE TERMS ARE NOT ACCEPTABLE, YOU AREN'T ALLOWED TO USE THE CODE.
Raw data
{
"_id": null,
"home_page": null,
"name": "localleaf",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3",
"maintainer_email": "Jaziel Loureiro <jazielloureiro17@gmail.com>",
"keywords": "overleaf, local, sync, latex, tex",
"author": null,
"author_email": "Jaziel Loureiro <jazielloureiro17@gmail.com>, Moritz Gl\u00f6ckl <moritzgloeckl@users.noreply.github.com>",
"download_url": "https://files.pythonhosted.org/packages/83/79/6abeb3bf8d8b09d20063c6de53e80a247d0518a3fc7d25d6596450f70191/localleaf-1.1.1.tar.gz",
"platform": null,
"description": "# LocalLeaf\n\nThis tool provides an easy way to synchronize Overleaf projects from and to your local computer. No paid account necessary.\n\n## Features\n- Sync your locally modified `.tex` (and other) files to your Overleaf projects\n- Sync your remotely modified `.tex` (and other) files to computer\n- Works with free Overleaf account\n- No Git or Dropbox required\n- Does not steal or store your login credentials (works with a persisted cookie, logging in is done on the original Overleaf website)\n\n## How To Use\n### Install\nThe package is available via [PyPI](https://pypi.org/project/localleaf/). Just run:\n\n```\npip3 install localleaf\n```\n\nThat's it! Depending on your local Python installation, you might need to use `pip` instead of `pip3`.\n\n### Prerequisites\n- Create your project on [Overleaf](https://www.overleaf.com/project), for example a project named `test`. localleaf is not able to create projects (yet).\n- Create a folder, preferably with the same name as the project (`test`) on your computer.\n- Execute the script from that folder (`test`).\n- If you do not specify the project name, localleaf uses the current folder's name as the project name.\n\n### Usage\n#### Login\n```\nlleaf [--cookie-path -v/--verbose] login\n```\n\nLogging in will be handled by a mini web browser opening on your device (using Qt5). You can then enter your username and password securely on the official Overleaf website. You might get asked to solve a CAPTCHA in the process. Your credentials are sent to Overleaf over HTTPS.\n\nIt then stores your *cookie* (**not** your login credentials) in a hidden file called `.olauth` in your system configuration directory. It is possible to store the cookie elsewhere using the `--cookie-path` option. The cookie file will not be synced to or from Overleaf.\n\nKeep the `.olauth` file save, as it can be used to log in into your account.\n\n### Listing all projects\n```\nlleaf [--cookie-path -v/--verbose] list\n```\n\nUse `lleaf list` to conveniently list all projects in your account available for syncing. \n\n### Downloading project's PDF\n```\nlleaf [--cookie-path -v/--verbose] download [-n/--name --download-path]\n```\n\nUse `lleaf download` to compile and download your project's PDF. Specify a download path if you do not want to store the PDF file in the current folder. Currently only downloads the first PDF file it finds. Using the `-n/--name` option allows you to specify a different Overleaf project name than the name of the folder you're calling `lleaf` from.\n\n### Pulling and pushing changes\n```\nlleaf [--cookie-path -v/--verbose] pull [-n/--name -p/--path -i/--olignore]\n```\n\n```\nlleaf [--cookie-path -v/--verbose] push [-n/--name -p/--path -i/--olignore]\n```\n\nUse `lleaf pull` to pull your Overleaf project files to your local project and `lleaf push` to push your local project files to your Overleaf project. When there are changes both locally, and remotely you will be asked which file to keep. If a file has been deleted on the source it can either be deleted on the target as well, restored on the source or ignored.\n\nThe `-n/--name` option allows you to specify a different Overleaf project name than the name of the folder you're calling `lleaf` from. The `-p/--path` option allows you to specify a different sync folder than the one you're calling `lleaf` from. The `-i/--olignore` option allows you to specify the path of an `.olignore` file. It uses `fnmatch` internally, so it may have some similarity to `.gitignore` but doesn't work exactly the same. For example, if you wish to exclude a specific folder named `out`, you need to specify it as `out/*`. See [here](https://docs.python.org/3/library/fnmatch.html) for more information.\n\n## Known Bugs\n- When modifying a file on Overleaf and immediately syncing afterwards, the tool might not detect the changes. Please allow 1-2 minutes after modifying a file on Overleaf before syncing it to your local computer.\n\n## Contributing\n\nAll pull requests and change/feature requests are welcome.\n\n## Disclaimer\nTHE AUTHOR OF THIS SOFTWARE AND THIS SOFTWARE IS NOT ENDORSED BY, DIRECTLY AFFILIATED WITH, MAINTAINED, AUTHORIZED, OR SPONSORED BY OVERLEAF OR WRITELATEX LIMITED. ALL PRODUCT AND COMPANY NAMES ARE THE REGISTERED TRADEMARKS OF THEIR ORIGINAL OWNERS. THE USE OF ANY TRADE NAME OR TRADEMARK IS FOR IDENTIFICATION AND REFERENCE PURPOSES ONLY AND DOES NOT IMPLY ANY ASSOCIATION WITH THE TRADEMARK HOLDER OF THEIR PRODUCT BRAND.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nTHIS SOFTWARE WAS DESIGNED TO BE USED ONLY FOR RESEARCH PURPOSES. THIS SOFTWARE COMES WITH NO WARRANTIES OF ANY KIND WHATSOEVER. USE IT AT YOUR OWN RISK! IF THESE TERMS ARE NOT ACCEPTABLE, YOU AREN'T ALLOWED TO USE THE CODE.\n\n\n",
"bugtrack_url": null,
"license": null,
"summary": "Manage your Overleaf projects locally",
"version": "1.1.1",
"project_urls": {
"Source": "https://github.com/jazielloureiro/LocalLeaf"
},
"split_keywords": [
"overleaf",
" local",
" sync",
" latex",
" tex"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "bd48badd3e79b4213bf5ed4fd64a17b4031525a46a894f9ccd53612fd7b7919d",
"md5": "45433e93716af2048e81cbab89cefa9e",
"sha256": "c6b4cdf57003388e5156fdaa98c747af804b754a2b9f736e345957c8d153002e"
},
"downloads": -1,
"filename": "localleaf-1.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "45433e93716af2048e81cbab89cefa9e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3",
"size": 13328,
"upload_time": "2024-11-24T19:52:02",
"upload_time_iso_8601": "2024-11-24T19:52:02.153028Z",
"url": "https://files.pythonhosted.org/packages/bd/48/badd3e79b4213bf5ed4fd64a17b4031525a46a894f9ccd53612fd7b7919d/localleaf-1.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "83796abeb3bf8d8b09d20063c6de53e80a247d0518a3fc7d25d6596450f70191",
"md5": "843c6ca2bebda64decc2e4845ea5613d",
"sha256": "bc706573491c4fc40aed169c028b490829bd51cf1a9d0fa2c496cdc78b1c5504"
},
"downloads": -1,
"filename": "localleaf-1.1.1.tar.gz",
"has_sig": false,
"md5_digest": "843c6ca2bebda64decc2e4845ea5613d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3",
"size": 13850,
"upload_time": "2024-11-24T19:52:04",
"upload_time_iso_8601": "2024-11-24T19:52:04.216549Z",
"url": "https://files.pythonhosted.org/packages/83/79/6abeb3bf8d8b09d20063c6de53e80a247d0518a3fc7d25d6596450f70191/localleaf-1.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-24 19:52:04",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jazielloureiro",
"github_project": "LocalLeaf",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "beautifulsoup4",
"specs": [
[
"==",
"4.11.1"
]
]
},
{
"name": "certifi",
"specs": [
[
"==",
"2024.8.30"
]
]
},
{
"name": "charset-normalizer",
"specs": [
[
"==",
"3.4.0"
]
]
},
{
"name": "click",
"specs": [
[
"==",
"8.1.7"
]
]
},
{
"name": "idna",
"specs": [
[
"==",
"3.10"
]
]
},
{
"name": "platformdirs",
"specs": [
[
"==",
"4.3.6"
]
]
},
{
"name": "PySide6",
"specs": [
[
"==",
"6.8.0.2"
]
]
},
{
"name": "PySide6_Addons",
"specs": [
[
"==",
"6.8.0.2"
]
]
},
{
"name": "PySide6_Essentials",
"specs": [
[
"==",
"6.8.0.2"
]
]
},
{
"name": "python-dateutil",
"specs": [
[
"==",
"2.8.2"
]
]
},
{
"name": "requests",
"specs": [
[
"==",
"2.32.3"
]
]
},
{
"name": "shiboken6",
"specs": [
[
"==",
"6.8.0.2"
]
]
},
{
"name": "six",
"specs": [
[
"==",
"1.16.0"
]
]
},
{
"name": "socketIO-client",
"specs": [
[
"==",
"0.5.7.2"
]
]
},
{
"name": "soupsieve",
"specs": [
[
"==",
"2.6"
]
]
},
{
"name": "urllib3",
"specs": [
[
"==",
"2.2.3"
]
]
},
{
"name": "websocket-client",
"specs": [
[
"==",
"1.8.0"
]
]
}
],
"lcname": "localleaf"
}