1+ // Read S SmartImage.Linux SearchCommand.cs
2+ // 2023-07-05 @ 2:07 AM
3+
4+ using System . Collections . Concurrent ;
5+ using System . ComponentModel ;
6+ using System . Diagnostics ;
7+ using SmartImage . Lib ;
8+ using SmartImage . Lib . Engines ;
9+ using SmartImage . Lib . Results ;
10+ using SmartImage . Lib . Utilities ;
11+ using Spectre . Console ;
12+ using Spectre . Console . Cli ;
13+ using Spectre . Console . Rendering ;
14+
15+ namespace SmartImage . Linux . Cli ;
16+
17+ internal sealed class SearchCommand : AsyncCommand < SearchCommand . Settings >
18+ {
19+ private SearchClient m_client ;
20+ private SearchQuery ? m_query ;
21+ private SearchConfig m_config ;
22+ private readonly CancellationTokenSource m_cts = new ( ) ;
23+ private readonly ConcurrentBag < SearchResult > m_results = new ( ) ;
24+
25+ public sealed class Settings : CommandSettings
26+ {
27+ [ Description ( "Query" ) ]
28+ [ CommandArgument ( 0 , "[query]" ) ]
29+ public string ? Query { get ; init ; }
30+
31+ [ CommandOption ( "-e|--engines" ) ]
32+ [ DefaultValue ( SearchConfig . SE_DEFAULT ) ]
33+ public SearchEngineOptions Engines { get ; init ; }
34+
35+ [ CommandOption ( "--autosearch" ) ]
36+ [ DefaultValue ( SearchConfig . AUTOSEARCH_DEFAULT ) ]
37+ public bool AutoSearch { get ; init ; }
38+ }
39+
40+ private async Task RunSearchAsync ( )
41+ {
42+
43+ void OnComplete ( object sender , SearchResult [ ] searchResults )
44+ {
45+ // pt1.Increment(COMPLETE);
46+ }
47+
48+ m_client . OnComplete += OnComplete ;
49+
50+ var mt = new Table ( )
51+ {
52+ Border = TableBorder . Heavy ,
53+ Title = new ( $ "Results") ,
54+ ShowFooters = true ,
55+ ShowHeaders = true ,
56+ } ;
57+
58+ mt . AddColumns ( new TableColumn ( "#" ) ,
59+ new TableColumn ( "Name" ) ,
60+ new TableColumn ( "Similarity" ) ,
61+ new TableColumn ( "Artist" ) ,
62+ new TableColumn ( "Description" ) ,
63+ new TableColumn ( "Character" )
64+ ) ;
65+
66+ // pt1.MaxValue = m_client.Engines.Length;
67+
68+ void OnResult ( object sender , SearchResult sr )
69+ {
70+ m_results . Add ( sr ) ;
71+ // ptMap[sr.Engine].Item1.Increment(COMPLETE);
72+ // pt1.Increment(1.0);
73+ int i = 0 ;
74+
75+ // var t = ptMap[sr.Engine].Item2;
76+
77+ foreach ( SearchResultItem sri in sr . Results )
78+ {
79+ mt . Rows . Add ( new IRenderable [ ]
80+ {
81+ new Text ( $ "{ i + 1 } ") ,
82+ Markup . FromInterpolated ( $ "[link={ sri . Url } ]{ sr . Engine . Name } #{ i + 1 } [/]") ,
83+ Markup . FromInterpolated ( $ "{ sri . Similarity } ") ,
84+ Markup . FromInterpolated ( $ "{ sri . Artist } ") ,
85+ Markup . FromInterpolated ( $ "{ sri . Description } ") ,
86+ Markup . FromInterpolated ( $ "{ sri . Character } ") ,
87+ } ) ;
88+
89+ i ++ ;
90+ }
91+
92+ // AnsiConsole.Write(t);
93+ }
94+
95+ m_client . OnResult += OnResult ;
96+
97+ var run = m_client . RunSearchAsync ( m_query , token : m_cts . Token ) ;
98+
99+ var sw = Stopwatch . StartNew ( ) ;
100+
101+ var live = AConsole . Live ( mt )
102+ . AutoClear ( false )
103+ . Overflow ( VerticalOverflow . Ellipsis )
104+ . StartAsync ( async ( ctx ) =>
105+ {
106+ while ( ! run . IsCompleted )
107+ {
108+ ctx . Refresh ( ) ;
109+ mt . Caption = new TableTitle ( $ "{ sw . Elapsed . TotalSeconds : F3} ") ;
110+ // await Task.Delay(1000);
111+ }
112+
113+ } ) ;
114+
115+ await run ;
116+
117+ await live ;
118+
119+ }
120+
121+ private const int COMPLETE = 100 ;
122+
123+ public async Task < object ? > RunAsync ( object ? c )
124+ {
125+ var cstr = ( string ? ) c ;
126+ Debug . WriteLine ( $ "Input: { cstr } ") ;
127+
128+ await AConsole . Progress ( ) . AutoRefresh ( true ) . StartAsync ( async ctx =>
129+ {
130+ var p = ctx . AddTask ( "Creating query" ) ;
131+ p . IsIndeterminate = true ;
132+ m_query = await SearchQuery . TryCreateAsync ( cstr ) ;
133+ p . Increment ( COMPLETE ) ;
134+ ctx . Refresh ( ) ;
135+ } ) ;
136+
137+ AConsole . WriteLine ( $ "Input: { m_query } ") ;
138+
139+ await AConsole . Progress ( ) . AutoRefresh ( true ) . StartAsync ( async ctx =>
140+ {
141+ var p = ctx . AddTask ( "Uploading" ) ;
142+ p . IsIndeterminate = true ;
143+ var url = await m_query . UploadAsync ( ) ;
144+
145+ if ( url == null )
146+ {
147+ throw new SmartImageException ( ) ; //todo
148+ }
149+
150+ p . Increment ( COMPLETE ) ;
151+ ctx . Refresh ( ) ;
152+ } ) ;
153+
154+ AConsole . MarkupLine ( $ "[green]{ m_query . Upload } [/]") ;
155+
156+ AConsole . WriteLine ( $ "{ m_config } ") ;
157+
158+ Console . CancelKeyPress += ( sender , args ) =>
159+ {
160+ AConsole . MarkupLine ( $ "[red]Cancellation requested[/]") ;
161+ m_cts . Cancel ( ) ;
162+ args . Cancel = false ;
163+
164+ Environment . Exit ( - 1 ) ;
165+ } ;
166+
167+ // await Prg_1.StartAsync(RunSearchAsync);
168+
169+ await RunSearchAsync ( ) ;
170+
171+ return null ;
172+
173+ }
174+
175+ public override async Task < int > ExecuteAsync ( CommandContext context , Settings settings )
176+ {
177+ m_config = new SearchConfig ( )
178+ {
179+ SearchEngines = settings . Engines ,
180+ AutoSearch = settings . AutoSearch
181+ } ;
182+
183+ m_client = new SearchClient ( m_config ) ;
184+
185+ var r = await RunAsync ( settings . Query ) ;
186+ AC . WriteLine ( $ "{ m_query } ") ;
187+
188+ foreach ( var sr in m_results )
189+ {
190+ AC . WriteLine ( $ "{ sr } ") ;
191+ Console . ReadKey ( ) ;
192+
193+ foreach ( SearchResultItem sri in sr . AllResults )
194+ {
195+ AC . WriteLine ( $ "{ sri } ") ;
196+
197+ }
198+ }
199+
200+ return 0 ;
201+ }
202+ }
0 commit comments