diff --git a/.vscode/launch.json b/.vscode/launch.json index 1e8f990..b6f08f4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,7 @@ "name": "Build & Debug DUB project", "cwd": "${command:dubWorkingDirectory}", "program": "bin/${command:dubTarget}", - "args": ["./data/database.db", "./data/sample.test"] + "args": ["~/Documents/Programming/Repositories/dlang/shkolaspo/data/database.db", "./data/pic.test"] } ] } diff --git a/data/pic.test b/data/pic.test new file mode 100644 index 0000000..772d048 --- /dev/null +++ b/data/pic.test @@ -0,0 +1,19 @@ +# Тема +? Первый вопрос +* 1.png +- Ответ 1 +- Ответ 2 ++ Ответ 3 +- Ответ 4 +? Второй вопрос +* 2.png +- Ответ 1 ++ Ответ 2 +- Ответ 3 +- Ответ 4 +? Третий вопрос +* 3.jpg ++ Ответ 1 +- Ответ 2 +- Ответ 3 +- Ответ 4 diff --git a/images/1.png b/images/1.png new file mode 100644 index 0000000..185ce09 Binary files /dev/null and b/images/1.png differ diff --git a/images/2.png b/images/2.png new file mode 100644 index 0000000..d84aa95 Binary files /dev/null and b/images/2.png differ diff --git a/images/3.jpg b/images/3.jpg new file mode 100644 index 0000000..96ce37e Binary files /dev/null and b/images/3.jpg differ diff --git a/source/app.d b/source/app.d index aa19f90..9f9a533 100644 --- a/source/app.d +++ b/source/app.d @@ -1,7 +1,7 @@ import singlog; 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.sql; @@ -15,6 +15,8 @@ enum { GROUP_ANSWER_TEXT = 15, GROUP_ANSWER_RIGHT = 17, GROUP_ANSWER_RIGHT_TEXT = 20, + GROUP_IMAGE = 22, + GROUP_IMAGE_NAME = 25, } int main(string[] args) @@ -23,6 +25,8 @@ int main(string[] args) .output(log.output.stdout.stderr) .color(true); + const string pictures = "./images"; + string testFilePath; string databaseFile; @@ -35,7 +39,7 @@ int main(string[] args) testFilePath = args[2]; 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; @@ -70,17 +74,35 @@ int main(string[] args) int number; string text; Answer[int] answers; + bool hasPicture; + ubyte[] picture; + string pictureName; + int pictureSize; ulong count() { return answers.length; } 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) { - 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) return false; @@ -128,6 +150,9 @@ int main(string[] args) foreach (question; this.questions.byKeyValue.array.sort!((a, b) => a.key < b.key)) { 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())); 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)); @@ -146,9 +171,8 @@ int main(string[] args) if (!error) { foreach (question; this.questions.byKeyValue.array.sort!((a, b) => a.key < b.key)) { if (!question.value.isValid()) { - writeln("Вопрос №%d \"%s\" содержит недостаточное количество ответов: %d".format( - question.key, question.value.text, question.value.count() - )); + writeln("Вопрос №%d \"%s\" содержит недостаточное количество ответов (%d) или большой (> 256 kB) размер изображения (%d kB)" + .format(question.key, question.value.text, question.value.count(), question.value.pictureSize)); error = true; } @@ -208,6 +232,23 @@ int main(string[] args) theme.questions[numQuestion].answers[++numAnswer] = Answer(numAnswer, match[GROUP_ANSWER_RIGHT_TEXT], true); 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(); diff --git a/source/sql.d b/source/sql.d index c30ce93..50fce50 100644 --- a/source/sql.d +++ b/source/sql.d @@ -2,6 +2,7 @@ module source.sql; import singlog; import std.conv; +import arsd.sqlite; import source.dblite; @@ -20,12 +21,28 @@ int sqlAddNewTheme(string topic) { 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 { - auto queryResult = dblite.sql( - "insert into questions (topic_id, number, text) values (?, ?, ?) returning id", - topic_id, question_number, question_text - ); + 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", + topic_id, question_number, question_text + ); + if (!queryResult.empty()) return queryResult.front()["id"].to!int; } catch (Exception e) {