Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ publish := uv publish --username=__token__ --keyring-provider=subprocess
test := $(run) pytest
python := $(run) python
ruff := $(run) ruff
lint := $(ruff) check --select I
lint := $(ruff) check
fmt := $(ruff) format
mypy := $(run) mypy
spell := $(run) codespell
Expand Down
23 changes: 23 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,26 @@ asyncio_default_fixture_loop_scope = "function"
venvPath="."
venv=".venv"
exclude=[".venv"]

[tool.ruff.lint]
select = [
# pycodestyle
"E",
# Pyflakes
"F",
# pyupgrade
"UP",
# flake8-bugbear
"B",
# flake8-simplify
"SIM",
# isort
"I",
]
ignore = [
# I think try...expect...pass reads far better.
"SIM105",
]

[tool.ruff.lint.pycodestyle]
max-line-length = 120
2 changes: 1 addition & 1 deletion src/braindrop/app/braindrop.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def api_token(self) -> str | None:
return self.environmental_token() or token_file().read_text(
encoding="utf-8"
)
except IOError:
except OSError:
pass
return None

Expand Down
6 changes: 3 additions & 3 deletions src/braindrop/app/data/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

##############################################################################
# Python imports.
from collections.abc import Iterator
from contextlib import contextmanager
from dataclasses import asdict, dataclass, field
from functools import lru_cache
from functools import cache
from json import dumps, loads
from pathlib import Path
from typing import Iterator

##############################################################################
# Local imports.
Expand Down Expand Up @@ -63,7 +63,7 @@ def save_configuration(configuration: Configuration) -> Configuration:


##############################################################################
@lru_cache(maxsize=None)
@cache
def load_configuration() -> Configuration:
"""Load the configuration.

Expand Down
3 changes: 2 additions & 1 deletion src/braindrop/app/data/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

##############################################################################
# Python imports.
from collections.abc import Callable, Iterable, Iterator
from datetime import datetime
from json import dumps, loads
from pathlib import Path
from typing import Any, Callable, Final, Iterable, Iterator, Self
from typing import Any, Final, Self

##############################################################################
# pytz imports.
Expand Down
6 changes: 4 additions & 2 deletions src/braindrop/app/data/raindrops.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

##############################################################################
# Python imports.
from collections import Counter
from collections.abc import Callable, Iterable, Iterator
from dataclasses import dataclass
from functools import total_ordering
from typing import Callable, Counter, Iterable, Iterator, Self, TypeAlias
from typing import Self

##############################################################################
# Local imports.
Expand Down Expand Up @@ -81,7 +83,7 @@ def __eq__(self, value: object, /) -> bool:


##############################################################################
Filters: TypeAlias = tuple["Filter", ...]
type Filters = tuple["Filter", ...]
"""The type of a collection of filters."""


Expand Down
2 changes: 1 addition & 1 deletion src/braindrop/app/screens/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

##############################################################################
# Python imports.
from typing import Callable
from collections.abc import Callable
from webbrowser import open as open_url

##############################################################################
Expand Down
2 changes: 1 addition & 1 deletion src/braindrop/app/screens/raindrop_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

##############################################################################
# Python imports.
from typing import Iterator
from collections.abc import Iterator

##############################################################################
# httpx imports.
Expand Down
7 changes: 4 additions & 3 deletions src/braindrop/app/suggestions/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

##############################################################################
# Python imports.
import re
from typing import Final, Iterable, Pattern
from collections.abc import Iterable
from re import Pattern, compile
from typing import Final

##############################################################################
# Textual imports.
Expand Down Expand Up @@ -33,7 +34,7 @@ def __init__(self, tags: Iterable[Tag | TagCount], use_cache: bool = True) -> No
self._tags = [tag.tag if isinstance(tag, TagCount) else tag for tag in tags]
"""The tags to take suggestions from."""

_SUGGESTABLE: Final[Pattern[str]] = re.compile(r".*[^,\s]$")
_SUGGESTABLE: Final[Pattern[str]] = compile(r".*[^,\s]$")
"""Regular expression to test if a value deserves a suggestion."""

async def get_suggestion(self, value: str) -> str | None:
Expand Down
3 changes: 2 additions & 1 deletion src/braindrop/app/widgets/raindrop_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

##############################################################################
# Python imports.
from collections.abc import Callable
from datetime import datetime
from typing import Any, Callable, Final
from typing import Any, Final

##############################################################################
# Humanize imports.
Expand Down
7 changes: 5 additions & 2 deletions src/braindrop/app/widgets/raindrops_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,12 @@ def prompt(self) -> Group:
if self._raindrop.excerpt:
excerpt = Table.grid()
excerpt.add_column(ratio=1, no_wrap=self._compact)
excerpt.add_row(
f"[dim]{escape(self._raindrop.excerpt.splitlines()[0] if self._compact else self._raindrop.excerpt)}[/dim]"
content = escape(
self._raindrop.excerpt.splitlines()[0]
if self._compact
else self._raindrop.excerpt
)
excerpt.add_row(f"[dim]{content}[/dim]")
body.append(excerpt)

details = Table.grid(expand=True)
Expand Down
7 changes: 4 additions & 3 deletions src/braindrop/raindrop/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
##############################################################################
# Python imports.
from asyncio import sleep
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from http import HTTPStatus
from json import loads
from ssl import SSLCertVerificationError
from typing import Any, Awaitable, Callable, Final, Literal
from typing import Any, Final, Literal

##############################################################################
# HTTPX imports.
Expand Down Expand Up @@ -140,7 +141,7 @@ async def _call(
int(error.response.headers["Retry-After"])
if "Retry-After" in error.response.headers
else None
)
) from None
else:
raise self.RequestError(str(error)) from None

Expand Down Expand Up @@ -332,7 +333,7 @@ def gndn(_: int) -> None:
if limit.retry_after is None:
raise self.RequestError(
"Raindrop.io API limit exceeded with no option to retry"
)
) from None
count_update(-len(raindrops))
await sleep(limit.retry_after)
continue
Expand Down
7 changes: 3 additions & 4 deletions src/braindrop/raindrop/raindrop.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

##############################################################################
# Python imports.
from collections.abc import Iterable
from dataclasses import dataclass, field, replace
from datetime import datetime
from typing import Any, Final, Iterable, Literal, TypeAlias
from typing import Any, Final, Literal

##############################################################################
# Local imports.
Expand All @@ -17,9 +18,7 @@
from .time_tools import get_time, json_time

##############################################################################
RaindropType: TypeAlias = Literal[
"link", "article", "image", "video", "document", "audio"
]
type RaindropType = Literal["link", "article", "image", "video", "document", "audio"]
"""The type of a Raindrop."""


Expand Down