Package: calcurse-load
Hooks/scripts for loading data for calcurse. This integratescalcursewith Google Calendar, andtodo.txt.pre-load:Looks at the locally indexed Google Calendar JSON dump, adds events ascalcurseappointments; adds summary/HTML links as appointment notes.Replacecalcurses todos with my currenttodo.txt, converting priorities accordingly.post-saveIf any new todos are added, write those back to mytodo.txtfile.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 correspondingtodotxtstill exists. Only reason for me to load my todos intocalcurseis to remind me what they are, and to possibly add new ones. I haveother waysI mark todos as done.Other than the extensions provided here, you can also define completely custom behaviour by creating your own extensions, seeextension referenceAs a general warning, if theres any output from the hooks, calcurse fails to load, so you could do something like this in yourpre-loadscript:python3-mcalcurse_load--pre-loadgcal>>/tmp/calcurse_load.log2>&1Setupgitclonehttps://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 scriptscp./hooks/*~/.config/calcurse/hooks/
pipinstall.# install current directory with pipThis installs 2 python scripts/modules,gcal_index, andcalcurse_load.gcal_indexhas 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_DIRenvironment variable. That's not somethingcalcurserecognizes, but you could setup an alias:exportCALCURSE_DIR="$HOME/Documents/calcurse"aliascalcurse='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 forgcal_index.AboutIf you wanted to disable one of thetodotxtorgcalextensions, you could remove or rename the corresponding scripts in thehooksdirectory.gcal pre-loadThegcalcalcurse hook tries to read anygcal_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 fileRemoves any Google Calendar events (which are tagged with[gcal])Generates Google Calendar events from the JSONAdds the newly created events and writes back to the appointments file.gcal update examplegcal_indexsaves an index of Google Calendar events for a Google Account locally as a JSON file.To setup credentials, seehere.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 yourpre-loadhook as well, before the call topython3 -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>.jsonFor an example script one might put under cron, seeexample_update_google_caltodotxtThepre-load/post-savetodotxthook converts thecalcursetodos back totodotxttodos, and updates thetodotxtfile if any todos were added. Atodo.txtis 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.txtTodo.txt Priority ConversionTodo.txtCalcurse(A)1 - 3(B)4 - 6(C)7 - 9None0calcurse_load referencecalcurse_loadaccepts one, or multiple pre/post hooks, with an extension name. There are individualhooksfor for each extension (gcal/todotxt)You could instead just add the single line you want into yourpre-loadscript, like:python3 -m calcurse_load --pre-load todotxt --pre-load gcalUsage: 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 aExtensionbase class incalcurse_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.RelativeWith relative paths, the easiest way is to put the extension in amyextension.pyfile in your hooks directory:.
├──gcal.enabled
├──myextension.py
├──post-save
├──pre-load
└──todotxt.enabled1directory,5filesAs an example:importosfromcalcurse_load.ext.abstractimportExtensionclassNotifier(Extension):"""Sends a notification letting you know how many appointments were loaded"""defpre_load(self):appointments=self.config.calcurse_dir/"apts"withopen(appointments,"r")asf:lines=[lforlinf.readlines()ifl.strip()]os.system(f"notify-send 'Loaded{len(lines)}appointments'")defpost_save(self):# do nothingpassThen, for example, at the top of yourpre-load, just be sure to change the directory to the current one, and call your custom extension:#!/bin/shcd"$(dirname"$0")"||exit1python3-mcalcurse_load--pre-loadmyextension.NotifierAbsoluteIf you had a wrote your own package and likemy_custom_calcurseinstalled into your python environment, and
inside that file you have a class calledMyCustomExtension, you can
load that extension by passingmy_custom_calcurse.MyCustomExtensionto
the--pre-loador--post-saveoptions.As another example, to use it with the gcal extension, you could also provide the fully qualified path:python3-mcalcurse_load--pre-loadcalcurse_load.ext.gcal.gcal_ext