Skip to content

Commit bf85af1

Browse files
author
Panos
committed
make it simpler
1 parent 2bb9fa3 commit bf85af1

File tree

2 files changed

+195
-76
lines changed

2 files changed

+195
-76
lines changed

github_trending/cli.py

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ def run(self):
3030
print("❌ No repositories found or error occurred.")
3131
sys.exit(1)
3232

33-
# Display repositories
34-
self.display.show_repositories(self.current_repos, args.range)
35-
36-
# Start interactive navigation
37-
self._interactive_navigation(args.range)
33+
# Display repositories with interactive callback
34+
self.display.show_repositories(
35+
self.current_repos,
36+
args.range,
37+
callback=self._handle_repository_selection
38+
)
3839

3940
def _create_parser(self) -> argparse.ArgumentParser:
4041
"""Create and configure the argument parser."""
@@ -58,43 +59,9 @@ def _create_parser(self) -> argparse.ArgumentParser:
5859

5960
return parser
6061

61-
def _interactive_navigation(self, date_range: str):
62-
"""Handle interactive navigation through repositories."""
63-
while True:
64-
try:
65-
print("\n" + "╔" + "═"*58 + "╗")
66-
print("║" + "🧭 Navigation Menu".center(58) + "║")
67-
print("╠" + "═"*58 + "╣")
68-
print("║ 📖 Enter a number (1-{}) to view README".format(len(self.current_repos)).ljust(58) + "║")
69-
print("║ 📋 Enter 'list' or 'l' to show repositories again".ljust(58) + "║")
70-
print("║ 🚪 Enter 'quit' or 'q' to exit".ljust(58) + "║")
71-
print("╚" + "═"*58 + "╝")
72-
73-
user_input = input("\n👉 Your choice: ").strip().lower()
74-
75-
if user_input in ['quit', 'q', 'exit']:
76-
print("\n👋 Thanks for using GitHub Trending CLI!")
77-
break
78-
elif user_input in ['list', 'l']:
79-
self.display.show_repositories(self.current_repos, date_range)
80-
elif user_input.isdigit():
81-
repo_index = int(user_input) - 1
82-
if 0 <= repo_index < len(self.current_repos):
83-
self._show_repository_details(repo_index)
84-
else:
85-
print(f"❌ Invalid number. Please enter 1-{len(self.current_repos)}")
86-
else:
87-
print("❌ Invalid input. Please try again.")
88-
89-
except KeyboardInterrupt:
90-
print("\n\n👋 Thanks for using GitHub Trending CLI!")
91-
break
92-
except Exception as e:
93-
print(f"❌ An error occurred: {e}")
94-
95-
def _show_repository_details(self, repo_index: int):
96-
"""Show detailed information and README for a repository."""
97-
repo = self.current_repos[repo_index]
62+
def _handle_repository_selection(self, repo_index: int, displayed_repos: List[Dict[str, str]]):
63+
"""Handle repository selection from the scrolling interface."""
64+
repo = displayed_repos[repo_index]
9865

9966
print("\n" + "="*80)
10067
print(f"📦 Repository Details")

github_trending/display.py

Lines changed: 186 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
import re
1010
from rich.console import Console
1111
from rich.markdown import Markdown
12+
from rich.panel import Panel
13+
from rich.text import Text
14+
from rich.align import Align
1215

1316

1417
class DisplayManager:
@@ -69,30 +72,36 @@ def _format_number(self, number_str: str) -> str:
6972
except (ValueError, AttributeError):
7073
return number_str or "0"
7174

72-
def show_repositories(self, repos: List[Dict[str, str]], date_range: str):
73-
"""Display a list of trending repositories."""
75+
def show_repositories(self, repos: List[Dict[str, str]], date_range: str, callback=None):
76+
"""Display a list of trending repositories with Rich formatting."""
7477
if not repos:
75-
print("No repositories found.")
78+
self.console.print("[red]No repositories found.[/red]")
7679
return
7780

7881
# Header with enhanced styling
7982
range_emoji = {"daily": "📅", "weekly": "📊", "monthly": "📈"}.get(date_range, "📋")
8083
range_text = date_range.title() if date_range != "current" else "Current List"
8184

82-
# Create a beautiful header
83-
header_line = "═" * self.terminal_width
84-
print(f"\n{header_line}")
85-
print(f"🚀 GitHub Trending Repositories - {range_text} {range_emoji}".center(self.terminal_width))
86-
print(f"🌟 Discover the hottest projects on GitHub".center(self.terminal_width))
87-
print(f"{header_line}")
85+
# Simple header without panels
86+
header_text = Text()
87+
header_text.append("🚀 GitHub Trending Repositories", style="bold")
88+
header_text.append(f" - {range_text} {range_emoji}", style="dim")
8889

