2
2
using CommandLine . Text ;
3
3
using ImageComparison . Models ;
4
4
using ImageComparison . Services ;
5
- using Microsoft . CodeAnalysis . CSharp . Syntax ;
6
- using System . IO ;
7
5
using System . Reflection ;
8
6
9
7
namespace ImageComparison
@@ -15,6 +13,22 @@ internal class Program
15
13
public static bool force = false ;
16
14
public static ProgressBar ? progress = null ;
17
15
16
+ private static readonly List < string > preOptions =
17
+ new List < string > ( ) {
18
+ "\n \n USAGE:" ,
19
+ $ "\n { Assembly . GetExecutingAssembly ( ) . GetName ( ) . Name } .exe [options...]",
20
+ "\n \n OPTIONS:" ,
21
+ } ;
22
+ private static readonly List < string > postOptions = new List < string > ( )
23
+ {
24
+ "EXIT CODES:" ,
25
+ "" ,
26
+ " 0 - Success" ,
27
+ " 1 - General Error" ,
28
+ " 11 - Warning" ,
29
+ " 127 - Bad Request"
30
+ } ;
31
+
18
32
public static int Main ( string [ ] args )
19
33
{
20
34
ParserResult < Options > parser = new Parser ( with => {
@@ -29,6 +43,53 @@ public static int Main(string[] args)
29
43
LogService . OnLog += OnLog ;
30
44
CompareService . OnProgress += OnProgress ;
31
45
46
+ // custom validation
47
+ List < string > customErrors = new ( ) ;
48
+
49
+ if ( options . Processors . Count ( ) == 0 && ( options . Action == Models . Action . Move || options . Action == Models . Action . Bin || options . Action == Models . Action . Delete ) )
50
+ customErrors . Add ( $ "Required option 'p, processors' missing on action '{ options . Action } '") ;
51
+
52
+ if ( options . Similarity < 0 || options . Similarity > 10000 )
53
+ customErrors . Add ( "Option 's, similarity' is out of range. Valid 0 - 10000" ) ;
54
+
55
+ if ( options . HashDetail <= 0 || options . HashDetail >= 10 )
56
+ customErrors . Add ( "Option 'd, detail' is out of range. Valid 1 - 99" ) ;
57
+
58
+ if ( options . Target . Length == 0 && options . Action == Models . Action . Move )
59
+ customErrors . Add ( $ "Required option 't, target' missing on action '{ options . Action } '") ;
60
+
61
+ if ( options . Cache . Length == 0 && options . Action == Models . Action . NoMatch )
62
+ customErrors . Add ( $ "Required option 'c, cache' missing on action '{ options . Action } '") ;
63
+
64
+ if ( customErrors . Count > 0 )
65
+ {
66
+ ParserResult < Options > errorParser = new Parser ( with =>
67
+ {
68
+ with . HelpWriter = null ;
69
+ } ) . ParseArguments < Options > ( new string [ ] { "--help" } ) ;
70
+
71
+ List < string > customErrorsText = new ( )
72
+ {
73
+ "\n \n ERROR(S):"
74
+ } ;
75
+ customErrorsText . AddRange ( customErrors . Select ( e => " " + e ) ) ;
76
+ customErrorsText . AddRange ( preOptions ) ;
77
+
78
+ errorParser . WithNotParsed ( error =>
79
+ {
80
+ Console . WriteLine (
81
+ HelpText . AutoBuild ( errorParser , h =>
82
+ {
83
+ h . AddEnumValuesToHelpText = false ;
84
+ return h ;
85
+ } )
86
+ . AddPreOptionsLines ( customErrorsText )
87
+ . AddPostOptionsLines ( postOptions )
88
+ ) ;
89
+ } ) ;
90
+ return ;
91
+ }
92
+
32
93
try
33
94
{
34
95
string hashVersion = HashService . GetIdentifier ( options . HashDetail , options . HashAlgorithm ) ;
@@ -37,9 +98,12 @@ public static int Main(string[] args)
37
98
options . Locations = options . Locations . Select ( l => Path . IsPathRooted ( l ) ? l : Path . Combine ( Assembly . GetExecutingAssembly ( ) . Location , l ) ) ;
38
99
List < List < FileInfo > > searchLocations = FileService . SearchProcessableFiles ( options . Locations . ToArray ( ) , options . Recursive ) ;
39
100
40
- FileService . DataDirectory = Path . IsPathRooted ( options . Cache ) ? options . Cache : Path . Combine ( Assembly . GetExecutingAssembly ( ) . Location , Path . GetDirectoryName ( options . Cache ) ?? ".\\ " ) ;
101
+ FileService . DataDirectory = Path . IsPathRooted ( options . Cache ) ? ( Path . GetDirectoryName ( options . Cache ) ?? FileService . DataDirectory ) : Path . Combine ( Assembly . GetExecutingAssembly ( ) . Location , Path . GetDirectoryName ( options . Cache ) ?? ".\\ " ) ;
41
102
FileService . CacheFile = Path . GetFileName ( options . Cache ) . NullIfEmpty ( ) ?? FileService . CacheFile ;
103
+ if ( options . Cache . Length >= 1 )
104
+ CacheService . Init ( ) ;
42
105
List < CacheItem > cachedAnalysis = options . Cache . Length >= 1 ? CacheService . GetImages ( hashVersion ) : new ( ) ;
106
+
43
107
List < List < ImageAnalysis > > analysedImages = CompareService . AnalyseImages ( searchLocations , options . HashDetail , options . HashAlgorithm , cachedAnalysis ) ;
44
108
if ( options . Cache . Length >= 1 )
45
109
CacheService . UpdateImages ( analysedImages . SelectMany ( i => i ) . ToList ( ) , hashVersion , scantime ) ;
@@ -73,6 +137,8 @@ public static int Main(string[] args)
73
137
{
74
138
case Models . Action . Move :
75
139
deleteAction = DeleteAction . Move ;
140
+ if ( ! options . Target . EndsWith ( "\\ " ) && ! options . Target . EndsWith ( "/" ) )
141
+ options . Target += "\\ " ;
76
142
break ;
77
143
case Models . Action . Delete :
78
144
deleteAction = DeleteAction . Delete ;
@@ -107,7 +173,7 @@ public static int Main(string[] args)
107
173
try
108
174
{
109
175
processedFiles . Add ( image . Image . FullName ) ;
110
- FileService . DeleteFile ( m . Image1 . Image . FullName , deleteAction , options . Target , Path . IsPathRooted ( options . Target ) ) ;
176
+ FileService . DeleteFile ( image . Image . FullName , deleteAction , options . Target , ! Path . IsPathRooted ( options . Target ) ) ;
111
177
}
112
178
catch { }
113
179
}
@@ -130,7 +196,15 @@ public static int Main(string[] args)
130
196
} )
131
197
. WithNotParsed ( errors =>
132
198
{
133
- DisplayHelp ( parser ) ;
199
+ Console . WriteLine (
200
+ HelpText . AutoBuild ( parser , h =>
201
+ {
202
+ h . AddEnumValuesToHelpText = false ;
203
+ return h ;
204
+ } )
205
+ . AddPreOptionsLines ( preOptions )
206
+ . AddPostOptionsLines ( postOptions )
207
+ ) ;
134
208
135
209
if ( ! errors . Any ( e => e . GetType ( ) == typeof ( HelpRequestedError ) ) )
136
210
{
@@ -156,6 +230,9 @@ public static void OnProgress(object? sender, ImageComparerEventArgs e)
156
230
}
157
231
}
158
232
233
+ /*
234
+ * Log implementation for console output
235
+ */
159
236
private static void OnLog ( object ? sender , LogEventArgs logEvent )
160
237
{
161
238
if ( logLevel <= logEvent . Log . LogLevel )
@@ -182,35 +259,5 @@ private static string ToLiteral(string valueTextForCompiler)
182
259
{
183
260
return Microsoft . CodeAnalysis . CSharp . SymbolDisplay . FormatLiteral ( valueTextForCompiler , false ) ;
184
261
}
185
-
186
- private static void DisplayHelp < T > ( ParserResult < T > result )
187
- {
188
- Console . WriteLine (
189
- HelpText . AutoBuild ( result , h =>
190
- {
191
- h . AddEnumValuesToHelpText = false ;
192
- return h ;
193
- } )
194
- . AddPreOptionsLines (
195
- new List < string > ( )
196
- {
197
- "\n \n USAGE:" ,
198
- $ "\n { Assembly . GetExecutingAssembly ( ) . GetName ( ) . Name } .exe [options...]",
199
- "\n \n OPTIONS:"
200
- }
201
- )
202
- . AddPostOptionsLines (
203
- new List < string > ( )
204
- {
205
- "EXIT CODES:" ,
206
- "" ,
207
- " 0 - Success" ,
208
- " 1 - General Error" ,
209
- " 11 - Warning" ,
210
- " 127 - Bad Request"
211
- }
212
- )
213
- ) ;
214
- }
215
262
}
216
263
}
0 commit comments