Skip to content

Commit

Permalink
Add support for builtin profiles (WIP)
Browse files Browse the repository at this point in the history
TODO:
- complement the "minimal.conf" profile
- add more builtin profiles (e.g. a "narrow.conf", to limit the number
  of columns)?
- add a compat layer around importlib.resources API
- add tests
  • Loading branch information
dlax committed Feb 19, 2024
1 parent f7a86c3 commit 17f8b8a
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
`${XDG_CONFIG_HOME:~/.config}/pg_activity/<profile>.conf` or
`/etc/pg_activity/<profile>.conf` as selected from the command line through
`--profile <profile>`.
A few built-in profiles are distributed with pg\_activity.

### Changed

Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ files located at `${XDG_CONFIG_HOME:~/.config}/pg_activity/<my-profile>.conf` or
`--profile <my-profile>` command-line option. The format of these files is the
same as the main configuration file.

`pg_activity` ships with a few built-in profiles:

- `minimal`, providing a minimal user interface with most non-essential
information hidden

[INI format]: https://docs.python.org/3/library/configparser.html#supported-ini-file-structure

Expand Down
19 changes: 18 additions & 1 deletion pgactivity/compat.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import importlib.resources
import operator
import sys
from typing import Any, Dict
from typing import Any, Dict, Optional

import attr
import attr.validators
Expand All @@ -11,6 +12,22 @@
else:
from importlib.metadata import version

if sys.version_info >= (3, 11):

def read_resource(pkgname: str, dirname: str, *args: str) -> Optional[str]:
resource = importlib.resources.files(pkgname).joinpath(dirname)
for arg in args:
resource = resource.joinpath(arg)
if resource.is_file():
return resource.read_text()
return None

else:

def read_resource(pkgname: str, dirname: str, *args: str) -> Optional[str]:
raise NotImplementedError


ATTR_VERSION = tuple(int(x) for x in version("attrs").split(".", 2)[:2])
BLESSED_VERSION = tuple(int(x) for x in version("blessed").split(".", 2)[:2])

Expand Down
21 changes: 20 additions & 1 deletion pgactivity/config.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import configparser
import enum
import io
import os
from pathlib import Path
from typing import IO, Any, Dict, List, Optional, Type, TypeVar

import attr
from attr import validators

from .compat import gt
from .compat import gt, read_resource


class ConfigurationError(Exception):
Expand Down Expand Up @@ -188,6 +189,19 @@ def from_config_section(cls: Type[_T], section: configparser.SectionProxy) -> _T
return cls(**values)


@attr.s(auto_attribs=True, frozen=True, slots=True)
class BuiltinProfile:
name: str
content: IO[str]

@classmethod
def get(cls, name: str) -> Optional["BuiltinProfile"]:
content = read_resource("pgactivity", "profiles", f"{name}.conf")
if content is not None:
return BuiltinProfile(name, io.StringIO(content))
return None


USER_CONFIG_HOME = Path(os.environ.get("XDG_CONFIG_HOME", Path.home() / ".config"))
ETC = Path("/etc")

Expand Down Expand Up @@ -282,4 +296,9 @@ def lookup(
if fpath.exists():
with fpath.open() as f:
return cls.parse(f, str(fpath))

builtin_profile = BuiltinProfile.get(profile)
if builtin_profile is not None:
return cls.parse(builtin_profile.content, builtin_profile.name)

raise FileNotFoundError(f"profile {profile!r} not found")
2 changes: 2 additions & 0 deletions pgactivity/profiles/minimal.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[database]
hidden = yes

0 comments on commit 17f8b8a

Please sign in to comment.