@@ -4,7 +4,12 @@ use indicatif::HumanBytes;
4
4
use regex:: Regex ;
5
5
use reqwest:: StatusCode ;
6
6
use serde:: Deserialize ;
7
- use soar_core:: { config:: get_config, SoarResult } ;
7
+ use soar_core:: {
8
+ config:: get_config,
9
+ database:: { models:: Package , packages:: PackageQueryBuilder } ,
10
+ package:: query:: PackageQuery ,
11
+ SoarResult ,
12
+ } ;
8
13
use soar_dl:: {
9
14
downloader:: { DownloadOptions , DownloadState , Downloader , OciDownloadOptions , OciDownloader } ,
10
15
error:: DownloadError ,
@@ -19,7 +24,8 @@ use tracing::{error, info};
19
24
20
25
use crate :: {
21
26
progress:: { self , create_progress_bar} ,
22
- utils:: interactive_ask,
27
+ state:: AppState ,
28
+ utils:: { interactive_ask, select_package_interactively} ,
23
29
} ;
24
30
25
31
pub struct DownloadContext {
@@ -127,7 +133,57 @@ pub async fn handle_direct_downloads(
127
133
eprintln ! ( "{}" , e) ;
128
134
} ;
129
135
}
130
- Err ( err) => eprintln ! ( "Error parsing URL '{}' : {}" , link, err) ,
136
+ Err ( _) => {
137
+ // if it's not a url, try to parse it as package
138
+ let state = AppState :: new ( ) ;
139
+ let repo_db = state. repo_db ( ) . await ?;
140
+ let query = PackageQuery :: try_from ( link. as_str ( ) ) ?;
141
+ let builder = PackageQueryBuilder :: new ( repo_db. clone ( ) ) ;
142
+ let builder = query. apply_filters ( builder) ;
143
+ let packages: Vec < Package > = builder. load ( ) ?. items ;
144
+
145
+ if packages. is_empty ( ) {
146
+ eprintln ! ( "Invalid download resource '{}'" , link) ;
147
+ break ;
148
+ }
149
+
150
+ let package = if packages. len ( ) > 1 {
151
+ & select_package_interactively ( packages, link) ?. unwrap ( )
152
+ } else {
153
+ packages. first ( ) . unwrap ( )
154
+ } ;
155
+
156
+ info ! (
157
+ "Downloading package: {}#{}" ,
158
+ package. pkg_name, package. pkg_id
159
+ ) ;
160
+ if let Some ( ref url) = package. ghcr_blob {
161
+ let options = OciDownloadOptions {
162
+ url : url. to_string ( ) ,
163
+ output_path : None ,
164
+ progress_callback : Some ( progress_callback. clone ( ) ) ,
165
+ api : None ,
166
+ concurrency : Some ( 1 ) ,
167
+ regex_patterns : Vec :: new ( ) ,
168
+ exclude_keywords : Vec :: new ( ) ,
169
+ match_keywords : Vec :: new ( ) ,
170
+ exact_case : false ,
171
+ } ;
172
+
173
+ let mut downloader = OciDownloader :: new ( options) ;
174
+
175
+ downloader. download_oci ( ) . await ?;
176
+ } else {
177
+ let downloader = Downloader :: default ( ) ;
178
+ let options = DownloadOptions {
179
+ url : package. download_url . clone ( ) ,
180
+ output_path : None ,
181
+ progress_callback : Some ( progress_callback. clone ( ) ) ,
182
+ } ;
183
+
184
+ downloader. download ( options) . await ?;
185
+ }
186
+ }
131
187
} ;
132
188
}
133
189
0 commit comments