Source code for bugwarrior.config.data

import json
import os
from pathlib import Path
import subprocess
import typing

from lockfile.pidlockfile import PIDLockFile


def get_data_path(taskrc: str | Path) -> str:
    # We cannot use the taskw module here because it doesn't really support
    # the `_` subcommands properly (`rc:` can't be used for them).
    line_prefix = 'data.location='

    # Take a copy of the environment and add our taskrc to it.
    env = dict(os.environ)
    env['TASKRC'] = str(taskrc)

    tw_show = subprocess.Popen(('task', '_show'), stdout=subprocess.PIPE, env=env)
    data_location = subprocess.check_output(
        ('grep', '-e', '^' + line_prefix), stdin=tw_show.stdout
    )
    tw_show.wait()
    data_path = data_location[len(line_prefix) :].rstrip().decode('utf-8')

    if not data_path:
        raise OSError('Unable to determine the data location.')

    return os.path.normpath(os.path.expanduser(data_path))


[docs] class BugwarriorData: """Local data storage. This exposes taskwarrior's `data.location` configuration value, as well as an interface to the ``bugwarrior.data`` file which serves as an arbitrary key-value store. """ def __init__(self, data_path: str) -> None: self._datafile = os.path.join(data_path, 'bugwarrior.data') self._lockfile = os.path.join(data_path, 'bugwarrior-data.lockfile') #: Taskwarrior's ``data.location`` configuration value. If necessary, #: services can manage their own files here. self.path = data_path @classmethod def __get_pydantic_json_schema__( cls, core_schema: typing.Any, handler: typing.Any ) -> dict[str, str]: """Fix schema generation in pydantic v2.""" return {"type": "object", "description": "Local data storage"}
[docs] def get_data(self) -> dict[str, typing.Any]: """Return all data from the ``bugwarrior.data`` file.""" with open(self._datafile) as jsondata: return json.load(jsondata)
[docs] def get(self, key: str) -> typing.Any: """Return a value stored in the ``bugwarrior.data`` file.""" try: return self.get_data()[key] except OSError: # File does not exist. return None
[docs] def set(self, key: str, value: typing.Any) -> None: """Set a value in the ``bugwarrior.data`` file.""" with PIDLockFile(self._lockfile): try: data = self.get_data() except OSError: # File does not exist. with open(self._datafile, 'w') as jsondata: json.dump({key: value}, jsondata) else: with open(self._datafile, 'w') as jsondata: data[key] = value json.dump(data, jsondata) os.chmod(self._datafile, 0o600)