11use crate :: infrastructure:: cache:: { TrendingRepository , TRENDING_CACHE } ;
2+ use crate :: infrastructure:: http:: OssInsightClient ;
23use crate :: presentation:: cli:: commands:: run_game_session;
34use crate :: presentation:: cli:: views:: { trending_repository_selection_view, trending_unified_view} ;
45use crate :: presentation:: cli:: Cli ;
56use crate :: { GitTypeError , Result } ;
6- use reqwest:: Client ;
7- use std:: time:: Duration ;
87
98const SUPPORTED_LANGUAGES : & [ ( & str , & str ) ] = & [
109 ( "C" , "C" ) ,
@@ -52,9 +51,8 @@ pub async fn run_trending(
5251 }
5352 if let Some ( name) = repo_name {
5453 // Direct repository selection by name
55- let client = Client :: new ( ) ;
5654 let repos =
57- fetch_trending_repositories_cached ( & client , language. as_deref ( ) , & period) . await ?;
55+ fetch_trending_repositories_cached ( & ( ) , language. as_deref ( ) , & period) . await ?;
5856
5957 if let Some ( repo) = select_repository_by_name ( & repos, & name) {
6058 let repo_url = format ! ( "https://github.com/{}" , repo. repo_name) ;
@@ -72,9 +70,8 @@ pub async fn run_trending(
7270 }
7371 } else if language. is_some ( ) {
7472 // Language provided - show repositories directly
75- let client = Client :: new ( ) ;
7673 let repos =
77- fetch_trending_repositories_cached ( & client , language. as_deref ( ) , & period) . await ?;
74+ fetch_trending_repositories_cached ( & ( ) , language. as_deref ( ) , & period) . await ?;
7875
7976 if repos. is_empty ( ) {
8077 return Ok ( ( ) ) ;
@@ -116,132 +113,34 @@ pub async fn run_trending(
116113 Ok ( ( ) )
117114}
118115
119- // Make this function public so it can be used from the UI
120116pub async fn fetch_trending_repositories_cached (
121- client : & Client ,
117+ _client : & ( ) ,
122118 language : Option < & str > ,
123119 period : & str ,
124120) -> Result < Vec < TrendingRepository > > {
125- // Create cache key from parameters
126121 let cache_key = format ! ( "{}:{}" , language. unwrap_or( "all" ) , period) ;
127122
128- // Check cache first
129123 if let Some ( cached_repos) = TRENDING_CACHE . get ( & cache_key) {
130124 log:: debug!( "Using cached trending repositories for key: {}" , cache_key) ;
131125 return Ok ( cached_repos) ;
132126 }
133127
134- // Clean up expired cache entries before making API call
135128 TRENDING_CACHE . cleanup_expired ( ) ;
136129
137- // Rate limiting: wait a bit between API calls to be respectful
138- let rate_limit_ms = 100 ; // 100ms
139- tokio:: time:: sleep ( Duration :: from_millis ( rate_limit_ms) ) . await ;
130+ let rate_limit_ms = 100 ;
131+ tokio:: time:: sleep ( std:: time:: Duration :: from_millis ( rate_limit_ms) ) . await ;
140132
141- // Fetch from API
142- let repos = fetch_trending_repositories ( client, language, period) . await ?;
133+ let api_client = OssInsightClient :: new ( ) ;
134+ let repos = api_client
135+ . fetch_trending_repositories ( language, period)
136+ . await ?;
143137
144- // Cache the result
145138 TRENDING_CACHE . set ( & cache_key, repos. clone ( ) ) ;
146139 log:: debug!( "Cached trending repositories for key: {}" , cache_key) ;
147140
148141 Ok ( repos)
149142}
150143
151- async fn fetch_trending_repositories (
152- client : & Client ,
153- language : Option < & str > ,
154- period : & str ,
155- ) -> Result < Vec < TrendingRepository > > {
156- let api_period = match period {
157- "daily" => "past_24_hours" ,
158- "weekly" => "past_week" ,
159- "monthly" => "past_month" ,
160- _ => "past_24_hours" ,
161- } ;
162-
163- let mut url = format ! (
164- "https://api.ossinsight.io/v1/trends/repos/?period={}" ,
165- api_period
166- ) ;
167-
168- if let Some ( lang) = language {
169- // Map to correct language name format expected by API
170- let api_lang = match lang. to_lowercase ( ) . as_str ( ) {
171- "javascript" => "JavaScript" . to_string ( ) ,
172- "typescript" => "TypeScript" . to_string ( ) ,
173- "c++" => "C++" . to_string ( ) ,
174- "c#" => "C#" . to_string ( ) ,
175- "php" => "PHP" . to_string ( ) ,
176- _ => {
177- // Capitalize first letter for other languages
178- let mut chars = lang. chars ( ) ;
179- match chars. next ( ) {
180- None => lang. to_string ( ) ,
181- Some ( first) => {
182- first. to_uppercase ( ) . collect :: < String > ( ) + & chars. as_str ( ) . to_lowercase ( )
183- }
184- }
185- }
186- } ;
187- url = format ! ( "{}&language={}" , url, urlencoding:: encode( & api_lang) ) ;
188- }
189-
190- let response = client
191- . get ( & url)
192- . header ( "User-Agent" , "gittype" )
193- . header ( "Accept" , "application/json" )
194- . timeout ( Duration :: from_secs ( 10 ) )
195- . send ( )
196- . await ?;
197-
198- if !response. status ( ) . is_success ( ) {
199- return Err ( GitTypeError :: ApiError ( format ! (
200- "OSS Insight API request failed: {}" ,
201- response. status( )
202- ) ) ) ;
203- }
204-
205- #[ derive( serde:: Deserialize ) ]
206- struct ApiResponse {
207- data : ApiData ,
208- }
209-
210- #[ derive( serde:: Deserialize ) ]
211- struct ApiData {
212- rows : Vec < RowData > ,
213- }
214-
215- #[ derive( serde:: Deserialize ) ]
216- struct RowData {
217- repo_name : String ,
218- primary_language : Option < String > ,
219- description : Option < String > ,
220- stars : Option < String > ,
221- forks : Option < String > ,
222- total_score : Option < String > ,
223- }
224-
225- let api_response: ApiResponse = response. json ( ) . await ?;
226-
227- // Convert API response to TrendingRepository objects
228- let repositories: Vec < TrendingRepository > = api_response
229- . data
230- . rows
231- . into_iter ( )
232- . map ( |row| TrendingRepository {
233- repo_name : row. repo_name ,
234- primary_language : row. primary_language ,
235- description : row. description ,
236- stars : row. stars . unwrap_or_else ( || "0" . to_string ( ) ) ,
237- forks : row. forks . unwrap_or_else ( || "0" . to_string ( ) ) ,
238- total_score : row. total_score . unwrap_or_else ( || "0" . to_string ( ) ) ,
239- } )
240- . collect ( ) ;
241-
242- Ok ( repositories)
243- }
244-
245144fn select_repository_by_name < ' a > (
246145 repos : & ' a [ TrendingRepository ] ,
247146 name : & str ,
0 commit comments