89-
# Paginate repository list
90-
self._paginate_repositories(repos)
90+
self.console.print()
91+
self.console.print(header_text)
92+
self.console.print()
9193

92-
# Footer with stats
93-
print(f"\n{header_line}")
94-
print(f"📊 Found {len(repos)} trending repositories • Happy coding! 🎉".center(self.terminal_width))
95-
print(f"{header_line}")
94+
# Paginate repository list with Rich
95+
self._paginate_repositories_rich(repos, callback)
96+
97+
# Simple footer without panels
98+
footer_text = Text()
99+
footer_text.append("Found ", style="dim")
100+
footer_text.append(str(len(repos)), style="bold")
101+
footer_text.append(" trending repositories", style="dim")
102+
103+
self.console.print()
104+
self.console.print(footer_text)
96105

97106
def _print_repository_summary(self, index: int, repo: Dict[str, str]):
98107
"""Print a single repository summary with enhanced formatting."""
@@ -250,38 +259,181 @@ def _paginate_content(self, lines: List[str]):
250259
print("\n📖 README reading interrupted.")
251260
break
252261

253-
def _paginate_repositories(self, repos: List[Dict[str, str]]):
254-
"""Display repositories with pagination."""
262+
def _paginate_repositories_rich(self, repos: List[Dict[str, str]], callback=None):
263+
"""Display repositories with scrolling pagination and interactive selection."""
255264
repos_per_page = 5 # Show 5 repositories per page
256265
current_repo = 0
266+
displayed_repos = [] # Keep track of all displayed repos
257267

258-
while current_repo < len(repos):
268+
while True: # Infinite loop - only exit when user presses 'q'
269+
# Clear screen for scroll effect (but keep header visible)
270+
if current_repo > 0:
271+
# Clear previous content but keep some context
272+
print("\033[H\033[2J", end="") # Clear screen
273+
# Re-print header
274+
header_text = Text()
275+
header_text.append("🚀 GitHub Trending Repositories", style="bold")
276+
header_text.append(" - Daily 📅", style="dim")
277+
self.console.print(header_text)
278+
self.console.print()
279+
259280
# Display current page of repositories
260281
end_repo = min(current_repo + repos_per_page, len(repos))
261282

283+
# Add current page repos to displayed list
262284
for i in range(current_repo, end_repo):
263-
repo = repos[i]
264-
self._print_repository_summary(i + 1, repo)
265-
# Add separator between repos (except for the last one on the page)
266-
if i < end_repo - 1:
267-
print("─" * min(60, self.terminal_width - 10))
285+
if i >= len(displayed_repos):
286+
displayed_repos.append(repos[i])
268287

269-
current_repo = end_repo
288+
# Show all repositories up to current point
289+
for i, repo in enumerate(displayed_repos):
290+
name = repo.get('name', 'Unknown').strip()
291+
language = repo.get('language', 'Unknown').strip()
292+
stars = self._format_number(repo.get('stars', '0'))
293+
stars_today = self._format_number(repo.get('stars_today', '0'))
294+
description = repo.get('description', 'No description').strip()
295+
296+
# Clean up repository name
297+
name = re.sub(r'\s+', ' ', name)
298+
299+
# Get language emoji and color
300+
lang_emoji = self.LANGUAGE_COLORS.get(language, self.LANGUAGE_COLORS['Unknown'])
301+
302+
# Color coding for stars today with trending indicators
303+
stars_today_num = int(repo.get('stars_today', '0').replace(',', '') or '0')
304+
if stars_today_num > 100:
305+
stars_today_style = "red"
306+
trending_indicator = "🔥"
307+
elif stars_today_num > 50:
308+
stars_today_style = "yellow"
309+
trending_indicator = "🚀"
310+
elif stars_today_num > 10:
311+
stars_today_style = "green"
312+
trending_indicator = "📈"
313+
else:
314+
stars_today_style = "dim"
315+
trending_indicator = ""
316+
317+
# Create the main line with repository info
318+
line = Text()
319+
line.append(f"{i + 1:2}. ", style="dim")
320+
line.append(f"{name}", style="bold")
321+
line.append(f" {lang_emoji}", style="dim")
322+
line.append(f" ⭐{stars}", style="dim")
323+
line.append(f" {trending_indicator}", style=stars_today_style)
324+
line.append(f"+{stars_today}", style=stars_today_style)
325+
326+
self.console.print(line)
327+
self.console.print(f" [dim]{description}[/dim]")
328+
self.console.print()
270329

