Skip to content

Commit 62c45a6

Browse files
committed
Initial commit
0 parents  commit 62c45a6

67 files changed

Lines changed: 5785 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
using System;
2+
using System.Linq;
3+
using LibgenServer.Core.Entities;
4+
5+
namespace LibgenServer.Cli.CommandLine
6+
{
7+
internal class CommandLineParser
8+
{
9+
public ICommandLineParserResult Parse(string[] commandLineArguments)
10+
{
11+
if (commandLineArguments.Any())
12+
{
13+
switch (commandLineArguments[0].ToLowerInvariant())
14+
{
15+
case "db":
16+
case "database":
17+
return ParseDatabaseCommand(commandLineArguments.Skip(1).ToArray());
18+
case "configuration":
19+
case "config":
20+
return ParseConfigurationCommand(commandLineArguments.Skip(1).ToArray());
21+
case "import":
22+
return ParseImportCommand(commandLineArguments.Skip(1).ToArray());
23+
case "scan":
24+
return ParseScanCommand(commandLineArguments.Skip(1).ToArray());
25+
}
26+
}
27+
return new PrintUsageResult(PrintUsageResult.Usage.COMMAND_LIST);
28+
}
29+
30+
private ICommandLineParserResult ParseDatabaseCommand(string[] databaseCommandLineArguments)
31+
{
32+
if (databaseCommandLineArguments.Any())
33+
{
34+
switch (databaseCommandLineArguments[0].ToLowerInvariant())
35+
{
36+
case "create":
37+
return ParseDatabaseCreateCommand(databaseCommandLineArguments.Skip(1).ToArray());
38+
}
39+
}
40+
return new PrintUsageResult(PrintUsageResult.Usage.DATABASE);
41+
}
42+
43+
private ICommandLineParserResult ParseDatabaseCreateCommand(string[] databaseCreateCommandLineArguments)
44+
{
45+
if (databaseCreateCommandLineArguments.Length != 1)
46+
{
47+
int returnCode;
48+
if (databaseCreateCommandLineArguments.Length < 1)
49+
{
50+
Console.WriteLine("Error: path to the database file is not specified.");
51+
returnCode = 1;
52+
}
53+
else
54+
{
55+
Console.WriteLine("Error: too many arguments.");
56+
returnCode = 2;
57+
}
58+
return new PrintUsageResult(PrintUsageResult.Usage.DATABASE_CREATE, returnCode);
59+
}
60+
return new DatabaseCreateResult(databaseCreateCommandLineArguments[0]);
61+
}
62+
63+
private ICommandLineParserResult ParseConfigurationCommand(string[] configurationCommandLineArguments)
64+
{
65+
if (configurationCommandLineArguments.Any())
66+
{
67+
switch (configurationCommandLineArguments[0].ToLowerInvariant())
68+
{
69+
case "database":
70+
case "db":
71+
return ParseConfigurationDatabaseCommand(configurationCommandLineArguments.Skip(1).ToArray());
72+
}
73+
}
74+
return new PrintUsageResult(PrintUsageResult.Usage.CONFIGURATION);
75+
}
76+
77+
private ICommandLineParserResult ParseConfigurationDatabaseCommand(string[] configurationDatabaseCommandLineArguments)
78+
{
79+
if (configurationDatabaseCommandLineArguments.Length != 1)
80+
{
81+
int returnCode;
82+
if (configurationDatabaseCommandLineArguments.Length < 1)
83+
{
84+
Console.WriteLine("Error: path to the database file is not specified.");
85+
returnCode = 1;
86+
}
87+
else
88+
{
89+
Console.WriteLine("Error: too many arguments.");
90+
returnCode = 2;
91+
}
92+
return new PrintUsageResult(PrintUsageResult.Usage.CONFIGURATION_DATABASE, returnCode);
93+
}
94+
return new ConfigurationResult(configurationDatabaseCommandLineArguments[0]);
95+
}
96+
97+
private ICommandLineParserResult ParseImportCommand(string[] importCommandLineArguments)
98+
{
99+
if (importCommandLineArguments.Length != 2)
100+
{
101+
int returnCode;
102+
if (importCommandLineArguments.Length < 1)
103+
{
104+
Console.WriteLine("Error: import format is not specified.");
105+
returnCode = 1;
106+
}
107+
else if (importCommandLineArguments.Length < 2)
108+
{
109+
Console.WriteLine("Error: path to the file to import is not specified.");
110+
returnCode = 2;
111+
}
112+
else
113+
{
114+
Console.WriteLine("Error: too many arguments.");
115+
returnCode = 3;
116+
}
117+
return new PrintUsageResult(PrintUsageResult.Usage.IMPORT, returnCode);
118+
}
119+
string importFormatString = importCommandLineArguments[0];
120+
string importFilePath = importCommandLineArguments[1];
121+
ImportFormat? importFormat;
122+
switch (importFormatString.ToLowerInvariant())
123+
{
124+
case "libgen-nonfiction":
125+
importFormat = ImportFormat.LIBGEN_NONFICTION;
126+
break;
127+
default:
128+
importFormat = null;
129+
break;
130+
}
131+
if (!importFormat.HasValue)
132+
{
133+
Console.WriteLine($"Error: import format {importFormatString} is not supported.");
134+
return new PrintUsageResult(PrintUsageResult.Usage.IMPORT, 4);
135+
}
136+
return new ImportResult(importFormat.Value, importFilePath);
137+
}
138+
139+
private ICommandLineParserResult ParseScanCommand(string[] scanCommandLineArguments)
140+
{
141+
if (scanCommandLineArguments.Length != 2)
142+
{
143+
int returnCode;
144+
if (scanCommandLineArguments.Length < 1)
145+
{
146+
Console.WriteLine("Error: library is not specified.");
147+
returnCode = 1;
148+
}
149+
else if (scanCommandLineArguments.Length < 2)
150+
{
151+
Console.WriteLine("Error: path to the directory to scan is not specified.");
152+
returnCode = 2;
153+
}
154+
else
155+
{
156+
Console.WriteLine("Error: too many arguments.");
157+
returnCode = 3;
158+
}
159+
return new PrintUsageResult(PrintUsageResult.Usage.SCAN, returnCode);
160+
}
161+
string scanLibraryString = scanCommandLineArguments[0];
162+
string scanDirectoryPath = scanCommandLineArguments[1];
163+
ScanLibrary? scanLibrary;
164+
switch (scanLibraryString.ToLowerInvariant())
165+
{
166+
case "libgen-nonfiction":
167+
scanLibrary = ScanLibrary.LIBGEN_NONFICTION;
168+
break;
169+
default:
170+
scanLibrary = null;
171+
break;
172+
}
173+
if (!scanLibrary.HasValue)
174+
{
175+
Console.WriteLine($"Error: library {scanLibraryString} is not supported.");
176+
return new PrintUsageResult(PrintUsageResult.Usage.SCAN, 4);
177+
}
178+
return new ScanResult(scanLibrary.Value, scanDirectoryPath);
179+
}
180+
}
181+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using LibgenServer.Cli.Configuration;
2+
3+
namespace LibgenServer.Cli.CommandLine
4+
{
5+
internal class ConfigurationResult : ICommandLineParserResult
6+
{
7+
private readonly string databaseFilePath;
8+
9+
public ConfigurationResult(string databaseFilePath)
10+
{
11+
this.databaseFilePath = databaseFilePath;
12+
}
13+
14+
public int Execute()
15+
{
16+
ConfigurationOperations configurationOperations = new ConfigurationOperations();
17+
return configurationOperations.SetDatabaseFilePath(databaseFilePath);
18+
}
19+
}
20+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using LibgenServer.Cli.Database;
5+
6+
namespace LibgenServer.Cli.CommandLine
7+
{
8+
internal class DatabaseCreateResult : ICommandLineParserResult
9+
{
10+
private readonly DatabaseOperations databaseOperations;
11+
12+
public DatabaseCreateResult(string databaseFilePath)
13+
{
14+
databaseOperations = new DatabaseOperations(databaseFilePath);
15+
}
16+
17+
public int Execute()
18+
{
19+
return databaseOperations.CreateDatabase();
20+
}
21+
}
22+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace LibgenServer.Cli.CommandLine
2+
{
3+
internal interface ICommandLineParserResult
4+
{
5+
int Execute();
6+
}
7+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using LibgenServer.Cli.Import;
2+
using LibgenServer.Core.Entities;
3+
4+
namespace LibgenServer.Cli.CommandLine
5+
{
6+
internal class ImportResult : ICommandLineParserResult
7+
{
8+
private readonly ImportFormat importFormat;
9+
private readonly string importFilePath;
10+
11+
public ImportResult(ImportFormat importFormat, string importFilePath)
12+
{
13+
this.importFormat = importFormat;
14+
this.importFilePath = importFilePath;
15+
}
16+
17+
public int Execute()
18+
{
19+
ImportOperations importOperations = new ImportOperations(importFormat, importFilePath);
20+
return importOperations.Import();
21+
}
22+
}
23+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
6+
namespace LibgenServer.Cli.CommandLine
7+
{
8+
internal class PrintUsageResult : ICommandLineParserResult
9+
{
10+
internal enum Usage
11+
{
12+
COMMAND_LIST,
13+
DATABASE,
14+
DATABASE_CREATE,
15+
CONFIGURATION,
16+
CONFIGURATION_DATABASE,
17+
IMPORT,
18+
SCAN
19+
}
20+
21+
private readonly Usage usage;
22+
private readonly int returnCode;
23+
private readonly string executableName;
24+
private bool needEmptyLine;
25+
26+
public PrintUsageResult(Usage usage, int returnCode = 0)
27+
{
28+
this.usage = usage;
29+
this.returnCode = returnCode;
30+
executableName = Assembly.GetExecutingAssembly().GetName().Name;
31+
needEmptyLine = false;
32+
}
33+
34+
public int Execute()
35+
{
36+
switch (usage)
37+
{
38+
case Usage.COMMAND_LIST:
39+
PrintAppName();
40+
PrintUsage("<command> [<command arguments>]");
41+
PrintCommandsHeader();
42+
PrintKeyValuePairs(new[] {
43+
KeyValuePair.Create("config", "Alias for configuration command"),
44+
KeyValuePair.Create("configuration", "Configuration management"),
45+
KeyValuePair.Create("database", "Database operations"),
46+
KeyValuePair.Create("db", "Alias for database command"),
47+
KeyValuePair.Create("import", "Import a database dump"),
48+
KeyValuePair.Create("scan", "Scan local files and add them to the library")
49+
});
50+
break;
51+
case Usage.DATABASE:
52+
PrintAppName();
53+
PrintUsage("database <command> [<command arguments>]");
54+
PrintCommandsHeader();
55+
PrintKeyValuePairs(new[] {
56+
KeyValuePair.Create("create", "Create a new database")
57+
});
58+
break;
59+
case Usage.DATABASE_CREATE:
60+
PrintUsage("database create <path to a new database file>");
61+
break;
62+
case Usage.CONFIGURATION:
63+
PrintAppName();
64+
PrintUsage("configuration <option> <value>");
65+
PrintOptionsHeader();
66+
PrintKeyValuePairs(new[] {
67+
KeyValuePair.Create("database", "Path to the database file"),
68+
KeyValuePair.Create("db", "Alias for database option")
69+
});
70+
break;
71+
case Usage.CONFIGURATION_DATABASE:
72+
PrintUsage("database configuration database <path to the database file>");
73+
break;
74+
case Usage.IMPORT:
75+
Console.WriteLine();
76+
PrintUsage("import <format> <path to the file to import>");
77+
Console.WriteLine();
78+
Console.WriteLine("Supported formats:");
79+
PrintKeyValuePairs(new[] {
80+
KeyValuePair.Create("libgen-nonfiction", "Library Genesis MySQL dump for the non-fiction books (unpacked sql or a zip/rar/gz/7z archive)")
81+
});
82+
break;
83+
case Usage.SCAN:
84+
Console.WriteLine();
85+
PrintUsage("scan <library> <path to the directory to scan>");
86+
Console.WriteLine();
87+
Console.WriteLine("Supported libraries:");
88+
PrintKeyValuePairs(new[] {
89+
KeyValuePair.Create("libgen-nonfiction", "Library Genesis non-fiction books")
90+
});
91+
break;
92+
}
93+
return returnCode;
94+
}
95+
96+
private void PrintAppName()
97+
{
98+
Console.WriteLine("LibgenServer command-line tools 0.1 alpha");
99+
needEmptyLine = true;
100+
}
101+
102+
private void PrintUsage(string commandFormat)
103+
{
104+
PrintEmptyLineIfNeeded();
105+
Console.WriteLine($"Usage: {executableName} {commandFormat}");
106+
needEmptyLine = true;
107+
}
108+
109+
private void PrintCommandsHeader()
110+
{
111+
PrintEmptyLineIfNeeded();
112+
Console.WriteLine("Available commands:");
113+
needEmptyLine = false;
114+
}
115+
116+
private void PrintOptionsHeader()
117+
{
118+
PrintEmptyLineIfNeeded();
119+
Console.WriteLine("Available options:");
120+
needEmptyLine = false;
121+
}
122+
123+
private void PrintKeyValuePairs(IEnumerable<KeyValuePair<string, string>> keyValuePairs)
124+
{
125+
int maxKeyNameLength = keyValuePairs.Max(command => command.Key.Length);
126+
foreach (KeyValuePair<string, string> keyValuePair in keyValuePairs)
127+
{
128+
Console.WriteLine($" {keyValuePair.Key}{new string(' ', maxKeyNameLength - keyValuePair.Key.Length + 2)}{keyValuePair.Value}");
129+
}
130+
}
131+
132+
private void PrintEmptyLineIfNeeded()
133+
{
134+
if (needEmptyLine)
135+
{
136+
Console.WriteLine();
137+
}
138+
}
139+
}
140+
}

0 commit comments

Comments
 (0)