22// 2023-01-30 @ 10:37 PM
33
44using System . Collections . Concurrent ;
5+ using System . Diagnostics . CodeAnalysis ;
6+ using JetBrains . Annotations ;
57using SmartImage . Lib ;
68using SmartImage . Lib . Engines ;
79using SmartImage . Lib . Results ;
10+ using SmartImage . Utilities ;
811using Spectre . Console ;
12+ using Spectre . Console . Rendering ;
913
1014// ReSharper disable InconsistentNaming
1115
1216namespace SmartImage ;
1317
14- public class CliMain : IDisposable
18+ public sealed class CliMain : IDisposable , IMain
1519{
20+ #region
21+
1622 private const double COMPLETE = 100.0D ;
1723
1824 private static readonly ProgressColumn [ ] PrgCol_1 =
@@ -26,95 +32,173 @@ public class CliMain : IDisposable
2632 new ProgressBarColumn ( )
2733 } ;
2834
29- static CliMain ( ) { }
30-
3135 private static readonly Progress Prg_1 = AnsiConsole . Progress ( )
3236 . AutoClear ( true )
3337 . AutoRefresh ( true )
34- . HideCompleted ( false )
38+ . HideCompleted ( true )
3539 . Columns ( PrgCol_1 ) ;
3640
37- public static async Task RunCliAsync ( string c )
38- {
39- var q = await Prg_1 . StartAsync ( async ctx =>
40- {
41- var t = ctx . AddTask ( "Validating input" ) ;
42- t . IsIndeterminate = true ;
43- var qInner = await SearchQuery . TryCreateAsync ( c ) ;
44- t . Increment ( COMPLETE ) ;
45- return qInner ;
46- } ) ;
41+ static CliMain ( ) { }
4742
48- AnsiConsole . WriteLine ( $ " { q } " ) ;
43+ #endregion
4944
50- var url = await Prg_1 . StartAsync ( async ( p ) =>
51- {
52- var pt = p . AddTask ( $ "Upload") ;
53- pt . IsIndeterminate = true ;
54- var urlInner = await q . UploadAsync ( ) ;
55- pt . Increment ( COMPLETE ) ;
56- return urlInner ;
45+ private readonly ConcurrentBag < SearchResult > m_results = new ( ) ;
46+
47+ private SearchResult [ ] m_results2 ;
48+
49+ private readonly SearchConfig m_cfg ;
50+
51+ private SearchQuery m_query ;
52+
53+ private readonly SearchClient m_client ;
54+
55+ private readonly CancellationTokenSource m_cts ;
56+
57+ public CliMain ( )
58+ {
59+ m_cfg = new SearchConfig ( ) ;
60+ m_client = new SearchClient ( m_cfg ) ;
61+ m_query = SearchQuery . Null ;
62+ m_cts = new CancellationTokenSource ( ) ;
63+ }
5764
58- } ) ;
65+ public async Task < object ? > RunAsync ( object ? c )
66+ {
67+ await Prg_1 . StartAsync ( ctx => ValidateInputAsync ( ctx , c as string ) ) ;
5968
60- AnsiConsole . MarkupLine ( $ "[green] { q . Upload } [/] ") ;
69+ AnsiConsole . WriteLine ( $ "{ m_query } ") ;
6170
62- var cfg = new SearchConfig ( ) ;
63- var sc = new SearchClient ( cfg ) ;
71+ var url = await Prg_1 . StartAsync ( UploadInputAsync ) ;
6472
65- AnsiConsole . WriteLine ( $ "{ cfg } ") ;
73+ AnsiConsole . MarkupLine ( $ "[green] { m_query . Upload } [/] ") ;
6674
67- var cts = new CancellationTokenSource ( ) ;
75+ AnsiConsole . WriteLine ( $ " { m_cfg } " ) ;
6876
6977 System . Console . CancelKeyPress += ( sender , args ) =>
7078 {
7179 args . Cancel = false ;
72- cts . Cancel ( ) ;
80+ m_cts . Cancel ( ) ;
7381 AnsiConsole . MarkupLine ( $ "[red]Cancellation requested { args } [/]") ;
7482 } ;
7583
76- var results = await Prg_1 . StartAsync ( async ctx =>
77- {
78- var ptMap = new Dictionary < BaseSearchEngine , ProgressTask > ( ) ;
84+ await Prg_1 . StartAsync ( RunSearchAsync ) ;
85+ return null ;
86+ }
7987
80- foreach ( var e in sc . Engines ) {
81- var t = ctx . AddTask ( $ "{ e } ") ;
82- t . IsIndeterminate = true ;
83- ptMap . Add ( e , t ) ;
84- }
88+ private async Task ValidateInputAsync ( ProgressContext ctx , string c )
89+ {
90+ var t = ctx . AddTask ( "Validating input" ) ;
91+ t . IsIndeterminate = true ;
92+ m_query = await SearchQuery . TryCreateAsync ( c ) ;
93+ t . Increment ( COMPLETE ) ;
94+ }
8595
86- var pt1 = ctx . AddTask ( "[yellow]Searching[/]" ) ;
87- pt1 . IsIndeterminate = false ;
88- var rg = new ConcurrentBag < SearchResult > ( ) ;
89-
90- sc . OnComplete += ( sender , searchResults ) =>
91- {
92- pt1 . Increment ( COMPLETE ) ;
93- } ;
94- pt1 . MaxValue = sc . Engines . Length ;
95-
96- sc . OnResult += ( sender , result ) =>
97- {
98- rg . Add ( result ) ;
99- ptMap [ result . Engine ] . Increment ( COMPLETE ) ;
100- pt1 . Increment ( ( 1.0 ) ) ;
101-
102- } ;
96+ private async Task < Url > UploadInputAsync ( ProgressContext p )
97+ {
98+ var pt = p . AddTask ( $ "Upload") ;
99+ pt . IsIndeterminate = true ;
100+ var urlInner = await m_query . UploadAsync ( ) ;
101+ pt . Increment ( COMPLETE ) ;
102+ return urlInner ;
103+
104+ }
105+
106+ private async Task RunSearchAsync ( ProgressContext ctx )
107+ {
108+ var ptMap = new Dictionary < BaseSearchEngine , ( ProgressTask , Table ) > ( ) ;
109+
110+ foreach ( var e in m_client . Engines ) {
111+ var t = ctx . AddTask ( $ "{ e } ") ;
112+ var tt = get_table ( e ) ;
113+ t . IsIndeterminate = true ;
114+ ptMap . Add ( e , ( t , tt ) ) ;
115+ }
116+
117+ var pt1 = ctx . AddTask ( "[yellow]Searching[/]" ) ;
118+ pt1 . IsIndeterminate = false ;
119+
120+ void OnComplete ( object sender , SearchResult [ ] searchResults )
121+ {
122+ pt1 . Increment ( COMPLETE ) ;
123+ }
103124
104- var resultsInner = await sc . RunSearchAsync ( q , cts . Token ) ;
125+ m_client . OnComplete += OnComplete ;
105126
106- return resultsInner ;
107- } ) ;
127+ pt1 . MaxValue = m_client . Engines . Length ;
108128
109- foreach ( SearchResult sr in results ) {
110- AnsiConsole . MarkupLine ( $ "[cyan][bold]{ sr . Engine . Name } [/][/]") ;
129+ void OnResult ( object sender , SearchResult sr )
130+ {
131+ m_results . Add ( sr ) ;
132+ ptMap [ sr . Engine ] . Item1 . Increment ( COMPLETE ) ;
133+ pt1 . Increment ( ( 1.0 ) ) ;
111134 int i = 0 ;
135+
136+ var t = ptMap [ sr . Engine ] . Item2 ;
137+
112138 foreach ( SearchResultItem sri in sr . Results ) {
113- AnsiConsole . MarkupLine ( $ "[link={ sri . Url } ]{ sr . Engine . Name } #{ i + 1 } [/]") ;
139+ t . Rows . Add ( new IRenderable [ ]
140+ {
141+ new Text ( $ "{ i + 1 } ") ,
142+ Markup . FromInterpolated ( $ "[link={ sri . Url } ]{ sr . Engine . Name } #{ i + 1 } [/]")
143+ } ) ;
144+
114145 i ++ ;
115146 }
147+
148+ // AnsiConsole.Write(t);
149+ }
150+
151+ m_client . OnResult += OnResult ;
152+
153+ var ttt = m_client . RunSearchAsync ( m_query , m_cts . Token ) ;
154+
155+ /*
156+ while (!pt1.IsFinished) { }*/
157+
158+ m_results2 = await ttt ;
159+
160+ /*var ld = AnsiConsole.Live(new Table()
161+ { });
162+ ld.StartAsync(async (x) =>
163+ {
164+ return;
165+ });*/
166+ // pt1.StopTask();
167+
168+ while ( ! pt1 . IsFinished || ptMap . Any ( s=> ! s . Value . Item1 . IsFinished ) ) {
169+ await Task . Delay ( TimeSpan . FromMilliseconds ( 100 ) ) ;
170+ }
171+
172+ AnsiConsole . Clear ( ) ;
173+
174+ foreach ( var vt in ptMap . Values ) {
175+ // vt.Item1.StopTask();
176+ AnsiConsole . Write ( vt . Item2 ) ;
116177 }
178+
117179 }
118180
119- public void Dispose ( ) { }
181+ private static Table get_table ( BaseSearchEngine bse )
182+ {
183+ var tt = new Table ( )
184+ {
185+ Border = TableBorder . Heavy ,
186+ Title = new ( $ "{ bse . Name } ") ,
187+ ShowFooters = true ,
188+ ShowHeaders = true ,
189+ } ;
190+
191+ tt . AddColumns ( new TableColumn ( "#" ) , new TableColumn ( "Link" ) ) ;
192+
193+ return tt ;
194+ }
195+
196+ public void Dispose ( )
197+ {
198+ m_results . Clear ( ) ;
199+ Array . Clear ( m_results2 ) ;
200+ m_cts . Dispose ( ) ;
201+ m_query . Dispose ( ) ;
202+ m_client . Dispose ( ) ;
203+ }
120204}
0 commit comments