44
55import argparse
66import sys
7- from typing import List , Dict
7+ from typing import List , Dict , Callable
88from .scraper import GitHubTrendingScraper
99from .display import DisplayManager
1010
1111
1212class GitHubTrendingCLI :
1313 """Main CLI application class."""
1414
15+ # Constants
16+ VALID_RANGES = ['daily' , 'weekly' , 'monthly' ]
17+ DEFAULT_RANGE = 'daily'
18+
1519 def __init__ (self ):
1620 self .scraper = GitHubTrendingScraper ()
1721 self .display = DisplayManager ()
18- self .current_repos = []
22+ self .current_repos : List [ Dict [ str , str ]] = []
1923
2024 def run (self ):
2125 """Main entry point for the CLI application."""
22- parser = self ._create_parser ()
23- args = parser .parse_args ()
26+ args = self ._parse_arguments ()
27+
28+ if not self ._fetch_repositories (args .range ):
29+ sys .exit (1 )
2430
25- # Fetch trending repositories
31+ self ._display_repositories (args .range )
32+
33+ def _parse_arguments (self ) -> argparse .Namespace :
34+ """Parse command line arguments."""
35+ parser = self ._create_parser ()
36+ return parser .parse_args ()
37+
38+ def _fetch_repositories (self , date_range : str ) -> bool :
39+ """Fetch trending repositories. Returns True if successful."""
2640 print ("🔍 Fetching trending repositories..." )
27- self .current_repos = self .scraper .get_trending_repos (args . range )
41+ self .current_repos = self .scraper .get_trending_repos (date_range )
2842
2943 if not self .current_repos :
3044 print ("❌ No repositories found or error occurred." )
31- sys .exit (1 )
32-
33- # Display repositories with interactive callback
45+ return False
46+ return True
47+
48+ def _display_repositories (self , date_range : str ):
49+ """Display repositories with interactive interface."""
3450 self .display .show_repositories (
3551 self .current_repos ,
36- args . range ,
52+ date_range ,
3753 callback = self ._handle_repository_selection
3854 )
3955
@@ -42,39 +58,50 @@ def _create_parser(self) -> argparse.ArgumentParser:
4258 parser = argparse .ArgumentParser (
4359 description = "Browse GitHub trending repositories from the command line" ,
4460 formatter_class = argparse .RawDescriptionHelpFormatter ,
45- epilog = """
46- Examples:
47- github-trending # Show today's trending repos
48- github-trending --range weekly # Show this week's trending repos
49- github-trending --range monthly # Show this month's trending repos
50- """
61+ epilog = self ._get_usage_examples ()
5162 )
5263
5364 parser .add_argument (
5465 '--range' , '-r' ,
55- choices = [ 'daily' , 'weekly' , 'monthly' ] ,
56- default = 'daily' ,
57- help = 'Time range for trending repositories (default: daily )'
66+ choices = self . VALID_RANGES ,
67+ default = self . DEFAULT_RANGE ,
68+ help = f 'Time range for trending repositories (default: { self . DEFAULT_RANGE } )'
5869 )
5970
6071 return parser
6172
73+ def _get_usage_examples (self ) -> str :
74+ """Get usage examples for the help text."""
75+ return """
76+ Examples:
77+ github-trending # Show today's trending repos
78+ github-trending --range weekly # Show this week's trending repos
79+ github-trending --range monthly # Show this month's trending repos
80+ """
81+
6282 def _handle_repository_selection (self , repo_index : int , displayed_repos : List [Dict [str , str ]]):
6383 """Handle repository selection from the scrolling interface."""
6484 repo = displayed_repos [repo_index ]
6585
86+ self ._show_repository_details (repo )
87+ self ._show_repository_readme (repo )
88+ self ._wait_for_user ()
89+
90+ def _show_repository_details (self , repo : Dict [str , str ]):
91+ """Display repository details header."""
6692 print ("\n " + "=" * 80 )
67- print (f "📦 Repository Details" )
93+ print ("📦 Repository Details" )
6894 print ("=" * 80 )
69-
7095 self .display .show_repository_header (repo )
71-
96+
97+ def _show_repository_readme (self , repo : Dict [str , str ]):
98+ """Fetch and display repository README."""
7299 print ("\n 📖 Fetching README..." )
73100 readme_content = self .scraper .get_readme (repo ['url' ])
74-
75101 self .display .show_readme (readme_content )
76-
77- # Wait for user to continue
102+
103+ def _wait_for_user (self ):
104+ """Wait for user input to continue."""
78105 input ("\n 📖 Press Enter to continue..." )
79106
80107
@@ -84,11 +111,21 @@ def main():
84111 cli = GitHubTrendingCLI ()
85112 cli .run ()
86113 except KeyboardInterrupt :
87- print ("\n \n 👋 Thanks for using GitHub Trending CLI!" )
88- sys .exit (0 )
114+ _handle_keyboard_interrupt ()
89115 except Exception as e :
90- print (f"❌ An unexpected error occurred: { e } " )
91- sys .exit (1 )
116+ _handle_unexpected_error (e )
117+
118+
119+ def _handle_keyboard_interrupt ():
120+ """Handle keyboard interrupt gracefully."""
121+ print ("\n \n 👋 Thanks for using GitHub Trending CLI!" )
122+ sys .exit (0 )
123+
124+
125+ def _handle_unexpected_error (error : Exception ):
126+ """Handle unexpected errors."""
127+ print (f"❌ An unexpected error occurred: { error } " )
128+ sys .exit (1 )
92129
93130
94131if __name__ == "__main__" :
0 commit comments