lazy-github 0.2.4__tar.gz → 0.2.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lazy_github-0.2.4 → lazy_github-0.2.6}/PKG-INFO +3 -3
- lazy_github-0.2.6/lazy_github/lib/github_cli.py +57 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/screens/notifications.py +3 -5
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/screens/primary.py +1 -1
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github.egg-info/PKG-INFO +3 -3
- {lazy_github-0.2.4 → lazy_github-0.2.6}/pyproject.toml +3 -3
- lazy_github-0.2.4/lazy_github/lib/github_cli.py +0 -44
- {lazy_github-0.2.4 → lazy_github-0.2.6}/LICENSE +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/README.md +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/__main__.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/cli.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/bindings.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/config.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/constants.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/context.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/git_cli.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/github/auth.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/github/branches.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/github/client.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/github/issues.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/github/pull_requests.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/github/repositories.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/github/workflows.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/logging.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/messages.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/lib/utils.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/models/github.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/app.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/screens/auth.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/screens/edit_issue.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/screens/new_comment.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/screens/new_issue.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/screens/new_pull_request.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/screens/settings.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/screens/trigger_workflow.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/widgets/command_log.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/widgets/common.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/widgets/conversations.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/widgets/info.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/widgets/issues.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/widgets/pull_requests.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/widgets/repositories.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/ui/widgets/workflows.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github/version.py +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github.egg-info/SOURCES.txt +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github.egg-info/dependency_links.txt +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github.egg-info/entry_points.txt +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github.egg-info/requires.txt +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/lazy_github.egg-info/top_level.txt +0 -0
- {lazy_github-0.2.4 → lazy_github-0.2.6}/setup.cfg +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lazy-github
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: A terminal UI for interacting with Github
|
|
5
|
-
Author-email: Chris
|
|
6
|
-
Maintainer-email: Chris
|
|
5
|
+
Author-email: "Chris (Gizmo)" <gizmo385@users.noreply.github.com>
|
|
6
|
+
Maintainer-email: "Chris (Gizmo)" <gizmo385@users.noreply.github.com>
|
|
7
7
|
License: MIT License
|
|
8
8
|
|
|
9
9
|
Copyright (c) 2024 Christopher Chapline
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import subprocess
|
|
3
|
+
from asyncio import sleep
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from lazy_github.lib.logging import lg
|
|
7
|
+
from lazy_github.models.github import Notification
|
|
8
|
+
|
|
9
|
+
NOTIFICATIONS_PAGE_COUNT = 30
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class _FinishedCommand:
|
|
14
|
+
returncode: int
|
|
15
|
+
stdout: str
|
|
16
|
+
stderr: str
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
async def _run_gh_cli_command(command: list[str]) -> _FinishedCommand:
|
|
20
|
+
"""Simple wrapper around running a Github CLI command"""
|
|
21
|
+
full_command = ["gh"] + command
|
|
22
|
+
proc = subprocess.Popen(full_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
23
|
+
while True:
|
|
24
|
+
if proc.poll() is None:
|
|
25
|
+
raw_stdout, raw_stderr = proc.communicate()
|
|
26
|
+
return _FinishedCommand(proc.returncode, raw_stdout.decode(), raw_stderr.decode())
|
|
27
|
+
else:
|
|
28
|
+
await sleep(0.5)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
async def is_logged_in() -> bool:
|
|
32
|
+
"""Checks to see if the user is currently logged into the GitHub CLI"""
|
|
33
|
+
try:
|
|
34
|
+
result = await _run_gh_cli_command(["auth", "status"])
|
|
35
|
+
return result.returncode == 0
|
|
36
|
+
except Exception:
|
|
37
|
+
lg.exception("Error checking if github CLI is authenticated")
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
async def fetch_notifications(all: bool) -> list[Notification]:
|
|
42
|
+
"""Fetches notifications on GitHub. If all=True, then previously read notifications will also be returned"""
|
|
43
|
+
result = await _run_gh_cli_command(["api", f"/notifications?all={str(all).lower()}"])
|
|
44
|
+
notifications: list[Notification] = []
|
|
45
|
+
if result.stdout:
|
|
46
|
+
parsed = json.loads(result.stdout)
|
|
47
|
+
notifications = [Notification(**n) for n in parsed]
|
|
48
|
+
return notifications
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
async def mark_notification_as_read(notification: Notification) -> None:
|
|
52
|
+
await _run_gh_cli_command(["--method", "PATCH", "api", f"/notifications/threads/{notification.id}"])
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
async def unread_notification_count() -> int:
|
|
56
|
+
"""Returns the number of currently unread notifications on GitHub"""
|
|
57
|
+
return len(await fetch_notifications(all=False))
|
|
@@ -40,7 +40,7 @@ class _NotificationsTableTabPane(TabPane):
|
|
|
40
40
|
self.searchable_table.table.add_row(
|
|
41
41
|
notification.updated_at.strftime("%c"),
|
|
42
42
|
notification.subject.subject_type,
|
|
43
|
-
notification.subject.title,
|
|
43
|
+
notification.subject.title.strip(),
|
|
44
44
|
notification.reason.replace("_", " ").title(),
|
|
45
45
|
notification.id,
|
|
46
46
|
key=str(notification.id),
|
|
@@ -135,9 +135,6 @@ class NotificationsContainer(Container):
|
|
|
135
135
|
self.action_view_read()
|
|
136
136
|
|
|
137
137
|
def on_mount(self) -> None:
|
|
138
|
-
self.read_tab.searchable_table.loading = True
|
|
139
|
-
self.unread_tab.searchable_table.loading = True
|
|
140
|
-
|
|
141
138
|
self.load_notifications()
|
|
142
139
|
|
|
143
140
|
|
|
@@ -148,7 +145,8 @@ class NotificationsModal(ModalScreen[None]):
|
|
|
148
145
|
}
|
|
149
146
|
|
|
150
147
|
NotificationsContainer {
|
|
151
|
-
width: 100;
|
|
148
|
+
min-width: 100;
|
|
149
|
+
max-width: 80%;
|
|
152
150
|
max-height: 50;
|
|
153
151
|
border: thick $background 80%;
|
|
154
152
|
background: $surface-lighten-3;
|
|
@@ -346,7 +346,7 @@ class LazyGithubMainScreen(Screen):
|
|
|
346
346
|
NOTIFICATION_REFRESH_INTERVAL, self.refresh_notification_count
|
|
347
347
|
)
|
|
348
348
|
|
|
349
|
-
@work
|
|
349
|
+
@work(thread=True)
|
|
350
350
|
async def refresh_notification_count(self) -> None:
|
|
351
351
|
widget = self.query_one("#unread_notifications", UnreadNotifications)
|
|
352
352
|
if LazyGithubContext.config.notifications.enabled:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lazy-github
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: A terminal UI for interacting with Github
|
|
5
|
-
Author-email: Chris
|
|
6
|
-
Maintainer-email: Chris
|
|
5
|
+
Author-email: "Chris (Gizmo)" <gizmo385@users.noreply.github.com>
|
|
6
|
+
Maintainer-email: "Chris (Gizmo)" <gizmo385@users.noreply.github.com>
|
|
7
7
|
License: MIT License
|
|
8
8
|
|
|
9
9
|
Copyright (c) 2024 Christopher Chapline
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
name = "lazy-github"
|
|
3
3
|
description = "A terminal UI for interacting with Github"
|
|
4
4
|
readme = "README.md"
|
|
5
|
-
version = "0.2.
|
|
5
|
+
version = "0.2.6"
|
|
6
6
|
authors = [
|
|
7
|
-
{ name = "Chris
|
|
7
|
+
{ name = "Chris (Gizmo)", email = "gizmo385@users.noreply.github.com" },
|
|
8
8
|
]
|
|
9
9
|
maintainers = [
|
|
10
|
-
{ name = "Chris
|
|
10
|
+
{ name = "Chris (Gizmo)", email = "gizmo385@users.noreply.github.com" },
|
|
11
11
|
]
|
|
12
12
|
license = { file = "LICENSE"}
|
|
13
13
|
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import json
|
|
3
|
-
from asyncio.subprocess import PIPE, Process
|
|
4
|
-
|
|
5
|
-
from lazy_github.models.github import Notification
|
|
6
|
-
|
|
7
|
-
NOTIFICATIONS_PAGE_COUNT = 30
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
async def _run_gh_cli_command(command: str) -> Process:
|
|
11
|
-
"""Simple wrapper around running a Github CLI command"""
|
|
12
|
-
return await asyncio.create_subprocess_shell(f"gh {command}", stdout=PIPE, stderr=PIPE)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
async def is_logged_in() -> bool:
|
|
16
|
-
"""Checks to see if the user is currently logged into the GitHub CLI"""
|
|
17
|
-
try:
|
|
18
|
-
result = await _run_gh_cli_command("auth status")
|
|
19
|
-
await result.wait()
|
|
20
|
-
return result.returncode == 0
|
|
21
|
-
except Exception:
|
|
22
|
-
return False
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
async def fetch_notifications(all: bool) -> list[Notification]:
|
|
26
|
-
"""Fetches notifications on GitHub. If all=True, then previously read notifications will also be returned"""
|
|
27
|
-
result = await _run_gh_cli_command(f'api "/notifications?all={str(all).lower()}"')
|
|
28
|
-
await result.wait()
|
|
29
|
-
notifications: list[Notification] = []
|
|
30
|
-
if result.stdout:
|
|
31
|
-
stdout = await result.stdout.read()
|
|
32
|
-
parsed = json.loads(stdout.decode())
|
|
33
|
-
notifications = [Notification(**n) for n in parsed]
|
|
34
|
-
return notifications
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
async def mark_notification_as_read(notification: Notification) -> None:
|
|
38
|
-
result = await _run_gh_cli_command(f"--method PATCH api /notifications/threads/{notification.id}")
|
|
39
|
-
await result.wait()
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
async def unread_notification_count() -> int:
|
|
43
|
-
"""Returns the number of currently unread notifications on GitHub"""
|
|
44
|
-
return len(await fetch_notifications(all=False))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|