271-
# Check if there are more repositories
330+
# Only advance current_repo if there are more repositories to show
331+
if current_repo < len(repos):
332+
current_repo = end_repo
333+
334+
# Interactive prompt
272335
if current_repo < len(repos):
273336
remaining_repos = len(repos) - current_repo
274-
print(f"\n--- More repositories available ({remaining_repos} remaining) ---")
337+
self.console.print(f"[dim]({remaining_repos} more repositories)[/dim]")
338+
prompt_text = f"Enter repo number (1-{len(displayed_repos)}), Enter for more, 'q' to quit: "
339+
else:
340+
prompt_text = f"Enter repo number (1-{len(displayed_repos)}) or 'q' to quit: "
341+
342+
try:
343+
user_input = input(prompt_text).strip().lower()
275344

276-
try:
277-
user_input = input("📋 Press Enter to see more repositories, 'q' to stop browsing: ").strip().lower()
278-
if user_input == 'q':
279-
print("📋 Repository browsing stopped.")
280-
break
281-
print() # Add spacing before next page
282-
except KeyboardInterrupt:
283-
print("\n📋 Repository browsing interrupted.")
345+
if user_input == 'q':
284346
break
347+
elif user_input == '':
348+
if current_repo >= len(repos):
349+
# No more repos, stay in selection mode and redisplay current state
350+
print("\033[H\033[2J", end="") # Clear screen
351+
# Re-print header
352+
header_text = Text()
353+
header_text.append("🚀 GitHub Trending Repositories", style="bold")
354+
header_text.append(" - Daily 📅", style="dim")
355+
self.console.print(header_text)
356+
self.console.print()
357+
358+
# Re-display all repos
359+
for i, repo in enumerate(displayed_repos):
360+
name = repo.get('name', 'Unknown').strip()
361+
language = repo.get('language', 'Unknown').strip()
362+
stars = self._format_number(repo.get('stars', '0'))
363+
stars_today = self._format_number(repo.get('stars_today', '0'))
364+
description = repo.get('description', 'No description').strip()
365+
366+
# Clean up repository name
367+
name = re.sub(r'\s+', ' ', name)
368+
369+
# Get language emoji and color
370+
lang_emoji = self.LANGUAGE_COLORS.get(language, self.LANGUAGE_COLORS['Unknown'])
371+
372+
# Color coding for stars today with trending indicators
373+
stars_today_num = int(repo.get('stars_today', '0').replace(',', '') or '0')
374+
if stars_today_num > 100:
375+
stars_today_style = "red"
376+
trending_indicator = "🔥"
377+
elif stars_today_num > 50:
378+
stars_today_style = "yellow"
379+
trending_indicator = "🚀"
380+
elif stars_today_num > 10:
381+
stars_today_style = "green"
382+
trending_indicator = "📈"
383+
else:
384+
stars_today_style = "dim"
385+
trending_indicator = ""
386+
387+
# Create the main line with repository info
388+
line = Text()
389+
line.append(f"{i + 1:2}. ", style="dim")
390+
line.append(f"{name}", style="bold")
391+
line.append(f" {lang_emoji}", style="dim")
392+
line.append(f" ⭐{stars}", style="dim")
393+
line.append(f" {trending_indicator}", style=stars_today_style)
394+
line.append(f"+{stars_today}", style=stars_today_style)
395+
396+
self.console.print(line)
397+
self.console.print(f" [dim]{description}[/dim]")
398+
self.console.print()
399+
400+
continue
401+
# Continue to next page (only if there are more repos)
402+
continue
403+
else:
404+
# Try to parse as repository number
405+
try:
406+
repo_num = int(user_input)
407+
if 1 <= repo_num <= len(displayed_repos):
408+
# User selected a repository
409+
selected_repo = displayed_repos[repo_num - 1]
410+
if callback:
411+
# Call the callback function (e.g., show repository details)
412+
callback(repo_num - 1, displayed_repos)
413+
# After viewing details, clear screen and redisplay current state
414+
print("\033[H\033[2J", end="") # Clear screen
415+
# Re-print header
416+
header_text = Text()
417+
header_text.append("🚀 GitHub Trending Repositories", style="bold")
418+
header_text.append(" - Daily 📅", style="dim")
419+
self.console.print(header_text)
420+
self.console.print()
421+
# Re-display all repos up to current point
422+
continue
423+
else:
424+
self.console.print(f"\n[green]Selected: {selected_repo.get('name', 'Unknown')}[/green]")
425+
input("Press Enter to continue browsing...")
426+
continue
427+
else:
428+
self.console.print(f"[red]Please enter a number between 1 and {len(displayed_repos)}[/red]")
429+
continue
430+
except ValueError:
431+
self.console.print("[red]Please enter a valid number, Enter, or 'q'[/red]")
432+
continue
433+
434+
except KeyboardInterrupt:
435+
print("\nInterrupted.")
436+
break
285437

286438
def show_error(self, message: str):
287439
"""Display an error message."""

0 commit comments

Comments
 (0)