calcurse-load


Namecalcurse-load JSON
Version 0.1.1 PyPI version JSON
download
home_pagehttps://github.com/seanbreckenridge/calcurse_load
SummarySources events for calcurse from Google Calendar and todo.txt
upload_time2023-10-13 05:05:29
maintainer
docs_urlNone
authorSean Breckenridge
requires_python>=3.8
licenseMIT
keywords calendar todo google
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            Hooks/scripts for loading data for calcurse. This integrates [`calcurse`](https://github.com/lfos/calcurse) with Google Calendar, and [`todo.txt`](http://todotxt.org/).

- pre-load:
  - Looks at the locally indexed Google Calendar JSON dump, adds events as `calcurse` appointments; adds summary/HTML links as appointment notes.
  - Replace `calcurse`s todos with my current [`todo.txt`](http://todotxt.org/), converting priorities accordingly.
- post-save
  - If any new todos are added, write those back to my `todo.txt` file.

This doesn't write back to Google Calendar, its only used to source events.

Should be mentioned that deleting a todo in calcurse does nothing, because the corresponding `todotxt` still exists. Only reason for me to load my todos into `calcurse` is to remind me what they are, and to possibly add new ones. I have [other ways](https://sean.fish/d/todo-prompt?dark) I mark todos as done.

Other than the extensions provided here, you can also define completely custom behaviour by creating your own extensions, see [extension reference](#calcurse_load-reference)

As a general warning, if theres any output from the hooks, calcurse fails to load, so you could do something like this in your `pre-load` script:

```python
python3 -m calcurse_load --pre-load gcal >>/tmp/calcurse_load.log 2>&1
```

## Setup

```bash
git clone https://github.com/seanbreckenridge/calcurse-load && cd ./calcurse-load
# copy over calcurse hooks
# assuming its not overwriting any hooks, else youd have to manually copy in parts of the scripts
cp ./hooks/* ~/.config/calcurse/hooks/
pip install .  # install current directory with pip
```

This installs 2 python scripts/modules, `gcal_index`, and `calcurse_load`.

`gcal_index` has nothing to do with calcurse inherently, it could be used on its own to export all your current data from Google Calendar.

The data for calcurse is typically kept in `$XDG_DATA_HOME/calcurse` (`$HOME/.local/share/calcurse`). If you want to override that for some reason, this allows you to set the `$CALCURSE_DIR` environment variable. That's not something `calcurse` recognizes, but you could setup an alias:

```bash
export CALCURSE_DIR="$HOME/Documents/calcurse"
alias calcurse='calcurse --datadir "$CALCURSE_DIR" --confdir ~/.config/calcurse "$@"'
```

In addition to that, this maintains a data directory in `$XDG_DATA_HOME/calcurse_load`, where it stores data for `gcal_index`.

## About

If you wanted to disable one of the `todotxt` or `gcal` extensions, you could remove or rename the corresponding scripts in the `hooks` directory.

## gcal pre-load

The `gcal` calcurse hook tries to read any `gcal_index`-created JSON files in the `$XDG_DATA_HOME/calcurse_load/gcal/` directory. If there's description/extra information for events from Google Calendar, this attaches corresponding notes to each calcurse event. Specifically, it:

- Loads the calcurse appointments file
- Removes any Google Calendar events (which are tagged with `[gcal]`)
- Generates Google Calendar events from the JSON
- Adds the newly created events and writes back to the appointments file.

### gcal update example

`gcal_index` saves an index of Google Calendar events for a Google Account locally as a JSON file.

To setup credentials, see [here](https://google-calendar-simple-api.readthedocs.io/en/latest/getting_started.html).

Put the downloaded credentials in `~/.credentials/`, and specify the location with the `--credential-file`. I'd recommend wrapping in a script, and then setting up a job to run in the background, to update the local JSON index of Google Calendar events.

Its possible to put the command to update the local JSON index in your `pre-load` hook as well, before the call to `python3 -m calcurse_load`, but that would cause some noticeable lag on calcurse start-up.

```
Usage: python -m gcal_index [OPTIONS]

  Export Google Calendar events

Options:
  --email TEXT            Google Email to export  [required]
  --credential-file TEXT  Google credential file  [required]
  --end-days INTEGER      Specify how many days into the future to get events
                          for (if we went forever, repeating events would be
                          there in 2050)  [default: 90]
  --calendar TEXT         Specify which calendar to export from  [default:
                          primary]
  --help                  Show this message and exit.
```

Prints the JSON dump to STDOUT; example:

`python3 -m gcal_index --email <your_email> --credential-file ~/.credentials/<credential>.json`

For an example script one might put under cron, see [`example_update_google_cal`](./example_update_google_cal)

## todotxt

The `pre-load`/`post-save` `todotxt` hook converts the `calcurse` todos back to `todotxt` todos, and updates the `todotxt` file if any todos were added. A `todo.txt` is searched for in one of the common locations:

- `$TODOTXT_FILE`
- `$TODO_DIR/todo.txt`
- `$XDG_CONFIG/todo/todo.txt`
- `~/.config/todo/todo.txt`
- `~/.todo/todo.txt`

### Todo.txt Priority Conversion

| Todo.txt | Calcurse |
| -------- | -------- |
| (A)      | 1 - 3    |
| (B)      | 4 - 6    |
| (C)      | 7 - 9    |
| None     | 0        |

## calcurse_load reference

`calcurse_load` accepts one, or multiple pre/post hooks, with an extension name. There are individual [`hooks`](./hooks) for for each extension (`gcal`/`todotxt`)

You could instead just add the single line you want into your `pre-load` script, like: `python3 -m calcurse_load --pre-load todotxt --pre-load gcal`

```
Usage: calcurse_load [OPTIONS]

  A CLI for loading data for calcurse

Options:
  --pre-load gcal|todotxt|custom.module.name.Extension
                                  Execute the preload action for the extension
  --post-save gcal|todotxt|custom.module.name.Extension
                                  Execute the postsave action for the
                                  extension
  --help                          Show this message and exit.
```

If you want to use this for other purposes; there is a `Extension` base class in `calcurse_load.ext.abstract`.

To load a custom extension, you can point this at the fully qualified path to an Extension (module name + class name). This works with both absolute and relative imports.

### Relative

With relative paths, the easiest way is to put the extension in a `myextension.py` file in your hooks directory:

```bash
.
├── gcal.enabled
├── myextension.py
├── post-save
├── pre-load
└── todotxt.enabled

1 directory, 5 files
```

As an example:

```python
import os
from calcurse_load.ext.abstract import Extension


class Notifier(Extension):
    """
    Sends a notification letting you know how many appointments were loaded
    """

    def pre_load(self):
        appointments = self.config.calcurse_dir / "apts"
        with open(appointments, "r") as f:
            lines = [l for l in f.readlines() if l.strip()]

        os.system(f"notify-send 'Loaded {len(lines)} appointments'")

    def post_save(self):
        # do nothing
        pass
```

Then, for example, at the top of your `pre-load`, just be sure to change the directory to the current one, and call your custom extension:

```bash
#!/bin/sh

cd "$(dirname "$0")" || exit 1

python3 -m calcurse_load --pre-load myextension.Notifier
```

### Absolute

If you had a wrote your own package and like `my_custom_calcurse` installed into your python environment, and
inside that file you have a class called `MyCustomExtension`, you can
load that extension by passing `my_custom_calcurse.MyCustomExtension` to
the `--pre-load` or `--post-save` options.

As another example, to use it with the gcal extension, you could also provide the fully qualified path:

```bash
python3 -m calcurse_load --pre-load calcurse_load.ext.gcal.gcal_ext
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/seanbreckenridge/calcurse_load",
    "name": "calcurse-load",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "calendar todo google",
    "author": "Sean Breckenridge",
    "author_email": "\"seanbrecke@gmail.com\"",
    "download_url": "https://files.pythonhosted.org/packages/47/47/8e32e2c46241a4c403f4e0115499a6a0304dabf30fb20b734bf6e89dd965/calcurse_load-0.1.1.tar.gz",
    "platform": null,
    "description": "Hooks/scripts for loading data for calcurse. This integrates [`calcurse`](https://github.com/lfos/calcurse) with Google Calendar, and [`todo.txt`](http://todotxt.org/).\n\n- pre-load:\n  - Looks at the locally indexed Google Calendar JSON dump, adds events as `calcurse` appointments; adds summary/HTML links as appointment notes.\n  - Replace `calcurse`s todos with my current [`todo.txt`](http://todotxt.org/), converting priorities accordingly.\n- post-save\n  - If any new todos are added, write those back to my `todo.txt` file.\n\nThis doesn't write back to Google Calendar, its only used to source events.\n\nShould be mentioned that deleting a todo in calcurse does nothing, because the corresponding `todotxt` still exists. Only reason for me to load my todos into `calcurse` is to remind me what they are, and to possibly add new ones. I have [other ways](https://sean.fish/d/todo-prompt?dark) I mark todos as done.\n\nOther than the extensions provided here, you can also define completely custom behaviour by creating your own extensions, see [extension reference](#calcurse_load-reference)\n\nAs a general warning, if theres any output from the hooks, calcurse fails to load, so you could do something like this in your `pre-load` script:\n\n```python\npython3 -m calcurse_load --pre-load gcal >>/tmp/calcurse_load.log 2>&1\n```\n\n## Setup\n\n```bash\ngit clone https://github.com/seanbreckenridge/calcurse-load && cd ./calcurse-load\n# copy over calcurse hooks\n# assuming its not overwriting any hooks, else youd have to manually copy in parts of the scripts\ncp ./hooks/* ~/.config/calcurse/hooks/\npip install .  # install current directory with pip\n```\n\nThis installs 2 python scripts/modules, `gcal_index`, and `calcurse_load`.\n\n`gcal_index` has nothing to do with calcurse inherently, it could be used on its own to export all your current data from Google Calendar.\n\nThe data for calcurse is typically kept in `$XDG_DATA_HOME/calcurse` (`$HOME/.local/share/calcurse`). If you want to override that for some reason, this allows you to set the `$CALCURSE_DIR` environment variable. That's not something `calcurse` recognizes, but you could setup an alias:\n\n```bash\nexport CALCURSE_DIR=\"$HOME/Documents/calcurse\"\nalias calcurse='calcurse --datadir \"$CALCURSE_DIR\" --confdir ~/.config/calcurse \"$@\"'\n```\n\nIn addition to that, this maintains a data directory in `$XDG_DATA_HOME/calcurse_load`, where it stores data for `gcal_index`.\n\n## About\n\nIf you wanted to disable one of the `todotxt` or `gcal` extensions, you could remove or rename the corresponding scripts in the `hooks` directory.\n\n## gcal pre-load\n\nThe `gcal` calcurse hook tries to read any `gcal_index`-created JSON files in the `$XDG_DATA_HOME/calcurse_load/gcal/` directory. If there's description/extra information for events from Google Calendar, this attaches corresponding notes to each calcurse event. Specifically, it:\n\n- Loads the calcurse appointments file\n- Removes any Google Calendar events (which are tagged with `[gcal]`)\n- Generates Google Calendar events from the JSON\n- Adds the newly created events and writes back to the appointments file.\n\n### gcal update example\n\n`gcal_index` saves an index of Google Calendar events for a Google Account locally as a JSON file.\n\nTo setup credentials, see [here](https://google-calendar-simple-api.readthedocs.io/en/latest/getting_started.html).\n\nPut the downloaded credentials in `~/.credentials/`, and specify the location with the `--credential-file`. I'd recommend wrapping in a script, and then setting up a job to run in the background, to update the local JSON index of Google Calendar events.\n\nIts possible to put the command to update the local JSON index in your `pre-load` hook as well, before the call to `python3 -m calcurse_load`, but that would cause some noticeable lag on calcurse start-up.\n\n```\nUsage: python -m gcal_index [OPTIONS]\n\n  Export Google Calendar events\n\nOptions:\n  --email TEXT            Google Email to export  [required]\n  --credential-file TEXT  Google credential file  [required]\n  --end-days INTEGER      Specify how many days into the future to get events\n                          for (if we went forever, repeating events would be\n                          there in 2050)  [default: 90]\n  --calendar TEXT         Specify which calendar to export from  [default:\n                          primary]\n  --help                  Show this message and exit.\n```\n\nPrints the JSON dump to STDOUT; example:\n\n`python3 -m gcal_index --email <your_email> --credential-file ~/.credentials/<credential>.json`\n\nFor an example script one might put under cron, see [`example_update_google_cal`](./example_update_google_cal)\n\n## todotxt\n\nThe `pre-load`/`post-save` `todotxt` hook converts the `calcurse` todos back to `todotxt` todos, and updates the `todotxt` file if any todos were added. A `todo.txt` is searched for in one of the common locations:\n\n- `$TODOTXT_FILE`\n- `$TODO_DIR/todo.txt`\n- `$XDG_CONFIG/todo/todo.txt`\n- `~/.config/todo/todo.txt`\n- `~/.todo/todo.txt`\n\n### Todo.txt Priority Conversion\n\n| Todo.txt | Calcurse |\n| -------- | -------- |\n| (A)      | 1 - 3    |\n| (B)      | 4 - 6    |\n| (C)      | 7 - 9    |\n| None     | 0        |\n\n## calcurse_load reference\n\n`calcurse_load` accepts one, or multiple pre/post hooks, with an extension name. There are individual [`hooks`](./hooks) for for each extension (`gcal`/`todotxt`)\n\nYou could instead just add the single line you want into your `pre-load` script, like: `python3 -m calcurse_load --pre-load todotxt --pre-load gcal`\n\n```\nUsage: calcurse_load [OPTIONS]\n\n  A CLI for loading data for calcurse\n\nOptions:\n  --pre-load gcal|todotxt|custom.module.name.Extension\n                                  Execute the preload action for the extension\n  --post-save gcal|todotxt|custom.module.name.Extension\n                                  Execute the postsave action for the\n                                  extension\n  --help                          Show this message and exit.\n```\n\nIf you want to use this for other purposes; there is a `Extension` base class in `calcurse_load.ext.abstract`.\n\nTo load a custom extension, you can point this at the fully qualified path to an Extension (module name + class name). This works with both absolute and relative imports.\n\n### Relative\n\nWith relative paths, the easiest way is to put the extension in a `myextension.py` file in your hooks directory:\n\n```bash\n.\n\u251c\u2500\u2500 gcal.enabled\n\u251c\u2500\u2500 myextension.py\n\u251c\u2500\u2500 post-save\n\u251c\u2500\u2500 pre-load\n\u2514\u2500\u2500 todotxt.enabled\n\n1 directory, 5 files\n```\n\nAs an example:\n\n```python\nimport os\nfrom calcurse_load.ext.abstract import Extension\n\n\nclass Notifier(Extension):\n    \"\"\"\n    Sends a notification letting you know how many appointments were loaded\n    \"\"\"\n\n    def pre_load(self):\n        appointments = self.config.calcurse_dir / \"apts\"\n        with open(appointments, \"r\") as f:\n            lines = [l for l in f.readlines() if l.strip()]\n\n        os.system(f\"notify-send 'Loaded {len(lines)} appointments'\")\n\n    def post_save(self):\n        # do nothing\n        pass\n```\n\nThen, for example, at the top of your `pre-load`, just be sure to change the directory to the current one, and call your custom extension:\n\n```bash\n#!/bin/sh\n\ncd \"$(dirname \"$0\")\" || exit 1\n\npython3 -m calcurse_load --pre-load myextension.Notifier\n```\n\n### Absolute\n\nIf you had a wrote your own package and like `my_custom_calcurse` installed into your python environment, and\ninside that file you have a class called `MyCustomExtension`, you can\nload that extension by passing `my_custom_calcurse.MyCustomExtension` to\nthe `--pre-load` or `--post-save` options.\n\nAs another example, to use it with the gcal extension, you could also provide the fully qualified path:\n\n```bash\npython3 -m calcurse_load --pre-load calcurse_load.ext.gcal.gcal_ext\n```\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Sources events for calcurse from Google Calendar and todo.txt",
    "version": "0.1.1",
    "project_urls": {
        "Homepage": "https://github.com/seanbreckenridge/calcurse_load"
    },
    "split_keywords": [
        "calendar",
        "todo",
        "google"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6822e6d0e9d9f020d67936ada9323939f16869bd3b95b7b91fd84f677d525e13",
                "md5": "f4834baf2702595ecb54c61166068a4b",
                "sha256": "24bb67652fb7d5c40cd3545eacbb5ed96f8ab22cc5f0a16e2f140ad81c6eb56d"
            },
            "downloads": -1,
            "filename": "calcurse_load-0.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f4834baf2702595ecb54c61166068a4b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 15018,
            "upload_time": "2023-10-13T05:05:27",
            "upload_time_iso_8601": "2023-10-13T05:05:27.717768Z",
            "url": "https://files.pythonhosted.org/packages/68/22/e6d0e9d9f020d67936ada9323939f16869bd3b95b7b91fd84f677d525e13/calcurse_load-0.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "47478e32e2c46241a4c403f4e0115499a6a0304dabf30fb20b734bf6e89dd965",
                "md5": "d80de365597c839bda373cf208508284",
                "sha256": "e863a2e194c65fd1ff62a626165fa5925667da91dfed494e7d4eaa60fea6fcd3"
            },
            "downloads": -1,
            "filename": "calcurse_load-0.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "d80de365597c839bda373cf208508284",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 15768,
            "upload_time": "2023-10-13T05:05:29",
            "upload_time_iso_8601": "2023-10-13T05:05:29.413346Z",
            "url": "https://files.pythonhosted.org/packages/47/47/8e32e2c46241a4c403f4e0115499a6a0304dabf30fb20b734bf6e89dd965/calcurse_load-0.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-13 05:05:29",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "seanbreckenridge",
    "github_project": "calcurse_load",
    "github_not_found": true,
    "lcname": "calcurse-load"
}
        
Elapsed time: 0.12351s