Добавлена поддержка изображений

This commit is contained in:
Alexander Zhirov 2024-02-17 21:47:20 +03:00
parent 74b33f455c
commit adf921162d
7 changed files with 90 additions and 13 deletions

2
.vscode/launch.json vendored
View File

@ -11,7 +11,7 @@
"name": "Build & Debug DUB project", "name": "Build & Debug DUB project",
"cwd": "${command:dubWorkingDirectory}", "cwd": "${command:dubWorkingDirectory}",
"program": "bin/${command:dubTarget}", "program": "bin/${command:dubTarget}",
"args": ["./data/database.db", "./data/sample.test"] "args": ["~/Documents/Programming/Repositories/dlang/shkolaspo/data/database.db", "./data/pic.test"]
} }
] ]
} }

19
data/pic.test Normal file
View File

@ -0,0 +1,19 @@
# Тема
? Первый вопрос
* 1.png
- Ответ 1
- Ответ 2
+ Ответ 3
- Ответ 4
? Второй вопрос
* 2.png
- Ответ 1
+ Ответ 2
- Ответ 3
- Ответ 4
? Третий вопрос
* 3.jpg
+ Ответ 1
- Ответ 2
- Ответ 3
- Ответ 4

BIN
images/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
images/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
images/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -1,7 +1,7 @@
import singlog; import singlog;
import core.stdc.stdlib : exit, EXIT_SUCCESS, EXIT_FAILURE; import core.stdc.stdlib : exit, EXIT_SUCCESS, EXIT_FAILURE;
import std.stdio, std.conv, std.path, std.file, std.format, std.regex, std.array, std.algorithm; import std.stdio, std.conv, std.path, std.file, std.format, std.regex, std.array, std.algorithm, std.uuid;
import source.database; import source.database;
import source.sql; import source.sql;
@ -15,6 +15,8 @@ enum {
GROUP_ANSWER_TEXT = 15, GROUP_ANSWER_TEXT = 15,
GROUP_ANSWER_RIGHT = 17, GROUP_ANSWER_RIGHT = 17,
GROUP_ANSWER_RIGHT_TEXT = 20, GROUP_ANSWER_RIGHT_TEXT = 20,
GROUP_IMAGE = 22,
GROUP_IMAGE_NAME = 25,
} }
int main(string[] args) int main(string[] args)
@ -23,6 +25,8 @@ int main(string[] args)
.output(log.output.stdout.stderr) .output(log.output.stdout.stderr)
.color(true); .color(true);
const string pictures = "./images";
string testFilePath; string testFilePath;
string databaseFile; string databaseFile;
@ -35,7 +39,7 @@ int main(string[] args)
testFilePath = args[2]; testFilePath = args[2];
const string pattern = "^((( |\\t)*\\#( |\\t)*)(.*[^\\s]))|((( |\\t)*\\?( |\\t)*)(.*[^\\s]))" const string pattern = "^((( |\\t)*\\#( |\\t)*)(.*[^\\s]))|((( |\\t)*\\?( |\\t)*)(.*[^\\s]))"
~ "|((( |\\t)*-( |\\t)*)(.*[^\\s]))|((( |\\t)*\\+( |\\t)*)(.*[^\\s]))$"; ~ "|((( |\\t)*-( |\\t)*)(.*[^\\s]))|((( |\\t)*\\+( |\\t)*)(.*[^\\s]))|((( |\\t)*\\*( |\\t)*)(.*[^\\s]))$";
File testFile; File testFile;
@ -70,17 +74,35 @@ int main(string[] args)
int number; int number;
string text; string text;
Answer[int] answers; Answer[int] answers;
bool hasPicture;
ubyte[] picture;
string pictureName;
int pictureSize;
ulong count() { ulong count() {
return answers.length; return answers.length;
} }
bool isValid() { bool isValid() {
return answers.length > 1; bool error = false;
if (answers.length <= 1)
error = true;
if (hasPicture && pictureSize > 256)
error = true;
return !error;
} }
bool addToDB(int topic_id) { bool addToDB(int topic_id) {
int id = sqlAddNewQuestion(topic_id, this.number, this.text); int id = sqlAddNewQuestion(
topic_id,
this.number,
this.text,
this.hasPicture,
this.picture,
this.pictureName);
if (!id) if (!id)
return false; return false;
@ -128,6 +150,9 @@ int main(string[] args)
foreach (question; this.questions.byKeyValue.array.sort!((a, b) => a.key < b.key)) { foreach (question; this.questions.byKeyValue.array.sort!((a, b) => a.key < b.key)) {
writeln("\tВопрос №%d: %s".format(question.key, question.value.text)); writeln("\tВопрос №%d: %s".format(question.key, question.value.text));
if (question.value.hasPicture)
writeln("\tСодержит изображение: %s (%d kB)"
.format(question.value.pictureName, question.value.pictureSize));
writeln("\tКоличество ответов: %d".format(question.value.count())); writeln("\tКоличество ответов: %d".format(question.value.count()));
foreach (answer; question.value.answers.byKeyValue.array.sort!((a, b) => a.key < b.key)) { foreach (answer; question.value.answers.byKeyValue.array.sort!((a, b) => a.key < b.key)) {
writeln("\t\tОтвет №%d: %s".format(answer.key, answer.value.text)); writeln("\t\tОтвет №%d: %s".format(answer.key, answer.value.text));
@ -146,9 +171,8 @@ int main(string[] args)
if (!error) { if (!error) {
foreach (question; this.questions.byKeyValue.array.sort!((a, b) => a.key < b.key)) { foreach (question; this.questions.byKeyValue.array.sort!((a, b) => a.key < b.key)) {
if (!question.value.isValid()) { if (!question.value.isValid()) {
writeln("Вопрос №%d \"%s\" содержит недостаточное количество ответов: %d".format( writeln("Вопрос №%d \"%s\" содержит недостаточное количество ответов (%d) или большой (> 256 kB) размер изображения (%d kB)"
question.key, question.value.text, question.value.count() .format(question.key, question.value.text, question.value.count(), question.value.pictureSize));
));
error = true; error = true;
} }
@ -208,6 +232,23 @@ int main(string[] args)
theme.questions[numQuestion].answers[++numAnswer] = Answer(numAnswer, match[GROUP_ANSWER_RIGHT_TEXT], true); theme.questions[numQuestion].answers[++numAnswer] = Answer(numAnswer, match[GROUP_ANSWER_RIGHT_TEXT], true);
continue; continue;
} }
if (match[GROUP_IMAGE].length)
{
string currentPicture = buildPath(pictures, match[GROUP_IMAGE_NAME]);
if (currentPicture.exists) {
auto picFile = File(currentPicture, "r");
theme.questions[numQuestion].hasPicture = true;
theme.questions[numQuestion].picture = cast(ubyte[])read(currentPicture);
theme.questions[numQuestion].pictureName =
md5UUID(theme.questions[numQuestion].picture).to!string ~ currentPicture.extension;
theme.questions[numQuestion].pictureSize = picFile.size().to!int / 1024;
} else {
log.e("Файл \"%s\" не найден".format(currentPicture));
}
continue;
}
} }
// theme.print(); // theme.print();

View File

@ -2,6 +2,7 @@ module source.sql;
import singlog; import singlog;
import std.conv; import std.conv;
import arsd.sqlite;
import source.dblite; import source.dblite;
@ -20,12 +21,28 @@ int sqlAddNewTheme(string topic) {
return 0; return 0;
} }
int sqlAddNewQuestion(int topic_id, int question_number, string question_text) { int sqlAddNewQuestion(
int topic_id,
int question_number,
string question_text,
bool question_has_picture,
ubyte[] question_picture,
string question_picture_name
) {
SqliteResult queryResult;
try { try {
auto queryResult = dblite.sql( if (question_has_picture)
queryResult = dblite.sql(
"insert into questions (topic_id, number, text, picture_name, picture)
values (?, ?, ?, ?, ?) returning id",
topic_id, question_number, question_text, question_picture_name, question_picture
);
else
queryResult = dblite.sql(
"insert into questions (topic_id, number, text) values (?, ?, ?) returning id", "insert into questions (topic_id, number, text) values (?, ?, ?) returning id",
topic_id, question_number, question_text topic_id, question_number, question_text
); );
if (!queryResult.empty()) if (!queryResult.empty())
return queryResult.front()["id"].to!int; return queryResult.front()["id"].to!int;
} catch (Exception e) { } catch (Exception e) {