Skip to content

Commit fa65929

Browse files
authored
Implement check for updates feature (#558)
* Implement check for updates * Fix tests * Bump version
1 parent 8bc87a4 commit fa65929

9 files changed

Lines changed: 52 additions & 20 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "streamrip"
3-
version = "2.0.2"
3+
version = "2.0.3"
44
description = "A fast, all-in-one music ripper for Qobuz, Deezer, Tidal, and SoundCloud"
55
authors = ["nathom <nathanthomas707@gmail.com>"]
66
license = "GPL-3.0-only"

streamrip/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
from .config import Config
33

44
__all__ = ["Config", "media", "metadata", "converter", "db", "exceptions"]
5-
__version__ = "2.0.2"
5+
__version__ = "2.0.3"

streamrip/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
APP_DIR = click.get_app_dir("streamrip")
1616
os.makedirs(APP_DIR, exist_ok=True)
1717
DEFAULT_CONFIG_PATH = os.path.join(APP_DIR, "config.toml")
18-
CURRENT_CONFIG_VERSION = "2.0"
18+
CURRENT_CONFIG_VERSION = "2.0.3"
1919

2020

2121
@dataclass(slots=True)
@@ -214,6 +214,7 @@ class CliConfig:
214214
@dataclass(slots=True)
215215
class MiscConfig:
216216
version: str
217+
check_for_updates: bool
217218

218219

219220
HOME = Path.home()

streamrip/config.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,6 @@ max_search_results = 100
186186

187187
[misc]
188188
# Metadata to identify this config file. Do not change.
189-
version = "2.0"
189+
version = "2.0.3"
190+
# Print a message if a new version of streamrip is available
191+
check_for_updates = true

streamrip/rip/cli.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
from typing import Any
99

1010
import aiofiles
11+
import aiohttp
1112
import click
1213
from click_help_colors import HelpColorsGroup # type: ignore
1314
from rich.logging import RichHandler
15+
from rich.markdown import Markdown
1416
from rich.prompt import Confirm
1517
from rich.traceback import install
1618

17-
from .. import db
19+
from .. import __version__, db
1820
from ..config import DEFAULT_CONFIG_PATH, Config, set_user_defaults
1921
from ..console import console
2022
from .main import Main
@@ -33,7 +35,7 @@ def wrapper(*args, **kwargs):
3335
help_headers_color="yellow",
3436
help_options_color="green",
3537
)
36-
@click.version_option(version="2.0.2")
38+
@click.version_option(version=__version__)
3739
@click.option(
3840
"--config-path",
3941
default=DEFAULT_CONFIG_PATH,
@@ -152,11 +154,30 @@ def rip(ctx, config_path, folder, no_db, quality, codec, no_progress, verbose):
152154
async def url(ctx, urls):
153155
"""Download content from URLs."""
154156
with ctx.obj["config"] as cfg:
157+
cfg: Config
158+
updates = cfg.session.misc.check_for_updates
159+
if updates:
160+
# Run in background
161+
version_coro = asyncio.create_task(latest_streamrip_version())
162+
else:
163+
version_coro = None
164+
155165
async with Main(cfg) as main:
156166
await main.add_all(urls)
157167
await main.resolve()
158168
await main.rip()
159169

170+
if version_coro is not None:
171+
latest_version, notes = await version_coro
172+
if latest_version != __version__:
173+
console.print(
174+
f"\n[green]A new version of streamrip [cyan]v{latest_version}[/cyan]"
175+
" is available! Run [white][bold]pip3 install streamrip --upgrade[/bold][/white]"
176+
" to update.[/green]\n"
177+
)
178+
179+
console.print(Markdown(notes))
180+
160181

161182
@rip.command()
162183
@click.argument(
@@ -390,5 +411,22 @@ async def id(ctx, source, media_type, id):
390411
await main.rip()
391412

392413

414+
async def latest_streamrip_version() -> tuple[str, str | None]:
415+
async with aiohttp.ClientSession() as s:
416+
async with s.get("https://pypi.org/pypi/streamrip/json") as resp:
417+
data = await resp.json()
418+
version = data["info"]["version"]
419+
420+
if version == __version__:
421+
return version, None
422+
423+
async with s.get(
424+
"https://api.github.com/repos/nathom/streamrip/releases/latest"
425+
) as resp:
426+
json = await resp.json()
427+
notes = json["body"]
428+
return version, notes
429+
430+
393431
if __name__ == "__main__":
394432
rip()

tests/silence.flac

9.92 KB
Binary file not shown.

tests/test_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def test_sample_config_data_fields(sample_config_data):
127127
bit_depth=24,
128128
lossy_bitrate=320,
129129
),
130-
misc=MiscConfig(version="2.0"),
130+
misc=MiscConfig(version="2.0", check_for_updates=True),
131131
_modified=False,
132132
)
133133
assert sample_config_data.downloads == test_config.downloads

tests/test_config.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,5 @@ max_search_results = 100
185185

186186
[misc]
187187
# Metadata to identify this config file. Do not change.
188-
version = "2.0"
188+
version = "2.0.3"
189+
check_for_updates = true

tests/test_versions.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,9 @@ def config_version() -> str | None:
2424
return m.group(1)
2525

2626

27-
@pytest.fixture
28-
def click_version() -> str | None:
29-
r = re.compile(r'\@click\.version_option\(version="([\d\.]+)"\)')
30-
with open("streamrip/rip/cli.py") as f:
31-
m = r.search(f.read())
32-
assert m is not None
33-
return m.group(1)
34-
35-
3627
def test_config_versions_match(config_version):
3728
assert config_version == CURRENT_CONFIG_VERSION
3829

3930

40-
def test_streamrip_versions_match(pyproject_version, click_version):
41-
assert pyproject_version == click_version
42-
assert click_version == init_version
31+
def test_streamrip_versions_match(pyproject_version):
32+
assert pyproject_version == init_version

0 commit comments

Comments
 (0)