From 14f2e9696c6102c0dec444e4009321cda30013e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9=20=D0=A1=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Wed, 3 May 2023 20:20:16 +0300 Subject: [PATCH 1/8] Add tests for http client --- CMakeLists.txt | 53 +++- client/CMakeLists.txt | 15 + client/cmd/CMakeLists.txt | 0 client/internal/CMakeLists.txt | 8 + client/internal/entities/CMakeLists.txt | 19 ++ client/internal/entities/include/Metric.h | 11 + client/internal/entities/include/Solution.h | 58 ++++ client/internal/entities/include/Task.h | 23 ++ client/internal/entities/include/User.h | 38 +++ client/internal/entities/src/Solution.cpp | 73 +++++ client/internal/entities/src/Task.cpp | 21 ++ client/internal/entities/src/User.cpp | 43 +++ client/internal/httpClient/CMakeLists.txt | 21 ++ .../internal/httpClient/include/ClientTypes.h | 34 +++ .../internal/httpClient/include/HttpClient.h | 41 +++ .../httpClient/include/HttpClientManager.h | 33 +++ .../internal/httpClient/include/Serializer.h | 14 + client/internal/httpClient/src/HttpClient.cpp | 32 +++ .../httpClient/src/HttpClientManager.cpp | 42 +++ .../internal/httpClient/tests/CMakeLists.txt | 16 ++ .../tests/HttpClientManagerSuite.cpp | 64 +++++ .../httpClient/tests/HttpClientSuite.cpp | 11 + client/internal/httpClient/tests/main.cpp | 8 + .../internal/httpClient/virtual/IHttpClient.h | 32 +++ server/CMakeLists.txt | 0 src/main.cpp | 264 ------------------ text-basic-metrics/code1.txt | 29 -- text-basic-metrics/code2.txt | 29 -- text-basic-metrics/tbm_main.cpp | 153 ---------- 29 files changed, 696 insertions(+), 489 deletions(-) create mode 100644 client/CMakeLists.txt create mode 100644 client/cmd/CMakeLists.txt create mode 100644 client/internal/CMakeLists.txt create mode 100644 client/internal/entities/CMakeLists.txt create mode 100644 client/internal/entities/include/Metric.h create mode 100644 client/internal/entities/include/Solution.h create mode 100644 client/internal/entities/include/Task.h create mode 100644 client/internal/entities/include/User.h create mode 100644 client/internal/entities/src/Solution.cpp create mode 100644 client/internal/entities/src/Task.cpp create mode 100644 client/internal/entities/src/User.cpp create mode 100644 client/internal/httpClient/CMakeLists.txt create mode 100644 client/internal/httpClient/include/ClientTypes.h create mode 100644 client/internal/httpClient/include/HttpClient.h create mode 100644 client/internal/httpClient/include/HttpClientManager.h create mode 100644 client/internal/httpClient/include/Serializer.h create mode 100644 client/internal/httpClient/src/HttpClient.cpp create mode 100644 client/internal/httpClient/src/HttpClientManager.cpp create mode 100644 client/internal/httpClient/tests/CMakeLists.txt create mode 100644 client/internal/httpClient/tests/HttpClientManagerSuite.cpp create mode 100644 client/internal/httpClient/tests/HttpClientSuite.cpp create mode 100644 client/internal/httpClient/tests/main.cpp create mode 100644 client/internal/httpClient/virtual/IHttpClient.h create mode 100644 server/CMakeLists.txt delete mode 100644 src/main.cpp delete mode 100644 text-basic-metrics/code1.txt delete mode 100644 text-basic-metrics/code2.txt delete mode 100644 text-basic-metrics/tbm_main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5054100..23aba3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,15 +1,40 @@ -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) cmake_minimum_required(VERSION 3.16) -set(CMAKE_PREFIX_PATH build) -project(SourcedOut CXX) -# find_package(antlr4-runtime REQUIRED) -find_package(Boost 1.8.1 REQUIRED) -# find_package(libpqxx REQUIRED) -find_package(GTest REQUIRED) -set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) -message(STATUS ${Boost_LIBRARIES}) -set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-lpthread -pthread") -add_executable(${PROJECT_NAME} src/main.cpp) -#add_executable(${PROJECT_NAME} text-basic-metrics/tbm_main.cpp text-basic-metrics/tbm_main.cpp) строка для запуска моей части в text-basic-metrics -target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${antlr4-runtime_LIBRARIES} ${libpqxx_LIBRARIES} ${GTest_LIBRARIES}) \ No newline at end of file + +set(PROJECT_NAME "SourcedOut") + +project(${PROJECT_NAME}) + + +set(BUILD_DEV TRUE CACHE BOOL "build dev version") +set(SANITIZE_BUILD TRUE CACHE BOOL "build with sanitizers") + +if(BUILD_DEV) + enable_testing() + message("Building dev version") + # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -O0 -fprofile-arcs -ftest-coverage") + # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ + # -Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align -lpq -lpqxx") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage -lgcov") + + if(SANITIZE_BUILD) + message("Sanitizers ON") + # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined -fno-sanitize-recover=all -fsanitize-undefined-trap-on-error") + endif(SANITIZE_BUILD) +endif(BUILD_DEV) + +set(BUILD_SERVER "BUILD_SERVER") +set(BUILD_CLIENT "BUILD_CLIENT") +set(BUILD_ALL "BUILD_ALL") + + +message("${BUILD_DEV} ${SANITIZE_BUILD} ${CMAKE_EXE_LINKER_FLAGS}") +set(BUILD_MODE ${BUILD_CLIENT}) + +if((BUILD_MODE STREQUAL ${BUILD_CLIENT}) OR (BUILD_MODE STREQUAL ${BUILD_ALL})) + add_subdirectory(client) +endif() + +if((BUILD_MODE STREQUAL ${BUILD_SERVER}) OR (BUILD_MODE STREQUAL ${BUILD_ALL})) + add_subdirectory(server) +endif() \ No newline at end of file diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt new file mode 100644 index 0000000..4147519 --- /dev/null +++ b/client/CMakeLists.txt @@ -0,0 +1,15 @@ +set(CMAKE_PREFIX_PATH build) +project(SourcedOut_client CXX) + +set(CMAKE_CXX_STANDARD 20) + +find_package(Boost 1.8.1 REQUIRED) +find_package(GTest REQUIRED) + +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) + +add_subdirectory(internal) +add_subdirectory(cmd) + +set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-lpthread -pthread") \ No newline at end of file diff --git a/client/cmd/CMakeLists.txt b/client/cmd/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/client/internal/CMakeLists.txt b/client/internal/CMakeLists.txt new file mode 100644 index 0000000..93fbed8 --- /dev/null +++ b/client/internal/CMakeLists.txt @@ -0,0 +1,8 @@ +add_subdirectory(entities) +add_subdirectory(httpClient) + +set(libClientEntities_LIB ${libClientEntities_LIB} PARENT_SCOPE) +set(libClientEntities_INCLUDE_DIRS ${libClientEntities_INCLUDE_DIRS} PARENT_SCOPE) + +set(HTTPCLIENT_lib_LIB ${HTTPCLIENT_lib_LIB} PARENT_SCOPE) +set(HTTPCLIENT_lib_INCLUDE_DIRS ${HTTPCLIENT_lib_INCLUDE_DIRS} PARENT_SCOPE) \ No newline at end of file diff --git a/client/internal/entities/CMakeLists.txt b/client/internal/entities/CMakeLists.txt new file mode 100644 index 0000000..4087519 --- /dev/null +++ b/client/internal/entities/CMakeLists.txt @@ -0,0 +1,19 @@ +project("ClientEntitiesLib") + +set(LIB_NAME libClientEntities) + +file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -O2 -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ +-Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align") + +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lboost_filesystem") + +add_library(${LIB_NAME} ${SOURCES} ${HEADERS}) +target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + +set(libClientEntities_LIB ${LIB_NAME}) +set(libClientEntities_LIB ${libClientEntities_LIB} PARENT_SCOPE) +set(libClientEntities_INCLUDE_DIRS ${LIB_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(libClientEntities_INCLUDE_DIRS ${libClientEntities_INCLUDE_DIRS} PARENT_SCOPE) \ No newline at end of file diff --git a/client/internal/entities/include/Metric.h b/client/internal/entities/include/Metric.h new file mode 100644 index 0000000..3ab8ea7 --- /dev/null +++ b/client/internal/entities/include/Metric.h @@ -0,0 +1,11 @@ +#ifndef SOURCEDOUT_METRIC_H +#define SOURCEDOUT_METRIC_H + +#include + +struct Metric { + std::string name; + unsigned int value; +}; + +#endif //SOURCEDOUT_METRIC_H diff --git a/client/internal/entities/include/Solution.h b/client/internal/entities/include/Solution.h new file mode 100644 index 0000000..6282f47 --- /dev/null +++ b/client/internal/entities/include/Solution.h @@ -0,0 +1,58 @@ +#ifndef SOURCEDOUT_SOLUTION_HPP +#define SOURCEDOUT_SOLUTION_HPP + +#include +#include +#include + +class Solution { +public: + Solution() =default; + Solution(size_t id, std::string sendDate, size_t senderId, std::string source, + std::string tokens, std::string astTree, size_t taskId, std::string result); + + [[nodiscard]] size_t getId() const; + + + [[nodiscard]] const std::string &getSendDate() const; + + void setSendDate(const std::string &sendDate); + + [[nodiscard]] size_t getSenderId() const; + + void setSenderId(size_t senderId); + + [[nodiscard]] const std::string &getSource() const; + + void setSource(const std::string &source); + + [[nodiscard]] const std::string &getTokens() const; + + void setTokens(const std::string &tokens); + + [[nodiscard]] const std::string &getAstTree() const; + + void setAstTree(const std::string &astTree); + + [[nodiscard]] size_t getTaskId() const; + + void setTaskId(size_t taskId); + + [[nodiscard]] const std::string &getResult() const; + + void setResult(const std::string &result); + +private: + size_t id; + std::string send_date; + size_t sender_id; + std::string source; + std::string tokens; + std::string astTree; + size_t task_id; + std::string result; +public: + +}; + +#endif //SOURCEDOUT_SOLUTION_HPP \ No newline at end of file diff --git a/client/internal/entities/include/Task.h b/client/internal/entities/include/Task.h new file mode 100644 index 0000000..d51c17f --- /dev/null +++ b/client/internal/entities/include/Task.h @@ -0,0 +1,23 @@ +#ifndef SOURCEDOUT_TASK_HPP +#define SOURCEDOUT_TASK_HPP +#include +#include +class Task{ +private: + size_t id; + std::string description; + +public: + Task()=default; + ~Task() = default; + Task(size_t id, std::string description); + + explicit Task(std::string description); + + [[nodiscard]] size_t getId() const; + + [[nodiscard]] const std::string &getDescription() const; + + void setDescription(const std::string &description); +}; +#endif //SOURCEDOUT_TASK_HPP \ No newline at end of file diff --git a/client/internal/entities/include/User.h b/client/internal/entities/include/User.h new file mode 100644 index 0000000..5802df2 --- /dev/null +++ b/client/internal/entities/include/User.h @@ -0,0 +1,38 @@ +#ifndef SOURCEDOUT_USER_HPP + +#include +#include + +#define SOURCEDOUT_USER_HPP + +class User { +private: + size_t id; + std::string login; + std::string password; + std::string username; + +public: + User()=default; + User(size_t id_, std::string login_, std::string password_, std::string username_); + + User(std::string login_, std::string password_, std::string username_); + + [[nodiscard]] const std::string &getLogin() const; + + void setLogin(const std::string &login); + + [[nodiscard]] const std::string &getPassword() const; + + void setPassword(const std::string &password); + + [[nodiscard]] const std::string &getUsername() const; + + void setUsername(const std::string &username); + + [[nodiscard]] size_t getId() const; + + friend std::ostream &operator<<(std::ostream &os, const User &user); +}; + +#endif //SOURCEDOUT_USER_HPP \ No newline at end of file diff --git a/client/internal/entities/src/Solution.cpp b/client/internal/entities/src/Solution.cpp new file mode 100644 index 0000000..2e9b1e8 --- /dev/null +++ b/client/internal/entities/src/Solution.cpp @@ -0,0 +1,73 @@ + +#include +#include +#include "Solution.h" + +Solution::Solution(unsigned long id, std::string sendDate, unsigned long senderId, + std::string source, std::string tokens, + std::string astTree, unsigned long taskId, + std::string result) : id(id), send_date(std::move(sendDate)), sender_id(senderId), + source(std::move(source)), tokens(std::move(tokens)), + astTree(std::move(astTree)), + task_id(taskId), result(std::move(result)) {} + +size_t Solution::getId() const { + return id; +} + + +const std::string &Solution::getSendDate() const { + return send_date; +} + +void Solution::setSendDate(const std::string &sendDate) { + send_date = sendDate; +} + +size_t Solution::getSenderId() const { + return sender_id; +} + +void Solution::setSenderId(size_t senderId) { + sender_id = senderId; +} + +const std::string &Solution::getSource() const { + return source; +} + +void Solution::setSource(const std::string &source_) { + Solution::source = source_; +} + +const std::string &Solution::getTokens() const { + return tokens; +} + +void Solution::setTokens(const std::string &tokens_) { + Solution::tokens = tokens_; +} + +const std::string &Solution::getAstTree() const { + return astTree; +} + +void Solution::setAstTree(const std::string &astTree_) { + Solution::astTree = astTree_; +} + +size_t Solution::getTaskId() const { + return task_id; +} + +void Solution::setTaskId(size_t taskId) { + task_id = taskId; +} + +const std::string &Solution::getResult() const { + return result; +} + +void Solution::setResult(const std::string &result_) { + Solution::result = result_; +} \ No newline at end of file diff --git a/client/internal/entities/src/Task.cpp b/client/internal/entities/src/Task.cpp new file mode 100644 index 0000000..7dd9bfe --- /dev/null +++ b/client/internal/entities/src/Task.cpp @@ -0,0 +1,21 @@ +#pragma once + +#include "Task.h" +#include +#include + +unsigned long Task::getId() const { + return id; +} + +Task::Task(size_t id, std::string description) : id(id), description(std::move(description)) {} + +Task::Task(std::string description) : id(0), description(std::move(description)) {} + +const std::string &Task::getDescription() const { + return description; +} + +void Task::setDescription(const std::string &description_) { + Task::description = description_; +} \ No newline at end of file diff --git a/client/internal/entities/src/User.cpp b/client/internal/entities/src/User.cpp new file mode 100644 index 0000000..53706e2 --- /dev/null +++ b/client/internal/entities/src/User.cpp @@ -0,0 +1,43 @@ +#include +#include "User.h" + +User::User(size_t id_, std::string login_, std::string password_, std::string username_) : + id(id_), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { +} +User::User(std::string login_, std::string password_, std::string username_) : + id(0), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { +} + +const std::string &User::getLogin() const { + return login; +} + +void User::setLogin(const std::string &login_) { + User::login = login_; +} + +const std::string &User::getPassword() const { + return password; +} + +void User::setPassword(const std::string &password_) { + User::password = password_; +} + +const std::string &User::getUsername() const { + return username; +} + +void User::setUsername(const std::string &username_) { + User::username = username_; +} + +size_t User::getId() const { + return id; +} + +std::ostream &operator<<(std::ostream &os, const User &user) { + os << "id: " << user.id << " login: " << user.login << " password: " << user.password << " username: " + << user.username; + return os; +} \ No newline at end of file diff --git a/client/internal/httpClient/CMakeLists.txt b/client/internal/httpClient/CMakeLists.txt new file mode 100644 index 0000000..591e57a --- /dev/null +++ b/client/internal/httpClient/CMakeLists.txt @@ -0,0 +1,21 @@ +project("HttpClientLib") + +set(CMAKE_CXX_STANDARD 20) + +file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/virtual) +file(GLOB INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h ${CMAKE_CURRENT_SOURCE_DIR}/virtual/*.h) + +include_directories(${INCLUDE_DIRS} ${Boost_INCLUDE_DIR} ${libClientEntities_INCLUDE_DIRS}) + +add_library(${PROJECT_NAME} ${SOURCES} ${INCLUDES}) +target_link_libraries(${PROJECT_NAME} ${libClientEntities_LIB} ${Boost_LIBRARIES}) + +set(HTTPCLIENT_lib_LIB ${PROJECT_NAME}) +set(HTTPCLIENT_lib_LIB ${HTTPCLIENT_lib_LIB} PARENT_SCOPE) + +set(HTTPCLIENT_lib_INCLUDE_DIRS ${INCLUDE_DIRS}) +set(HTTPCLIENT_lib_INCLUDE_DIRS ${HTTPCLIENT_lib_INCLUDE_DIRS} PARENT_SCOPE) + +enable_testing() +add_subdirectory(tests) \ No newline at end of file diff --git a/client/internal/httpClient/include/ClientTypes.h b/client/internal/httpClient/include/ClientTypes.h new file mode 100644 index 0000000..9ba6e87 --- /dev/null +++ b/client/internal/httpClient/include/ClientTypes.h @@ -0,0 +1,34 @@ +#ifndef APP_HTTPCLIENT_HTTPCLIENT_CLIENTTYPES_H_ +#define APP_HTTPCLIENT_HTTPCLIENT_CLIENTTYPES_H_ + +#include +#include +#include +#include +#include + +using Response = boost::beast::http::response; +using Request = boost::beast::http::request; + +using Params = std::map; + +struct Header { + std::string name; + std::string values; +}; + +struct ResponseStruct { + unsigned int status; + std::string body; + std::vector
headers; +}; + +struct Host { + std::string domain; + std::string ip; + unsigned short port; + Host(std::string domain, std::string ip, unsigned short port) + : domain(std::move(domain)), ip(std::move(ip)), port(port) {} +}; + +#endif // APP_HTTPCLIENT_HTTPCLIENT_CLIENTTYPES_H_ diff --git a/client/internal/httpClient/include/HttpClient.h b/client/internal/httpClient/include/HttpClient.h new file mode 100644 index 0000000..99e7fb0 --- /dev/null +++ b/client/internal/httpClient/include/HttpClient.h @@ -0,0 +1,41 @@ +#ifndef APP_HTTPCLIENT_HTTPCLIENT_HTTPCLIENT_H_ +#define APP_HTTPCLIENT_HTTPCLIENT_HTTPCLIENT_H_ + +#include +#include +#include +#include + +#include "ClientTypes.h" +#include "Serializer.h" +#include "IHttpClient.h" + +class HttpClient : public IHttpClient { + public: + HttpClient(); + ResponseStruct makeGetRequest(const Host& host, const std::string& target, + const std::shared_ptr& params = nullptr, + const std::shared_ptr& headers = nullptr) override; + ResponseStruct makePostRequest(const Host& host, const std::string& target, + const std::shared_ptr& body, + const std::shared_ptr& headers = nullptr) override; + + private: + ResponseStruct parseResponse(Response response) override; + std::string createURL(const std::string& target, const std::shared_ptr& params = nullptr) override; + bool connect(unsigned short port) override; + ResponseStruct makeRequest(const Host& host, const std::string& target, boost::beast::http::verb method, + const std::shared_ptr& params = nullptr, + const std::shared_ptr& body = nullptr, + const std::shared_ptr& headers = nullptr) override; + + boost::asio::io_context context; + boost::asio::ip::tcp::resolver resolver; + boost::asio::ip::tcp::socket socket; + std::string ip; + boost::beast::flat_buffer flat_buffer; + Serializer serializer; +}; + + +#endif // APP_HTTPCLIENT_HTTPCLIENT_HTTPCLIENT_H_ diff --git a/client/internal/httpClient/include/HttpClientManager.h b/client/internal/httpClient/include/HttpClientManager.h new file mode 100644 index 0000000..1d31ce3 --- /dev/null +++ b/client/internal/httpClient/include/HttpClientManager.h @@ -0,0 +1,33 @@ +#ifndef APP_HTTPCLIENT_HTTPCLIENTMANAGER_HTTPCLIENTMANAGER_H_ +#define APP_HTTPCLIENT_HTTPCLIENTMANAGER_HTTPCLIENTMANAGER_H_ + +#include +#include +#include + +#include "IHttpClient.h" +#include "User.h" +#include "Solution.h" +#include "Task.h" +#include "Metric.h" + +class HttpClientManager { + public: + HttpClientManager(const std::string &domain, const std::string &ip, const unsigned short &port, + std::string saved_path_); + unsigned int loginUser(const std::string &login, const std::string &password); + unsigned int registerUser(const std::string &login, const std::string &username, const std::string &password); + unsigned int submitSolution(const int& user_id, const std::string &path_to_sound); + unsigned int getAllSolutionsForTask(const int& user_id, const int& task_id); + std::vector getAllTasks(); + std::vector getMetrics(const int& sol_id); + void setHttpClient(std::shared_ptr client_); + private: + std::string saved_path; + Host host; + std::shared_ptr client; + Serializer serializer; +}; + + +#endif // APP_HTTPCLIENT_HTTPCLIENTMANAGER_HTTPCLIENTMANAGER_H_ diff --git a/client/internal/httpClient/include/Serializer.h b/client/internal/httpClient/include/Serializer.h new file mode 100644 index 0000000..31d4468 --- /dev/null +++ b/client/internal/httpClient/include/Serializer.h @@ -0,0 +1,14 @@ +#ifndef APP_HTTPCLIENT_HTTPCLIENT_SERIALIZER_H_ +#define APP_HTTPCLIENT_HTTPCLIENT_SERIALIZER_H_ + +#include +#include +#include + +#include "ClientTypes.h" + +class Serializer {}; + + + +#endif // APP_HTTPCLIENT_HTTPCLIENT_SERIALIZER_H_ diff --git a/client/internal/httpClient/src/HttpClient.cpp b/client/internal/httpClient/src/HttpClient.cpp new file mode 100644 index 0000000..93881ff --- /dev/null +++ b/client/internal/httpClient/src/HttpClient.cpp @@ -0,0 +1,32 @@ +#include "httpClient.h" + +#include +#include +#include +#include +#include +#include + +using Error = boost::system::system_error; + +std::string HttpClient::createURL(const std::string& target, const std::shared_ptr& params) {} + +bool HttpClient::connect(unsigned short port = 80) {} + +HttpClient::HttpClient() : socket(context), resolver(context) {} + +ResponseStruct HttpClient::makeRequest(const Host &host, const std::string &target, + const boost::beast::http::verb method, + const std::shared_ptr& params, + const std::shared_ptr& body, + const std::shared_ptr& headers) {} + +ResponseStruct HttpClient::parseResponse(Response response) {} + +ResponseStruct HttpClient::makeGetRequest(const Host &host, const std::string &target, + const std::shared_ptr& params, + const std::shared_ptr& headers) {} + +ResponseStruct HttpClient::makePostRequest(const Host &host, const std::string &target, + const std::shared_ptr& body, + const std::shared_ptr& headers) {} diff --git a/client/internal/httpClient/src/HttpClientManager.cpp b/client/internal/httpClient/src/HttpClientManager.cpp new file mode 100644 index 0000000..57e1a88 --- /dev/null +++ b/client/internal/httpClient/src/HttpClientManager.cpp @@ -0,0 +1,42 @@ +#include "httpClientManager.h" + +#include +#include +#include +#include +#include + +HttpClientManager::HttpClientManager(const std::string &domain, + const std::string &ip, + const unsigned short &port, + std::string saved_path_) + : host(domain, ip, port), client(), serializer(), saved_path(std::move(saved_path_)) {} + +unsigned int HttpClientManager::loginUser(const std::string &login, const std::string &password) { + return 0; +} + +unsigned int HttpClientManager::registerUser(const std::string &login, const std::string &username, + const std::string &password) { + return 0; +} + +unsigned int HttpClientManager::submitSolution(const int &user_id, const std::string &path_to_sound) { + return 0; +} + +unsigned int HttpClientManager::getAllSolutionsForTask(const int &user_id, const int &task_id) { + return 0; +} + +std::vector HttpClientManager::getMetrics(const int &sol_id) { + return std::vector(); +} + +void HttpClientManager::setHttpClient(std::shared_ptr client_) { + client = client_; +} + +std::vector HttpClientManager::getAllTasks() { + return std::vector(); +} diff --git a/client/internal/httpClient/tests/CMakeLists.txt b/client/internal/httpClient/tests/CMakeLists.txt new file mode 100644 index 0000000..7b0e0c7 --- /dev/null +++ b/client/internal/httpClient/tests/CMakeLists.txt @@ -0,0 +1,16 @@ +project(test_httpclient) + +set(CMAKE_CXX_STANDARD 20) +add_compile_options(-coverage) + +file(GLOB SOURCES *.cpp) + +enable_testing() +find_package(GTest REQUIRED) + +add_executable(${PROJECT_NAME} ${SOURCES}) + +target_link_libraries(${PROJECT_NAME} ${HTTPCLIENT_lib_LIB} GTest::GTest GTest::gmock) +target_include_directories(${PROJECT_NAME} PUBLIC ${HTTPCLIENT_lib_INCLUDE_DIRS}) + +add_test(test_httpclient test_httpclient) \ No newline at end of file diff --git a/client/internal/httpClient/tests/HttpClientManagerSuite.cpp b/client/internal/httpClient/tests/HttpClientManagerSuite.cpp new file mode 100644 index 0000000..44de182 --- /dev/null +++ b/client/internal/httpClient/tests/HttpClientManagerSuite.cpp @@ -0,0 +1,64 @@ +#include +#include + +#include "IHttpClient.h" +#include "HttpClientManager.h" + +class HttpClientMock : public IHttpClient { +public: + HttpClientMock() = default; + MOCK_METHOD(ResponseStruct, makeGetRequest, (const Host& host, const std::string& target, + const std::shared_ptr& params, + const std::shared_ptr& headers), (override)); + MOCK_METHOD(ResponseStruct, makePostRequest, (const Host& host, const std::string& target, + const std::shared_ptr& body, + const std::shared_ptr& headers), (override)); + MOCK_METHOD(ResponseStruct, parseResponse, (Response response), (override)); + MOCK_METHOD(std::string, createURL, (const std::string& target, const std::shared_ptr& params), + (override)); + MOCK_METHOD(bool, connect, (unsigned short port), (override)); + MOCK_METHOD(ResponseStruct, makeRequest, (const Host& host, const std::string& target, boost::beast::http::verb method, + const std::shared_ptr& params, + const std::shared_ptr& body, + const std::shared_ptr& headers), (override)); +}; + +class HttpClientManagerSuite : public ::testing::Test { +protected: + void SetUp() override { + manager.setHttpClient(client); + } + + std::shared_ptr client = std::make_shared(); + HttpClientManager manager = HttpClientManager("1", "1.1.1.1", 1, "."); +}; + +TEST_F(HttpClientManagerSuite, LoginUserTest){ + EXPECT_CALL(*client, makeGetRequest); + manager.loginUser("1", "2"); +} + +TEST_F(HttpClientManagerSuite, RegisterUserTest){ + EXPECT_CALL(*client, makePostRequest); + manager.registerUser("1", "2", "3"); +} + +TEST_F(HttpClientManagerSuite, SubmitSolutionTest){ + EXPECT_CALL(*client, makePostRequest); + manager.submitSolution(1, "2234"); +} + +TEST_F(HttpClientManagerSuite, GetAllSolutionsForTaskTest){ + EXPECT_CALL(*client, makeGetRequest); + manager.getAllSolutionsForTask(1, 2); +} + +TEST_F(HttpClientManagerSuite, GetAllTasksTest){ + EXPECT_CALL(*client, makeGetRequest); + manager.getAllTasks(); +} + +TEST_F(HttpClientManagerSuite, GetMetricsTest){ + EXPECT_CALL(*client, makeGetRequest); + manager.getMetrics(1); +} diff --git a/client/internal/httpClient/tests/HttpClientSuite.cpp b/client/internal/httpClient/tests/HttpClientSuite.cpp new file mode 100644 index 0000000..7ff26c2 --- /dev/null +++ b/client/internal/httpClient/tests/HttpClientSuite.cpp @@ -0,0 +1,11 @@ +#include +#include + +#include "HttpClient.h" + +TEST(HttpClientSuite, WrongGetTest) { + HttpClient client; + Host h("1", "1.1.1.1", 80); + ResponseStruct res = client.makeGetRequest(h, "/ser/login"); + EXPECT_EQ(res.status, 500); +} \ No newline at end of file diff --git a/client/internal/httpClient/tests/main.cpp b/client/internal/httpClient/tests/main.cpp new file mode 100644 index 0000000..21bd133 --- /dev/null +++ b/client/internal/httpClient/tests/main.cpp @@ -0,0 +1,8 @@ +#include +#include + +int main(int argc, char** argv) { + ::testing::InitGoogleMock(&argc, argv); + + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/client/internal/httpClient/virtual/IHttpClient.h b/client/internal/httpClient/virtual/IHttpClient.h new file mode 100644 index 0000000..e24e15d --- /dev/null +++ b/client/internal/httpClient/virtual/IHttpClient.h @@ -0,0 +1,32 @@ +#ifndef APP_HTTPCLIENT_HTTPCLIENT_IHTTPCLIENT_H_ +#define APP_HTTPCLIENT_HTTPCLIENT_IHTTPCLIENT_H_ + +#include +#include +#include +#include + +#include "clientTypes.h" +#include "serializer.h" + +class IHttpClient { +public: + virtual ResponseStruct makeGetRequest(const Host& host, const std::string& target, + const std::shared_ptr& params = nullptr, + const std::shared_ptr& headers = nullptr) = 0; + virtual ResponseStruct makePostRequest(const Host& host, const std::string& target, + const std::shared_ptr& body, + const std::shared_ptr& headers = nullptr) = 0; + +protected: + virtual ResponseStruct parseResponse(Response response) = 0; + virtual std::string createURL(const std::string& target, const std::shared_ptr& params = nullptr) = 0; + virtual bool connect(unsigned short port) = 0; + virtual ResponseStruct makeRequest(const Host& host, const std::string& target, boost::beast::http::verb method, + const std::shared_ptr& params = nullptr, + const std::shared_ptr& body = nullptr, + const std::shared_ptr& headers = nullptr) = 0; +}; + + +#endif // APP_HTTPCLIENT_HTTPCLIENT_HTTPCLIENT_H_ diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index cbd2bd5..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,264 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace beast = boost::beast; // from -namespace http = beast::http; // from -namespace net = boost::asio; // from -using tcp = boost::asio::ip::tcp; // from - -//------------------------------------------------------------------------------ - -// Return a reasonable mime type based on the extension of a file. -beast::string_view mime_type(beast::string_view path) { - using beast::iequals; - auto const ext = [&path] { - auto const pos = path.rfind("."); - if (pos == beast::string_view::npos) return beast::string_view{}; - return path.substr(pos); - }(); - if (iequals(ext, ".htm")) return "text/html"; - if (iequals(ext, ".html")) return "text/html"; - if (iequals(ext, ".php")) return "text/html"; - if (iequals(ext, ".css")) return "text/css"; - if (iequals(ext, ".txt")) return "text/plain"; - if (iequals(ext, ".js")) return "application/javascript"; - if (iequals(ext, ".json")) return "application/json"; - if (iequals(ext, ".xml")) return "application/xml"; - if (iequals(ext, ".swf")) return "application/x-shockwave-flash"; - if (iequals(ext, ".flv")) return "video/x-flv"; - if (iequals(ext, ".png")) return "image/png"; - if (iequals(ext, ".jpe")) return "image/jpeg"; - if (iequals(ext, ".jpeg")) return "image/jpeg"; - if (iequals(ext, ".jpg")) return "image/jpeg"; - if (iequals(ext, ".gif")) return "image/gif"; - if (iequals(ext, ".bmp")) return "image/bmp"; - if (iequals(ext, ".ico")) return "image/vnd.microsoft.icon"; - if (iequals(ext, ".tiff")) return "image/tiff"; - if (iequals(ext, ".tif")) return "image/tiff"; - if (iequals(ext, ".svg")) return "image/svg+xml"; - if (iequals(ext, ".svgz")) return "image/svg+xml"; - return "application/text"; -} - -// Append an HTTP rel-path to a local filesystem path. -// The returned path is normalized for the platform. -std::string path_cat(beast::string_view base, beast::string_view path) { - if (base.empty()) return std::string(path); - std::string result(base); -#ifdef BOOST_MSVC - char constexpr path_separator = '\\'; - if (result.back() == path_separator) result.resize(result.size() - 1); - result.append(path.data(), path.size()); - for (auto& c : result) - if (c == '/') c = path_separator; -#else - char constexpr path_separator = '/'; - if (result.back() == path_separator) result.resize(result.size() - 1); - result.append(path.data(), path.size()); -#endif - return result; -} - -// This function produces an HTTP response for the given -// request. The type of the response object depends on the -// contents of the request, so the interface requires the -// caller to pass a generic lambda for receiving the response. -template -void handle_request(beast::string_view doc_root, - http::request>&& req, - Send&& send) { - // Returns a bad request response - auto const bad_request = [&req](beast::string_view why) { - http::response res{http::status::bad_request, - req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, "text/html"); - res.keep_alive(req.keep_alive()); - res.body() = std::string(why); - res.prepare_payload(); - return res; - }; - - // Returns a not found response - auto const not_found = [&req](beast::string_view target) { - http::response res{http::status::not_found, - req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, "text/html"); - res.keep_alive(req.keep_alive()); - res.body() = "The resource '" + std::string(target) + "' was not found."; - res.prepare_payload(); - return res; - }; - - // Returns a server error response - auto const server_error = [&req](beast::string_view what) { - http::response res{http::status::internal_server_error, - req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, "text/html"); - res.keep_alive(req.keep_alive()); - res.body() = "An error occurred: '" + std::string(what) + "'"; - res.prepare_payload(); - return res; - }; - - // Make sure we can handle the method - if (req.method() != http::verb::get && req.method() != http::verb::head) - return send(bad_request("Unknown HTTP-method")); - - // Request path must be absolute and not contain "..". - if (req.target().empty() || req.target()[0] != '/' || - req.target().find("..") != beast::string_view::npos) - return send(bad_request("Illegal request-target")); - - // Build the path to the requested file - std::string path = path_cat(doc_root, req.target()); - if (req.target().back() == '/') path.append("index.html"); - - // Attempt to open the file - beast::error_code ec; - http::file_body::value_type body; - body.open(path.c_str(), beast::file_mode::scan, ec); - - // Handle the case where the file doesn't exist - if (ec == beast::errc::no_such_file_or_directory) - return send(not_found(req.target())); - - // Handle an unknown error - if (ec) return send(server_error(ec.message())); - - // Cache the size since we need it after the move - auto const size = body.size(); - - // Respond to HEAD request - if (req.method() == http::verb::head) { - http::response res{http::status::ok, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, mime_type(path)); - res.content_length(size); - res.keep_alive(req.keep_alive()); - return send(std::move(res)); - } - - // Respond to GET request - http::response res{ - std::piecewise_construct, std::make_tuple(std::move(body)), - std::make_tuple(http::status::ok, req.version())}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, mime_type(path)); - res.content_length(size); - res.keep_alive(req.keep_alive()); - return send(std::move(res)); -} - -//------------------------------------------------------------------------------ - -// Report a failure -void fail(beast::error_code ec, char const* what) { - std::cerr << what << ": " << ec.message() << "\n"; -} - -// This is the C++11 equivalent of a generic lambda. -// The function object is used to send an HTTP message. -template -struct send_lambda { - Stream& stream_; - bool& close_; - beast::error_code& ec_; - - explicit send_lambda(Stream& stream, bool& close, beast::error_code& ec) - : stream_(stream), close_(close), ec_(ec) {} - - template - void operator()(http::message&& msg) const { - // Determine if we should close the connection after - close_ = msg.need_eof(); - - // We need the serializer here because the serializer requires - // a non-const file_body, and the message oriented version of - // http::write only works with const messages. - http::serializer sr{msg}; - http::write(stream_, sr, ec_); - } -}; - -// Handles an HTTP server connection -void do_session(tcp::socket& socket, - std::shared_ptr const& doc_root) { - bool close = false; - beast::error_code ec; - - // This buffer is required to persist across reads - beast::flat_buffer buffer; - - // This lambda is used to send messages - send_lambda lambda{socket, close, ec}; - - for (;;) { - // Read a request - http::request req; - http::read(socket, buffer, req, ec); - if (ec == http::error::end_of_stream) break; - if (ec) return fail(ec, "read"); - - // Send the response - handle_request(*doc_root, std::move(req), lambda); - if (ec) return fail(ec, "write"); - if (close) { - // This means we should close the connection, usually because - // the response indicated the "Connection: close" semantic. - break; - } - } - - // Send a TCP shutdown - socket.shutdown(tcp::socket::shutdown_send, ec); - - // At this point the connection is closed gracefully -} - -//------------------------------------------------------------------------------ - -int main(int argc, char* argv[]) { - try { - // Check command line arguments. - if (argc != 4) { - std::cerr << "Usage: http-server-sync
\n" - << "Example:\n" - << " http-server-sync 0.0.0.0 8080 .\n"; - return EXIT_FAILURE; - } - auto const address = net::ip::make_address(argv[1]); - auto const port = static_cast(std::atoi(argv[2])); - auto const doc_root = std::make_shared(argv[3]); - - // The io_context is required for all I/O - net::io_context ioc{1}; - - // The acceptor receives incoming connections - tcp::acceptor acceptor{ioc, {address, port}}; - for (;;) { - // This will receive the new connection - tcp::socket socket{ioc}; - - // Block until we get a connection - acceptor.accept(socket); - - // Launch the session, transferring ownership of the socket - std::thread{std::bind(&do_session, std::move(socket), doc_root)}.detach(); - } - } catch (const std::exception& e) { - std::cerr << "Error: " << e.what() << std::endl; - return EXIT_FAILURE; - } -} diff --git a/text-basic-metrics/code1.txt b/text-basic-metrics/code1.txt deleted file mode 100644 index 5fa95b8..0000000 --- a/text-basic-metrics/code1.txt +++ /dev/null @@ -1,29 +0,0 @@ -// однострочный комментарий -// еще один -// вау еще один - -#include -#include -#include - -using namespace std; - -/* многострочный комм - * // внутри него однострочный - * - */ - - -int main() { - stringstream ss; - string res; - // ещё в код напихаю комментов - ss << "a bwfw ce "; - while(getline(ss, res, ' ')){ //комментарий после строки с кодом - /* - * летс гоу - * худшее место для многострочного коммента - */ - cout << res << endl; /* многострочный однострочно */ - } -} diff --git a/text-basic-metrics/code2.txt b/text-basic-metrics/code2.txt deleted file mode 100644 index 2115b76..0000000 --- a/text-basic-metrics/code2.txt +++ /dev/null @@ -1,29 +0,0 @@ -// однострочный комментарий -// еще один -// вау еще один - -#include -#include -#include - -using namespace std; - -/* многострочный комм - * // внутри него однострочный - * - */ - - -int main() { - stringstream ss1; - string res1; - // ещё в код напихаю комментов - ss1 << "a bwfw ce "; - while(getline(ss, res1, ' ')){ //комментарий после строки с кодом - /* - * летс гоу - * худшее место для многострочного коммента - */ - cout << res1 << endl; /* многострочный однострочно */ - } -} \ No newline at end of file diff --git a/text-basic-metrics/tbm_main.cpp b/text-basic-metrics/tbm_main.cpp deleted file mode 100644 index fdd4253..0000000 --- a/text-basic-metrics/tbm_main.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// -// Created by march on 21.04.2023. -// - -#include -#include -#include -#include -#include -#include -#include - -#include - - -std::string deleteComms(const std::string& text){ - std::string modif; - std::string res; - - std::stringstream ss; - std::string line; - - ss << text; - - while(getline(ss, line)){ - line.pop_back(); - line.push_back('\0'); - modif += line; - } - - bool s_comm = false; - bool m_comm = false; - - for (int i = 0; i < modif.size(); i++){ - if (s_comm && modif[i] == '\0') - s_comm = false; - else if (m_comm && modif[i] == '*' && modif[i + 1] == '/') - m_comm = false, i++; - else if (s_comm || m_comm) - continue; - else if (modif[i] == '/' && modif[i+1] == '/') - s_comm = true, i++; - else if (modif[i] == '/' && modif[i+1] == '*') - m_comm = true, i++; - - else if (modif[i] != '\0') - res += modif[i]; - else{ - res += '\n'; - } - } - return res; -} - -std::vector tbm_tokenizer(const std::string &text){ - boost::char_separator sep(" {}();,\"\0\'"); - std::vector res; - boost::tokenizer < boost::char_separator > tokens(text, sep); - - for (const std::string &s: tokens) { - if (!s.empty() && s[0] != '\n' && s[0] != '\0'){ - res.push_back(s); - } - } - return res; -} - -// % = intersection(A, B) / union(A, B) -double Jaccard_metric(const std::vector & tokens1, const std::vector & tokens2){ - std::set s1; - std::set s2; - - for (auto &i : tokens1) s1.insert(i); - for (auto &i : tokens2) s2.insert(i); - - - std::set intersect_sets; - set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), - std::inserter(intersect_sets, intersect_sets.begin())); - - std::set union_sets; - set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), - std::inserter(union_sets, union_sets.begin())); - - std::cout << intersect_sets.size() << " " << union_sets.size() << std::endl; - - return static_cast (intersect_sets.size()) / static_cast (union_sets.size()); -} - -double Livenstain_dist(std::vector tokens1, std::vector tokens2){ - unsigned long n = tokens1.size(); - unsigned long m = tokens2.size(); - int x, y, z; - - std::vector > lev (n, std::vector (m, 0)); - - for (int i = 0; i < n; i++){ - for (int j = 0; j < m; j++){ - if (std::min(i, j) == 0){ - lev[i][j] = std::max(i, j); - } - else{ - x = lev[i-1][j]; - y = lev[i][j-1]; - z = lev[i-1][j-1]; - lev[i][j] = std::min(x, std::min(y, z)); - if (tokens1[i] != tokens2[j]){ - lev[i][j]++; - } - } - } - } - - return lev[n-1][m-1]; -} - -std::pair textCompare(std::istream& fin1, std::istream& fin2){ - std::string line; - - std::string text1( (std::istreambuf_iterator(fin1) ), - (std::istreambuf_iterator() ) ); - - std::string text2( (std::istreambuf_iterator(fin2) ), - (std::istreambuf_iterator() ) ); - - std::string non_comm_text1 = deleteComms(text1); - std::string non_comm_text2 = deleteComms(text2); - - std::vector tokens1 = tbm_tokenizer(non_comm_text1); - std::vector tokens2 = tbm_tokenizer(non_comm_text2); - - double res1 = Jaccard_metric(tokens1, tokens2); - double res2 = 1 - Livenstain_dist(tokens1, tokens2) / std::max(tokens1.size(), tokens2.size()); - - return {res1, res2}; -} - -int main(){ - - std::ifstream fin1; - fin1.open("text-basic-metrics/code1.txt"); - assert(fin1.is_open()); - - std::ifstream fin2; - fin2.open("text-basic-metrics/code2.txt"); - assert(fin2.is_open()); - - std::pair metrics_res = textCompare(fin1, fin2); - - std::cout << "Jaccard metric "<< metrics_res.first << "\nLivenstein distance: " << metrics_res.second; - fin1.close(); - fin2.close(); -} \ No newline at end of file -- GitLab From 9404042b39d2194f23bdbbf396fc166814268ddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9=20=D0=A1=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Thu, 4 May 2023 09:14:37 +0300 Subject: [PATCH 2/8] Add skeleton for gui library --- client/internal/CMakeLists.txt | 6 ++- client/internal/gui/CMakeLists.txt | 24 ++++++++++ client/internal/gui/include/AuthDialog.h | 43 ++++++++++++++++++ client/internal/gui/include/EntryWindow.h | 45 +++++++++++++++++++ client/internal/gui/include/SignUpDialog.h | 46 +++++++++++++++++++ client/internal/gui/include/StatsDialog.h | 25 +++++++++++ client/internal/gui/include/UIManager.h | 21 +++++++++ client/internal/gui/include/UserWindow.h | 46 +++++++++++++++++++ client/internal/gui/src/AuthDialog.cpp | 15 +++++++ client/internal/gui/src/EntryWindow.cpp | 27 +++++++++++ client/internal/gui/src/SignUpDialog.cpp | 17 +++++++ client/internal/gui/src/UIManager.cpp | 11 +++++ client/internal/gui/src/UserWindow.cpp | 9 ++++ client/internal/gui/tests/CMakeLists.txt | 16 +++++++ client/internal/gui/tests/main.cpp | 52 ++++++++++++++++++++++ 15 files changed, 402 insertions(+), 1 deletion(-) create mode 100644 client/internal/gui/CMakeLists.txt create mode 100644 client/internal/gui/include/AuthDialog.h create mode 100644 client/internal/gui/include/EntryWindow.h create mode 100644 client/internal/gui/include/SignUpDialog.h create mode 100644 client/internal/gui/include/StatsDialog.h create mode 100644 client/internal/gui/include/UIManager.h create mode 100644 client/internal/gui/include/UserWindow.h create mode 100644 client/internal/gui/src/AuthDialog.cpp create mode 100644 client/internal/gui/src/EntryWindow.cpp create mode 100644 client/internal/gui/src/SignUpDialog.cpp create mode 100644 client/internal/gui/src/UIManager.cpp create mode 100644 client/internal/gui/src/UserWindow.cpp create mode 100644 client/internal/gui/tests/CMakeLists.txt create mode 100644 client/internal/gui/tests/main.cpp diff --git a/client/internal/CMakeLists.txt b/client/internal/CMakeLists.txt index 93fbed8..f76cc95 100644 --- a/client/internal/CMakeLists.txt +++ b/client/internal/CMakeLists.txt @@ -1,8 +1,12 @@ add_subdirectory(entities) add_subdirectory(httpClient) +add_subdirectory(gui) set(libClientEntities_LIB ${libClientEntities_LIB} PARENT_SCOPE) set(libClientEntities_INCLUDE_DIRS ${libClientEntities_INCLUDE_DIRS} PARENT_SCOPE) set(HTTPCLIENT_lib_LIB ${HTTPCLIENT_lib_LIB} PARENT_SCOPE) -set(HTTPCLIENT_lib_INCLUDE_DIRS ${HTTPCLIENT_lib_INCLUDE_DIRS} PARENT_SCOPE) \ No newline at end of file +set(HTTPCLIENT_lib_INCLUDE_DIRS ${HTTPCLIENT_lib_INCLUDE_DIRS} PARENT_SCOPE) + +set(GUI_lib_LIB ${GUI_lib_LIB} PARENT_SCOPE) +set(GUI_lib_INCLUDE_DIRS ${GUI_lib_INCLUDE_DIRS} PARENT_SCOPE) \ No newline at end of file diff --git a/client/internal/gui/CMakeLists.txt b/client/internal/gui/CMakeLists.txt new file mode 100644 index 0000000..60da13c --- /dev/null +++ b/client/internal/gui/CMakeLists.txt @@ -0,0 +1,24 @@ +project("GuiLib") + +set(CMAKE_CXX_STANDARD 20) + +file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include) +file(GLOB INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) + +set(CMAKE_PREFIX_PATH "~/Qt/6.5.0/macos/lib/cmake") +find_package(Qt6 REQUIRED COMPONENTS Widgets Core Gui) + +include_directories(${INCLUDE_DIRS} ${libClientEntities_INCLUDE_DIRS}) + +add_library(${PROJECT_NAME} ${SOURCES} ${INCLUDES}) +target_link_libraries(${PROJECT_NAME} ${libClientEntities_LIB} Qt6::Widgets Qt6::Core Qt6::Gui) + +set(GUI_lib_LIB ${PROJECT_NAME}) +set(GUI_lib_LIB ${GUI_lib_LIB} PARENT_SCOPE) + +set(GUI_lib_INCLUDE_DIRS ${INCLUDE_DIRS}) +set(GUI_lib_INCLUDE_DIRS ${GUI_lib_INCLUDE_DIRS} PARENT_SCOPE) + +enable_testing() +add_subdirectory(tests) \ No newline at end of file diff --git a/client/internal/gui/include/AuthDialog.h b/client/internal/gui/include/AuthDialog.h new file mode 100644 index 0000000..76b3f9b --- /dev/null +++ b/client/internal/gui/include/AuthDialog.h @@ -0,0 +1,43 @@ +#ifndef AUTH_DIALOG_H +#define AUTH_DIALOG_H + +#include +#include +#include +#include +#include + +class AuthDialog : public QDialog { + Q_OBJECT + +public: + explicit AuthDialog(QWidget *parent = nullptr); + ~AuthDialog() override; + +signals: + void showMainWindow(); + void showUserWindow(); + +private slots: + void on_loginButton_clicked(); + void on_backButton_clicked(); + +private: + QGroupBox *groupBox = nullptr; + QWidget *layoutWidget = nullptr; + QVBoxLayout *verticalLayout = nullptr; + QHBoxLayout *horizontalLayout = nullptr; + QLabel *loginLabel = nullptr; + QLineEdit *login = nullptr; + QHBoxLayout *horizontalLayout_2 = nullptr; + QLabel *passwordLabel = nullptr; + QLineEdit *password = nullptr; + QPushButton *loginButton = nullptr; + QPushButton *backButton = nullptr; + + void setupUi(QDialog *AuthDialog); + + void setTexts(QDialog *AuthDialog); +}; + +#endif // AUTH_DIALOG_H diff --git a/client/internal/gui/include/EntryWindow.h b/client/internal/gui/include/EntryWindow.h new file mode 100644 index 0000000..b7acbd0 --- /dev/null +++ b/client/internal/gui/include/EntryWindow.h @@ -0,0 +1,45 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include + +#include "AuthDialog.h" +#include "SignUpDialog.h" + +class EntryWindow : public QMainWindow { +Q_OBJECT + +public: + EntryWindow(QWidget *parent = nullptr); + ~EntryWindow() override; + + std::shared_ptr getSignUpDialog(); + std::shared_ptr getAuthDialog(); + +private slots: + static void onExitButtonClicked(); + void onLoginButtonClicked(); + void onSignUpButtonClicked(); + +private: + std::shared_ptr authDialog = nullptr; + std::shared_ptr signUpDialog = nullptr; + QWidget *centralwidget = nullptr; + QVBoxLayout *verticalLayout = nullptr; + QLabel *introLabel = nullptr; + QPushButton *loginButton = nullptr; + QSpacerItem *horizontalSpacer = nullptr; + QPushButton *signUpButton = nullptr; + QSpacerItem *horizontalSpacer_2 = nullptr; + QPushButton *exitButton = nullptr; + QMenuBar *menubar = nullptr; + QStatusBar *statusbar = nullptr; + + void setupUi(QMainWindow *MainWindow); + void retranslateUi(QMainWindow *MainWindow); +}; + +#endif // MAINWINDOW_H diff --git a/client/internal/gui/include/SignUpDialog.h b/client/internal/gui/include/SignUpDialog.h new file mode 100644 index 0000000..2882b24 --- /dev/null +++ b/client/internal/gui/include/SignUpDialog.h @@ -0,0 +1,46 @@ +#ifndef SIGN_UP_DIALOG_H +#define SIGN_UP_DIALOG_H + +#include +#include +#include +#include +#include + +class SignUpDialog : public QDialog { +Q_OBJECT + +public: + explicit SignUpDialog(QWidget *parent = nullptr); + ~SignUpDialog() override; + +signals: + void showEntryWindow(); + void showUserWindow(); + +private slots: + void on_signUpButton_clicked() {}; + void on_backButton_clicked() {}; + +private: + QGroupBox *groupBox = nullptr; + QWidget *layoutWidget = nullptr; + QVBoxLayout *verticalLayout_2 = nullptr; + QVBoxLayout *verticalLayout = nullptr; + QGridLayout *gridLayout = nullptr; + QLabel *enterLoginLabel = nullptr; + QLineEdit *login = nullptr; + QGridLayout *gridLayout_2 = nullptr; + QLineEdit *pass = nullptr; + QLabel *enterPasswordLabel = nullptr; + QHBoxLayout *horizontalLayout_3 = nullptr; + QLabel *repeatPasswordLabel = nullptr; + QLineEdit *passRepeat = nullptr; + QPushButton *signUpButton = nullptr; + QPushButton *backButton = nullptr; + + void setupUi(QDialog *SignUpDialog); + void retranslateUi(QDialog *SignUpDialog); +}; + +#endif // SIGN_UP_DIALOG_H diff --git a/client/internal/gui/include/StatsDialog.h b/client/internal/gui/include/StatsDialog.h new file mode 100644 index 0000000..8a10038 --- /dev/null +++ b/client/internal/gui/include/StatsDialog.h @@ -0,0 +1,25 @@ +// +// Created by Николай Степанов on 04.05.2023. +// + +#ifndef SOURCEDOUT_STATSDIALOG_H +#define SOURCEDOUT_STATSDIALOG_H + +#include +#include +#include "Metric.h" + +class StatsDialog : public QDialog { + Q_OBJECT + +public: + explicit StatsDialog(QWidget *parent = nullptr) {}; + ~StatsDialog() override {}; + +private: + QTableView* tableView = nullptr; + QTableWidget* tableWidget = nullptr; + QVector metrics; +}; + +#endif //SOURCEDOUT_STATSDIALOG_H diff --git a/client/internal/gui/include/UIManager.h b/client/internal/gui/include/UIManager.h new file mode 100644 index 0000000..3d030f2 --- /dev/null +++ b/client/internal/gui/include/UIManager.h @@ -0,0 +1,21 @@ +#ifndef INCLUDE_UIMANAGER_H_ +#define INCLUDE_UIMANAGER_H_ + +#include "EntryWindow.h" +#include "UserWindow.h" + +class UIManager { +public: + UIManager(); + + ~UIManager() = default; + + void showEntryWindow(); + void showUserWindow(); + +private: + EntryWindow entryWindow; + UserWindow userWindow; +}; + +#endif // INCLUDE_UIMANAGER_H_ diff --git a/client/internal/gui/include/UserWindow.h b/client/internal/gui/include/UserWindow.h new file mode 100644 index 0000000..859d69e --- /dev/null +++ b/client/internal/gui/include/UserWindow.h @@ -0,0 +1,46 @@ +#ifndef USERWINDOW_H +#define USERWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "StatsDialog.h" + +class UserWindow : public QMainWindow { +Q_OBJECT + +public: + explicit UserWindow(QWidget *parent = nullptr); + ~UserWindow() override = default; + +signals: + void logout(); + +private slots: + void onBackButtonClicked(); + void onListElementClicked(); + void onSendButtonClicked(); + +private: + + QTabWidget* tabs = nullptr; + StatsDialog* statsDialog = nullptr; + QPushButton *backButton = nullptr; + QPushButton *sendButton = nullptr; + QComboBox* comboBox = nullptr; + QVBoxLayout* verticalLayout = nullptr; + QLabel* label = nullptr; + QLabel* description = nullptr; + QFileDialog* fileDialog = nullptr; + QStringList* list = nullptr; + + QWidget *centralwidget = nullptr; +}; + +#endif // USERWINDOW_H diff --git a/client/internal/gui/src/AuthDialog.cpp b/client/internal/gui/src/AuthDialog.cpp new file mode 100644 index 0000000..0e57d4d --- /dev/null +++ b/client/internal/gui/src/AuthDialog.cpp @@ -0,0 +1,15 @@ +#include "AuthDialog.h" + +AuthDialog::AuthDialog(QWidget *parent) : QDialog(parent) { + setupUi(this); +} + +AuthDialog::~AuthDialog() {} + +void AuthDialog::on_loginButton_clicked() {} + +void AuthDialog::setupUi(QDialog *AuthDialog) {} + +void AuthDialog::setTexts(QDialog *AuthDialog) {} + +void AuthDialog::on_backButton_clicked() {} diff --git a/client/internal/gui/src/EntryWindow.cpp b/client/internal/gui/src/EntryWindow.cpp new file mode 100644 index 0000000..8bf9bc3 --- /dev/null +++ b/client/internal/gui/src/EntryWindow.cpp @@ -0,0 +1,27 @@ +#include "EntryWindow.h" + +#include +#include +#include +#include +#include "AuthDialog.h" +#include "SignUpDialog.h" + +EntryWindow::EntryWindow(QWidget *parent) : QMainWindow(parent) {} + +EntryWindow::~EntryWindow() {} + +void EntryWindow::setupUi(QMainWindow *MainWindow) {} + +void EntryWindow::retranslateUi(QMainWindow *MainWindow) {} + +void EntryWindow::onExitButtonClicked() {} + +void EntryWindow::onLoginButtonClicked() {} + + +void EntryWindow::onSignUpButtonClicked() {} + +std::shared_ptr EntryWindow::getSignUpDialog() {} + +std::shared_ptr EntryWindow::getAuthDialog() {} diff --git a/client/internal/gui/src/SignUpDialog.cpp b/client/internal/gui/src/SignUpDialog.cpp new file mode 100644 index 0000000..8750c80 --- /dev/null +++ b/client/internal/gui/src/SignUpDialog.cpp @@ -0,0 +1,17 @@ +#include "SignUpDialog.h" + +#include +#include +#include + +//#include "Core.h" + +SignUpDialog::SignUpDialog(QWidget *parent) : QDialog(parent) {} + +SignUpDialog::~SignUpDialog() {} + +void SignUpDialog::retranslateUi(QDialog *SignUpDialog) {} + +void SignUpDialog::setupUi(QDialog *SignUpDialog) {} + +// setupUi diff --git a/client/internal/gui/src/UIManager.cpp b/client/internal/gui/src/UIManager.cpp new file mode 100644 index 0000000..fc23301 --- /dev/null +++ b/client/internal/gui/src/UIManager.cpp @@ -0,0 +1,11 @@ +#include "UIManager.h" + +#include "EntryWindow.h" +#include "UserWindow.h" +#include "SignUpDialog.h" + +void UIManager::showEntryWindow() {} + +void UIManager::showUserWindow() {} + +UIManager::UIManager() = default; diff --git a/client/internal/gui/src/UserWindow.cpp b/client/internal/gui/src/UserWindow.cpp new file mode 100644 index 0000000..8e6169b --- /dev/null +++ b/client/internal/gui/src/UserWindow.cpp @@ -0,0 +1,9 @@ +#include "UserWindow.h" + +#include +#include +#include + +UserWindow::UserWindow(QWidget *parent) : QMainWindow(parent) {} + +void UserWindow::onBackButtonClicked() {} diff --git a/client/internal/gui/tests/CMakeLists.txt b/client/internal/gui/tests/CMakeLists.txt new file mode 100644 index 0000000..5877dc8 --- /dev/null +++ b/client/internal/gui/tests/CMakeLists.txt @@ -0,0 +1,16 @@ +project(test_gui) + +set(CMAKE_CXX_STANDARD 20) +add_compile_options(-coverage) + +file(GLOB SOURCES *.cpp) + +enable_testing() +find_package(GTest REQUIRED) + +add_executable(${PROJECT_NAME} ${SOURCES}) + +target_link_libraries(${PROJECT_NAME} ${GUI_lib_LIB} GTest::GTest GTest::gmock) +target_include_directories(${PROJECT_NAME} PUBLIC ${GUI_lib_INCLUDE_DIRS}) + +add_test(test_gui test_gui) \ No newline at end of file diff --git a/client/internal/gui/tests/main.cpp b/client/internal/gui/tests/main.cpp new file mode 100644 index 0000000..d9f4b73 --- /dev/null +++ b/client/internal/gui/tests/main.cpp @@ -0,0 +1,52 @@ +#include +#include + +#include "UIManager.h" +#include "EntryWindow.h" +#include "UserWindow.h" + +#include + +TEST(ConstructorTest, EntryWindow) { + int fake = 0; + QApplication a(fake, nullptr); + EntryWindow mw; + EXPECT_NO_FATAL_FAILURE(mw.show()); + a.exec(); +} + +TEST(ConstructorTest, UserWindow) { + int fake = 0; + QApplication a(fake, nullptr); + UserWindow uw; + EXPECT_NO_FATAL_FAILURE(uw.show()); + a.exec(); +} + +TEST(ConstructorTest, UIManagerMW) { + int fake_argc = 0; + QApplication a(fake_argc, nullptr); + UIManager um; + EXPECT_NO_FATAL_FAILURE(um.showEntryWindow()); + a.exec(); +} + +TEST(ConstructorTest, UIManagerUW) { + int fake_argc = 0; + QApplication a(fake_argc, nullptr); + UIManager um; + EXPECT_NO_FATAL_FAILURE(um.showUserWindow()); + a.exec(); +} + +TEST(ConstructorTest, MainWindow_AuthDialog) { + int fake_argc = 0; + QApplication a(fake_argc, nullptr); + EntryWindow mainWindow; + EXPECT_NO_FATAL_FAILURE(mainWindow.getAuthDialog()->show()); +} + +int main(int argc, char *argv[]) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} -- GitLab From 32bbd267282a0f3f4db6289b43f149d18d817d3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9=20=D0=A1=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Wed, 10 May 2023 08:37:14 +0300 Subject: [PATCH 3/8] Add realizations of server --- server/internal/httpServer/CMakeLists.txt | 2 + .../httpServer/include/HttpConnection.h | 44 ++++---- .../internal/httpServer/include/HttpServer.h | 27 +++-- server/internal/httpServer/include/Parser.h | 57 ---------- server/internal/httpServer/include/Request.h | 17 --- server/internal/httpServer/include/Response.h | 38 ------- server/internal/httpServer/include/Router.h | 26 +++-- .../internal/httpServer/include/Serializer.h | 14 ++- .../httpServer/include/SolutionManager.h | 13 ++- .../internal/httpServer/include/TaskManager.h | 7 +- .../internal/httpServer/include/UserManager.h | 7 +- server/internal/httpServer/include/Utils.h | 8 ++ server/internal/httpServer/main.cpp | 48 ++++++++ .../httpServer/src/HttpConnection.cpp | 74 +++++++++++-- server/internal/httpServer/src/HttpServer.cpp | 60 ++++++++-- server/internal/httpServer/src/Parser.cpp | 17 --- server/internal/httpServer/src/Response.cpp | 5 - server/internal/httpServer/src/Router.cpp | 52 ++++++++- server/internal/httpServer/src/Serializer.cpp | 103 ++++++++++++++++++ .../httpServer/src/SolutionManager.cpp | 59 ++++++++-- .../internal/httpServer/src/TaskManager.cpp | 34 +++--- .../internal/httpServer/src/UserManager.cpp | 45 +++++--- server/internal/httpServer/src/Utils.cpp | 6 + .../httpServer/virtual/ISolutionManager.h | 13 +-- .../httpServer/virtual/ITaskManager.h | 11 +- .../httpServer/virtual/IUserManager.h | 11 +- .../repository/include/SolutionRepository.hpp | 2 +- .../repository/include/UserRepository.hpp | 2 +- .../service/include/SolutionService.h | 2 +- server/internal/service/include/TaskService.h | 2 +- server/internal/service/include/UserService.h | 4 +- .../internal/service/src/SolutionService.cpp | 7 +- server/internal/service/src/TaskService.cpp | 7 +- server/internal/service/src/UserService.cpp | 6 +- 34 files changed, 541 insertions(+), 289 deletions(-) delete mode 100644 server/internal/httpServer/include/Parser.h delete mode 100644 server/internal/httpServer/include/Request.h delete mode 100644 server/internal/httpServer/include/Response.h create mode 100644 server/internal/httpServer/include/Utils.h create mode 100644 server/internal/httpServer/main.cpp delete mode 100644 server/internal/httpServer/src/Parser.cpp delete mode 100644 server/internal/httpServer/src/Response.cpp create mode 100644 server/internal/httpServer/src/Serializer.cpp create mode 100644 server/internal/httpServer/src/Utils.cpp diff --git a/server/internal/httpServer/CMakeLists.txt b/server/internal/httpServer/CMakeLists.txt index 871e221..f9227f4 100644 --- a/server/internal/httpServer/CMakeLists.txt +++ b/server/internal/httpServer/CMakeLists.txt @@ -8,11 +8,13 @@ file(GLOB INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h ${CMAKE_CURRENT_SOURC include_directories(${INCLUDE_DIRS} ${Boost_INCLUDE_DIR} ${libEntities_INCLUDE_DIRS} ${SERVICE_lib_INCLUDE_DIRS}) add_library(${PROJECT_NAME} ${SOURCES} ${INCLUDES}) +add_executable(HttpServer_run main.cpp) message("SERVICE_lib_LIB = ${SERVICE_lib_LIB}") message("SERVICE_lib_INCLUDE_DIRS = ${SERVICE_lib_INCLUDE_DIRS}") target_link_libraries(${PROJECT_NAME} ${SERVICE_lib_LIB} ${libEntities_LIB} ${Boost_LIBRARIES}) +target_link_libraries(HttpServer_run ${PROJECT_NAME} ${Boost_LIBRARIES}) set(HTTPSERVER_lib_LIB ${PROJECT_NAME}) set(HTTPSERVER_lib_LIB ${HTTPSERVER_lib_LIB} PARENT_SCOPE) diff --git a/server/internal/httpServer/include/HttpConnection.h b/server/internal/httpServer/include/HttpConnection.h index cee5f56..86d4bbb 100644 --- a/server/internal/httpServer/include/HttpConnection.h +++ b/server/internal/httpServer/include/HttpConnection.h @@ -1,33 +1,35 @@ -#ifndef APP_HTTPSERVER_HTTPSERVER_HTTPCONNECTION_H_ -#define APP_HTTPSERVER_HTTPSERVER_HTTPCONNECTION_H_ +#ifndef SOURCEDOUT_HTTPSERVER_HTTPCONNECTION_H +#define SOURCEDOUT_HTTPSERVER_HTTPCONNECTION_H #include #include +#include -#include "Response.h" -#include "Request.h" #include "Router.h" -#include "Parser.h" -class HttpConnection : public std::enable_shared_from_this, - private boost::noncopyable { +namespace beast = boost::beast; +namespace http = beast::http; +namespace net = boost::asio; +using tcp = boost::asio::ip::tcp; + +class HttpConnection : public std::enable_shared_from_this { public: - explicit HttpConnection(boost::asio::io_service& io_service); - boost::asio::ip::tcp::socket& getSocket(); - void start(); - protected: - void handleRead(const boost::system::error_code& e, - std::size_t bytes_transferred); - void handleWrite(const boost::system::error_code& e); + explicit HttpConnection(tcp::socket&& socket_, + std::shared_ptr const& doc_root_); + void run(); + void read(); + void handleRead(beast::error_code e, std::size_t bytes_transferred); + void sendResponse(http::message_generator&& msg); + void handleWrite(bool keep_alive, beast::error_code e, std::size_t bytes_transferred); + void close(); - boost::asio::io_service::strand strand; - boost::asio::ip::tcp::socket socket; + private: + beast::tcp_stream stream; + beast::flat_buffer buffer; + std::shared_ptr doc_root; + http::request request; std::shared_ptr router; - std::array buffer{}; - Request request; - Parser parser; - Response response; }; -#endif // APP_HTTPSERVER_HTTPSERVER_HTTPCONNECTION_H_ +#endif // SOURCEDOUT_HTTPSERVER_HTTPCONNECTION_H diff --git a/server/internal/httpServer/include/HttpServer.h b/server/internal/httpServer/include/HttpServer.h index 083d224..422a2c8 100644 --- a/server/internal/httpServer/include/HttpServer.h +++ b/server/internal/httpServer/include/HttpServer.h @@ -1,30 +1,29 @@ -#ifndef APP_HTTPSERVER_HTTPSERVER_HTTPSERVER_H_ -#define APP_HTTPSERVER_HTTPSERVER_HTTPSERVER_H_ +#ifndef SOURCEDOUT_HTTPSERVER_HTTPSERVER_H +#define SOURCEDOUT_HTTPSERVER_HTTPSERVER_H #include #include #include -#include -#include #include "HttpConnection.h" #include "Router.h" -class HttpServer : private boost::noncopyable { +namespace net = boost::asio; +using tcp = boost::asio::ip::tcp; + +class HttpServer : public std::enable_shared_from_this { public: - HttpServer(const std::string& address, const std::string& port, std::size_t thread_pool_size); + HttpServer(net::io_context& io_context_, tcp::endpoint endpoint_, + std::shared_ptr const& doc_root_); void run(); private: void startAccept(); - void handleAccept(const boost::system::error_code& e); - void handleStop(); + void handleAccept(beast::error_code ec, tcp::socket socket); - std::size_t thread_pool_size; - boost::asio::io_service io_service; - boost::asio::signal_set signals; - boost::asio::ip::tcp::acceptor acceptor; - std::shared_ptr connection; + net::io_context& io_context; + tcp::acceptor acceptor; + std::shared_ptr doc_root; }; -#endif // APP_HTTPSERVER_HTTPSERVER_HTTPSERVER_H_ +#endif // SOURCEDOUT_HTTPSERVER_HTTPSERVER_H diff --git a/server/internal/httpServer/include/Parser.h b/server/internal/httpServer/include/Parser.h deleted file mode 100644 index 142f234..0000000 --- a/server/internal/httpServer/include/Parser.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef APP_HTTPSERVER_HTTPSERVER_PARSER_H_ -#define APP_HTTPSERVER_HTTPSERVER_PARSER_H_ - -#include "Request.h" - -#include -#include - -class Parser { - public: - Parser(); - void reset(); - - template - boost::tuple parse(Request& req, - InputIterator begin, InputIterator end) { - while (begin != end) { - boost::tribool result = consume(req, *begin++); - if (result || !result) - return boost::make_tuple(result, begin); - } - boost::tribool result = boost::indeterminate; - return boost::make_tuple(result, begin); - } - - private: - boost::tribool consume(Request& req, char input); - static bool isChar(int c); - static bool isCtl(int c); - static bool isTspecial(int c); - static bool isDigit(int c); - - enum state { - method_start, - method, - uri, - http_version_h, - http_version_t_1, - http_version_t_2, - http_version_p, - http_version_slash, - http_version_major_start, - http_version_major, - http_version_minor_start, - http_version_minor, - expecting_newline_1, - header_line_start, - header_lws, - header_name, - space_before_header_value, - header_value, - expecting_newline_2, - expecting_newline_3 - } state; -}; - -#endif // APP_HTTPSERVER_HTTPSERVER_PARSER_H_ diff --git a/server/internal/httpServer/include/Request.h b/server/internal/httpServer/include/Request.h deleted file mode 100644 index 386f9b3..0000000 --- a/server/internal/httpServer/include/Request.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef APP_HTTPSERVER_HTTPSERVER_REQUEST_H_ -#define APP_HTTPSERVER_HTTPSERVER_REQUEST_H_ - -#include -#include - -#include "Header.h" - -struct Request { - std::string method; - std::string uri; - int http_version_major; - int http_version_minor; - std::vector
headers; -}; - -#endif // APP_HTTPSERVER_HTTPSERVER_REQUEST_H_ diff --git a/server/internal/httpServer/include/Response.h b/server/internal/httpServer/include/Response.h deleted file mode 100644 index 6dd3a1d..0000000 --- a/server/internal/httpServer/include/Response.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef APP_HTTPSERVER_HTTPSERVER_REPLY_H_ -#define APP_HTTPSERVER_HTTPSERVER_REPLY_H_ - -#include -#include -#include - -#include "Header.h" - -struct Response { - enum status_type { - ok = 200, - created = 201, - accepted = 202, - no_content = 204, - multiple_choices = 300, - moved_permanently = 301, - moved_temporarily = 302, - not_modified = 304, - bad_request = 400, - unauthorized = 401, - forbidden = 403, - not_found = 404, - internal_server_error = 500, - not_implemented = 501, - bad_gateway = 502, - service_unavailable = 503 - } status; - - std::vector
headers; - std::string content; - - std::vector toBuffers(); - static Response stockResponse(status_type status); -}; - - -#endif // APP_HTTPSERVER_HTTPSERVER_REPLY_H_ diff --git a/server/internal/httpServer/include/Router.h b/server/internal/httpServer/include/Router.h index 50267ea..404b44d 100644 --- a/server/internal/httpServer/include/Router.h +++ b/server/internal/httpServer/include/Router.h @@ -1,20 +1,25 @@ -#ifndef APP_HTTPSERVER_HTTPSERVER_ROUTER_H_ -#define APP_HTTPSERVER_HTTPSERVER_ROUTER_H_ +#ifndef SOURCEDOUT_HTTPSERVER_ROUTER_UTILS_H +#define SOURCEDOUT_HTTPSERVER_ROUTER_UTILS_H #include #include #include +#include #include "SolutionManager.h" #include "UserManager.h" #include "TaskManager.h" -#include "Response.h" -#include "Request.h" -class Router : private boost::noncopyable { +namespace beast = boost::beast; +namespace http = beast::http; +namespace net = boost::asio; + +class Router : public std::enable_shared_from_this { public: - Router(); - void handleRequest(const Request& req, Response& res); + explicit Router(std::string_view doc_root_); + + http::message_generator handleRequest(http::request&& req); + void setSolutionManager(std::shared_ptr mng) { solutionManager = mng; } @@ -28,8 +33,11 @@ class Router : private boost::noncopyable { std::shared_ptr solutionManager; std::shared_ptr userManager; std::shared_ptr taskManager; - static bool decodeUrl(const std::string& in, std::string& out); + std::string doc_root; + + http::response getBadRequest(const http::request& request, + beast::string_view why); }; -#endif // APP_HTTPSERVER_HTTPSERVER_ROUTER_H_ +#endif // SOURCEDOUT_HTTPSERVER_ROUTER_UTILS_H diff --git a/server/internal/httpServer/include/Serializer.h b/server/internal/httpServer/include/Serializer.h index a8a68be..34cb67a 100644 --- a/server/internal/httpServer/include/Serializer.h +++ b/server/internal/httpServer/include/Serializer.h @@ -7,8 +7,20 @@ #include "Solution.hpp" #include "User.hpp" +#include "Task.hpp" -class Serializer {}; +class Serializer { +public: + std::tuple deserialNewSolutionData(const std::string& val); + std::tuple deserialTaskData(const std::string &val); + std::string deserialNewTaskData(const std::string &val); + size_t deserialSolutionData(const std::string& val); + std::tuple deserialUserData(const std::string& val); + std::tuple deserialNewUserData(const std::string &val); + + std::string serialSolutions(const std::vector& solutions); + std::string serialAllTasks(const std::vector& tasks); +}; #endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_SERIALIZER_H_ diff --git a/server/internal/httpServer/include/SolutionManager.h b/server/internal/httpServer/include/SolutionManager.h index 5a11065..2c69a61 100644 --- a/server/internal/httpServer/include/SolutionManager.h +++ b/server/internal/httpServer/include/SolutionManager.h @@ -3,25 +3,26 @@ #include #include +#include -#include "Response.h" -#include "Request.h" #include "Serializer.h" #include "ISolutionManager.h" #include "ISolutionService.h" +namespace beast = boost::beast; +namespace http = boost::beast::http; + class SolutionManager : public ISolutionManager { public: SolutionManager(); - Response getAllSolutions(const Request &req) override; - Response createSolution(const Request &req) override; - Response getMetrics(const Request &req) override; + http::message_generator getAllSolutions(http::request&& req) override; + http::message_generator createSolution(http::request&& req) override; + http::message_generator getMetrics(http::request&& req) override; void setService(std::shared_ptr service); private: std::shared_ptr solutionService; std::shared_ptr serializer; - static std::string getParam(const std::string& path, const std::string& name); }; #endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_SolutionMANAGER_H_ diff --git a/server/internal/httpServer/include/TaskManager.h b/server/internal/httpServer/include/TaskManager.h index c49b08b..3adecd4 100644 --- a/server/internal/httpServer/include/TaskManager.h +++ b/server/internal/httpServer/include/TaskManager.h @@ -4,8 +4,6 @@ #include #include -#include "Response.h" -#include "Request.h" #include "Serializer.h" #include "ITaskManager.h" #include "ITaskService.h" @@ -13,13 +11,12 @@ class TaskManager : public ITaskManager { public: TaskManager(); - Response createTask(const Request &req) override; - Response getAllTasks(const Request &req) override; + http::message_generator createTask(http::request&& req) override; + http::message_generator getAllTasks(http::request&& req) override; void setService(std::shared_ptr service); private: std::shared_ptr taskService; std::shared_ptr serializer; - static std::string getParam(const std::string& path, const std::string& name); }; #endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_TaskMANAGER_H_ diff --git a/server/internal/httpServer/include/UserManager.h b/server/internal/httpServer/include/UserManager.h index 9043ada..01a16de 100644 --- a/server/internal/httpServer/include/UserManager.h +++ b/server/internal/httpServer/include/UserManager.h @@ -4,8 +4,6 @@ #include #include -#include "Response.h" -#include "Request.h" #include "Serializer.h" #include "IUserManager.h" #include "IUserService.h" @@ -13,13 +11,12 @@ class UserManager : public IUserManager { public: UserManager(); - Response loginUser(const Request &req) override; - Response registerUser(const Request &req) override; + http::message_generator loginUser(http::request&& req) override; + http::message_generator registerUser(http::request&& req) override; void setService(std::shared_ptr service); private: std::shared_ptr userService; std::shared_ptr serializer; - static std::string getParam(const std::string& path, const std::string& name); }; #endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_USERMANAGER_H_ diff --git a/server/internal/httpServer/include/Utils.h b/server/internal/httpServer/include/Utils.h new file mode 100644 index 0000000..8311dc7 --- /dev/null +++ b/server/internal/httpServer/include/Utils.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include + +namespace beast = boost::beast; + +void fail(beast::error_code ec, char const* what); diff --git a/server/internal/httpServer/main.cpp b/server/internal/httpServer/main.cpp new file mode 100644 index 0000000..8d48c12 --- /dev/null +++ b/server/internal/httpServer/main.cpp @@ -0,0 +1,48 @@ +#include + +#include + +#include "HttpServer.h" + +namespace net = boost::asio; +using tcp = boost::asio::ip::tcp; + +int main(int argc, char* argv[]) +{ + // Check command line arguments. + if (argc != 5) + { + std::cerr << + "Usage: http-server-async
\n" << + "Example:\n" << + " http-server-async 0.0.0.0 8080 . 1\n"; + return EXIT_FAILURE; + } + auto const address = net::ip::make_address(argv[1]); + auto const port = static_cast(std::atoi(argv[2])); + auto const doc_root = std::make_shared(argv[3]); + auto const threads = std::max(1, std::atoi(argv[4])); + + // The io_context is required for all I/O + net::io_context ioc{threads}; + + // Create and launch a listening port + std::make_shared( + ioc, + tcp::endpoint{address, port}, + doc_root + )->run(); + + // Run the I/O service on the requested number of threads + std::vector v; + v.reserve(threads - 1); + for(auto i = threads - 1; i > 0; --i) + v.emplace_back( + [&ioc] + { + ioc.run(); + }); + ioc.run(); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/server/internal/httpServer/src/HttpConnection.cpp b/server/internal/httpServer/src/HttpConnection.cpp index 412f670..084d91a 100644 --- a/server/internal/httpServer/src/HttpConnection.cpp +++ b/server/internal/httpServer/src/HttpConnection.cpp @@ -2,15 +2,73 @@ #include -HttpConnection::HttpConnection(boost::asio::io_service& io_service) - : strand(io_service), - socket(io_service) {} +#include "Utils.h" -boost::asio::ip::tcp::socket& HttpConnection::getSocket() {} +HttpConnection::HttpConnection(tcp::socket&& socket_, + std::shared_ptr const& doc_root_) + : stream(std::move(socket_)), doc_root(doc_root_) { + router = std::make_shared(*doc_root_); +} -void HttpConnection::start() {} +void HttpConnection::run() { + net::dispatch(stream.get_executor(), + beast::bind_front_handler(&HttpConnection::read, shared_from_this()) + ); +} -void HttpConnection::handleRead(const boost::system::error_code& e, - std::size_t bytes_transferred) {} +void HttpConnection::read() { + request = {}; + stream.expires_after(std::chrono::seconds(30)); + http::async_read(stream, buffer, request, + beast::bind_front_handler( + &HttpConnection::handleRead, + shared_from_this() + ) + ); +} -void HttpConnection::handleWrite(const boost::system::error_code& e) {} +void HttpConnection::handleRead(beast::error_code e, std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + + if(e == http::error::end_of_stream) + return close(); + + if(e) + return fail(e, "read"); + + sendResponse( + router->handleRequest(std::move(request)) + ); +} + +void HttpConnection::sendResponse(http::message_generator &&msg) { + bool keep_alive = msg.keep_alive(); + + beast::async_write( + stream, + std::move(msg), + beast::bind_front_handler( + &HttpConnection::handleWrite, + shared_from_this(), + keep_alive + ) + ); +} + +void HttpConnection::handleWrite(bool keep_alive, beast::error_code e, std::size_t bytes_transferred) { + boost::ignore_unused(bytes_transferred); + + if(e) + return fail(e, "write"); + + if(!keep_alive) { + return close(); + } + + read(); +} + +void HttpConnection::close() { + beast::error_code e; + stream.socket().shutdown(tcp::socket::shutdown_send, e); +} \ No newline at end of file diff --git a/server/internal/httpServer/src/HttpServer.cpp b/server/internal/httpServer/src/HttpServer.cpp index 246b4f0..e00df2a 100644 --- a/server/internal/httpServer/src/HttpServer.cpp +++ b/server/internal/httpServer/src/HttpServer.cpp @@ -1,20 +1,58 @@ #include "HttpServer.h" #include -#include #include -#include -HttpServer::HttpServer(const std::string& address, const std::string& port, std::size_t thread_pool_size) - : thread_pool_size(thread_pool_size), - signals(io_service), - acceptor(io_service), - connection() {} +#include "Utils.h" -void HttpServer::run() {} +HttpServer::HttpServer(net::io_context& io_context_, tcp::endpoint endpoint_, + std::shared_ptr const& doc_root_) + : io_context(io_context_), acceptor(net::make_strand(io_context_)), doc_root(doc_root_) { -void HttpServer::startAccept() {} + beast::error_code ec; + acceptor.open(endpoint_.protocol(), ec); + if(ec) { + fail(ec, "open"); + return; + } -void HttpServer::handleAccept(const boost::system::error_code& e) {} + acceptor.set_option(net::socket_base::reuse_address(true), ec); + if(ec) { + fail(ec, "set_option"); + return; + } -void HttpServer::handleStop() {} + acceptor.bind(endpoint_, ec); + if(ec) { + fail(ec, "bind"); + return; + } + + acceptor.listen(net::socket_base::max_listen_connections, ec); + if(ec) { + fail(ec, "listen"); + return; + } +} + +void HttpServer::run() { + startAccept(); +} + +void HttpServer::startAccept() { + acceptor.async_accept( + net::make_strand(io_context), + beast::bind_front_handler(&HttpServer::handleAccept, shared_from_this()) + ); +} + +void HttpServer::handleAccept(beast::error_code ec, tcp::socket socket) { + if(ec) { + fail(ec, "accept"); + return; + } else { + std::make_shared(std::move(socket), doc_root)->run(); + } + + startAccept(); +} \ No newline at end of file diff --git a/server/internal/httpServer/src/Parser.cpp b/server/internal/httpServer/src/Parser.cpp deleted file mode 100644 index 86b9541..0000000 --- a/server/internal/httpServer/src/Parser.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "Parser.h" -#include "Request.h" - -Parser::Parser() - : state(method_start) {} - -void Parser::reset() {} - -boost::tribool Parser::consume(Request& req, char input) {} - -bool Parser::isChar(int c) {} - -bool Parser::isCtl(int c) {} - -bool Parser::isTspecial(int c) {} - -bool Parser::isDigit(int c) {} diff --git a/server/internal/httpServer/src/Response.cpp b/server/internal/httpServer/src/Response.cpp deleted file mode 100644 index f688c34..0000000 --- a/server/internal/httpServer/src/Response.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Response.h" - -std::vector Response::toBuffers() {} - -Response Response::stockResponse(Response::status_type status) {} diff --git a/server/internal/httpServer/src/Router.cpp b/server/internal/httpServer/src/Router.cpp index e235dee..59b5791 100644 --- a/server/internal/httpServer/src/Router.cpp +++ b/server/internal/httpServer/src/Router.cpp @@ -2,14 +2,54 @@ #include #include -#include -#include "Response.h" +#include "Utils.h" -Router::Router() : +http::response Router::getBadRequest(const http::request& request, + beast::string_view why) { + http::response res{http::status::bad_request, request.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/plain"); + res.keep_alive(request.keep_alive()); + res.body() = std::string(why); + res.prepare_payload(); + return res; +} + +Router::Router(std::string_view doc_root_) : solutionManager(std::make_shared()), - userManager(std::make_shared()) {} + userManager(std::make_shared()), + taskManager(std::make_shared()), + doc_root(doc_root_) {} + + +http::message_generator Router::handleRequest(http::request &&req) { + + if(req.method() != http::verb::get && req.method() != http::verb::post) + return getBadRequest(req, "Unknown HTTP-method"); + + if(req.target().empty() || req.target()[0] != '/' || + req.target().find("..") != beast::string_view::npos) { + return getBadRequest(req, "Illegal request-target"); + } + + std::cout << req.target() << std::endl; -void Router::handleRequest(const Request& req, Response& res) {} + if (req.target() == "/solution/submit") { + return solutionManager->createSolution(std::move(req)); + } else if (req.target() == "/solution/metrics") { + return solutionManager->getMetrics(std::move(req)); + } else if (req.target() == "/solution/all") { + return solutionManager->getAllSolutions(std::move(req)); + } else if (req.target() == "/user/register") { + return userManager->registerUser(std::move(req)); + } else if (req.target() == "/user/login") { + return userManager->loginUser(std::move(req)); + } else if (req.target() == "/task/create") { + return taskManager->createTask(std::move(req)); + } else if (req.target() == "/task/all") { + return taskManager->getAllTasks(std::move(req)); + } -bool Router::decodeUrl(const std::string& in, std::string& out) {} + return getBadRequest(req, "Unknown request-target"); +} \ No newline at end of file diff --git a/server/internal/httpServer/src/Serializer.cpp b/server/internal/httpServer/src/Serializer.cpp new file mode 100644 index 0000000..8d2569a --- /dev/null +++ b/server/internal/httpServer/src/Serializer.cpp @@ -0,0 +1,103 @@ +#include "Serializer.h" + +#include +#include +#include + +std::tuple Serializer::deserialNewSolutionData(const std::string &val) { + std::stringstream ss; + ss << val; + boost::property_tree::ptree json; + boost::property_tree::read_json(ss, json); + std::tuple res = { + json.get("user_id"), + json.get("source"), + json.get("task_id") + }; + return res; +} + +size_t Serializer::deserialSolutionData(const std::string &val) { + std::stringstream ss; + ss << val; + boost::property_tree::ptree json; + boost::property_tree::read_json(ss, json); + return json.get("sol_id"); +} + +std::tuple Serializer::deserialTaskData(const std::string &val) { + std::stringstream ss; + ss << val; + boost::property_tree::ptree json; + boost::property_tree::read_json(ss, json); + std::tuple res = { + json.get("user_id"), + json.get("task_id") + }; + return res; +} + +std::string Serializer::deserialNewTaskData(const std::string &val) { + std::stringstream ss; + ss << val; + boost::property_tree::ptree json; + boost::property_tree::read_json(ss, json); + return json.get("description"); +} + +std::tuple Serializer::deserialUserData(const std::string &val) { + std::stringstream ss; + ss << val; + boost::property_tree::ptree json; + boost::property_tree::read_json(ss, json); + std::tuple res = { + json.get("login"), + json.get("password") + }; + return res; +} + +std::tuple Serializer::deserialNewUserData(const std::string &val) { + std::stringstream ss; + ss << val; + boost::property_tree::ptree json; + boost::property_tree::read_json(ss, json); + std::tuple res = { + json.get("login"), + json.get("password"), + json.get("username") + }; + return res; +} + +std::string Serializer::serialSolutions(const std::vector &solutions) { + boost::property_tree::ptree json; + json.put("count", solutions.size()); + boost::property_tree::ptree solutions_nodes; + for (auto &i : solutions) { + boost::property_tree::ptree node; + node.put("sol_id", i.getId()); + node.put("task_id", i.getTaskId()); + solutions_nodes.push_back(std::make_pair("", node)); + } + json.add_child("solutions", solutions_nodes); + std::stringstream out; + boost::property_tree::write_json(out, json); + return out.str(); +} + +std::string Serializer::serialAllTasks(const std::vector &tasks) { + boost::property_tree::ptree json; + json.put("count", tasks.size()); + boost::property_tree::ptree tasks_nodes; + for (auto &i : tasks) { + boost::property_tree::ptree node; + node.put("task_id", i.getId()); + node.put("description", i.getDescription()); + tasks_nodes.push_back(std::make_pair("", node)); + } + json.add_child("tasks", tasks_nodes); + std::stringstream out; + boost::property_tree::write_json(out, json); + return out.str(); +} diff --git a/server/internal/httpServer/src/SolutionManager.cpp b/server/internal/httpServer/src/SolutionManager.cpp index 3a93e41..e83c027 100644 --- a/server/internal/httpServer/src/SolutionManager.cpp +++ b/server/internal/httpServer/src/SolutionManager.cpp @@ -3,24 +3,59 @@ // #include "SolutionManager.h" -SolutionManager::SolutionManager() {} +#include -Response SolutionManager::getAllSolutions(const Request &req) { - return Response(); -} +SolutionManager::SolutionManager() : + serializer(std::make_shared()) {}; -Response SolutionManager::createSolution(const Request &req) { - return Response(); +void SolutionManager::setService(std::shared_ptr service) { + solutionService = std::move(service); } -Response SolutionManager::getMetrics(const Request &req) { - return Response(); +http::message_generator SolutionManager::createSolution(http::request&& req) { + + size_t user_id, task_id; + std::string source; + std::tie(user_id, source, task_id) = serializer->deserialNewSolutionData(req.body()); + Solution sol; + sol = solutionService->createSolution(user_id, task_id, source); + http::response res{http::status::ok, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/plain"); + res.keep_alive(req.keep_alive()); + res.body() = std::to_string(sol.getId()); + res.prepare_payload(); + return res; } -std::string SolutionManager::getParam(const std::string &path, const std::string &name) { - return std::string(); +http::message_generator SolutionManager::getAllSolutions(http::request&& req) { + size_t user_id, task_id; + std::tie(user_id, task_id) = serializer->deserialTaskData(req.body()); + std::vector solutions; + solutions = solutionService->getSolutionsByUserAndTaskId(user_id, task_id); + http::response res{http::status::ok, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/plain"); + res.keep_alive(req.keep_alive()); + res.body() = serializer->serialSolutions(solutions); + res.prepare_payload(); + return res; + } -void SolutionManager::setService(std::shared_ptr service) { - solutionService = service; +http::message_generator SolutionManager::getMetrics(http::request&& req) { + auto const bad_request = + [&req](beast::string_view why) + { + http::response res{http::status::bad_request, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/html"); + res.keep_alive(req.keep_alive()); + res.body() = std::string(why); + res.prepare_payload(); + return res; + }; + + return bad_request("123"); } + diff --git a/server/internal/httpServer/src/TaskManager.cpp b/server/internal/httpServer/src/TaskManager.cpp index ca3875d..2b45867 100644 --- a/server/internal/httpServer/src/TaskManager.cpp +++ b/server/internal/httpServer/src/TaskManager.cpp @@ -3,22 +3,30 @@ // #include "TaskManager.h" -TaskManager::TaskManager() { +TaskManager::TaskManager() : serializer(std::make_shared()) {} +void TaskManager::setService(std::shared_ptr service) { + taskService = service; } -Response TaskManager::createTask(const Request &req) { - return Response(); -} - -Response TaskManager::getAllTasks(const Request &req) { - return Response(); -} - -std::string TaskManager::getParam(const std::string &path, const std::string &name) { - return std::string(); +http::message_generator TaskManager::createTask(http::request &&req) { + std::string description = serializer->deserialNewTaskData(req.body()); + taskService->createTask(description); + http::response res{http::status::ok, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/plain"); + res.keep_alive(req.keep_alive()); + res.prepare_payload(); + return res; } -void TaskManager::setService(std::shared_ptr service) { - taskService = service; +http::message_generator TaskManager::getAllTasks(http::request &&req) { + std::vector tasks = taskService->getAllTasks(); + http::response res{http::status::ok, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/plain"); + res.keep_alive(req.keep_alive()); + res.body() = serializer->serialAllTasks(tasks); + res.prepare_payload(); + return res; } diff --git a/server/internal/httpServer/src/UserManager.cpp b/server/internal/httpServer/src/UserManager.cpp index 4137716..4048afd 100644 --- a/server/internal/httpServer/src/UserManager.cpp +++ b/server/internal/httpServer/src/UserManager.cpp @@ -1,24 +1,41 @@ -// -// Created by Николай Степанов on 03.05.2023. -// #include "UserManager.h" -UserManager::UserManager() { +UserManager::UserManager() : serializer(std::make_shared()) {} +void UserManager::setService(std::shared_ptr service) { + userService = service; } -Response UserManager::loginUser(const Request &req) { - return Response(); -} +http::message_generator UserManager::loginUser(http::request &&req) { -Response UserManager::registerUser(const Request &req) { - return Response(); -} + std::string login, password; + std::tie(login, password) = serializer->deserialUserData(req.body()); + /// TODO -std::string UserManager::getParam(const std::string &path, const std::string &name) { - return std::string(); + auto const bad_request = + [&req](beast::string_view why) + { + http::response res{http::status::bad_request, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/html"); + res.keep_alive(req.keep_alive()); + res.body() = std::string(why); + res.prepare_payload(); + return res; + }; + + return bad_request("123"); } -void UserManager::setService(std::shared_ptr service) { - userService = service; +http::message_generator UserManager::registerUser(http::request &&req) { + std::string login, password, username; + std::tie(login, password, username) = serializer->deserialNewUserData(req.body()); + User user = userService->createUser(login, username, password); + http::response res{http::status::ok, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/plain"); + res.keep_alive(req.keep_alive()); + res.body() = std::to_string(user.getId()); + res.prepare_payload(); + return res; } diff --git a/server/internal/httpServer/src/Utils.cpp b/server/internal/httpServer/src/Utils.cpp new file mode 100644 index 0000000..416b658 --- /dev/null +++ b/server/internal/httpServer/src/Utils.cpp @@ -0,0 +1,6 @@ +#include "Utils.h" + + +void fail(beast::error_code ec, const char *what) { + std::cerr << what << ": " << ec.message() << "\n"; +} diff --git a/server/internal/httpServer/virtual/ISolutionManager.h b/server/internal/httpServer/virtual/ISolutionManager.h index cd77215..ab86bc6 100644 --- a/server/internal/httpServer/virtual/ISolutionManager.h +++ b/server/internal/httpServer/virtual/ISolutionManager.h @@ -1,17 +1,16 @@ #ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_ISolutionMANAGER_H_ #define APP_HTTPSERVER_HTTPSERVER_MANAGERS_ISolutionMANAGER_H_ -#include -#include +#include -#include "Response.h" -#include "Request.h" +namespace beast = boost::beast; +namespace http = boost::beast::http; class ISolutionManager { public: - virtual Response getAllSolutions(const Request &req) = 0; - virtual Response createSolution(const Request &req) = 0; - virtual Response getMetrics(const Request &req) = 0; + virtual http::message_generator getAllSolutions(http::request&& req) = 0; + virtual http::message_generator createSolution(http::request&& req) = 0; + virtual http::message_generator getMetrics(http::request&& req) = 0; }; #endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_ISolutionMANAGER_H_ diff --git a/server/internal/httpServer/virtual/ITaskManager.h b/server/internal/httpServer/virtual/ITaskManager.h index 11747f7..260e2a0 100644 --- a/server/internal/httpServer/virtual/ITaskManager.h +++ b/server/internal/httpServer/virtual/ITaskManager.h @@ -4,14 +4,15 @@ #include #include -#include "Response.h" -#include "Request.h" -#include "Serializer.h" +#include + +namespace beast = boost::beast; +namespace http = boost::beast::http; class ITaskManager { public: - virtual Response createTask(const Request &req) = 0; - virtual Response getAllTasks(const Request &req) = 0; + virtual http::message_generator createTask(http::request&& req) = 0; + virtual http::message_generator getAllTasks(http::request&& req) = 0; }; #endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_ITaskMANAGER_H_ diff --git a/server/internal/httpServer/virtual/IUserManager.h b/server/internal/httpServer/virtual/IUserManager.h index 599a8ec..913e4e8 100644 --- a/server/internal/httpServer/virtual/IUserManager.h +++ b/server/internal/httpServer/virtual/IUserManager.h @@ -4,14 +4,15 @@ #include #include -#include "Response.h" -#include "Request.h" -#include "Serializer.h" +#include + +namespace beast = boost::beast; +namespace http = boost::beast::http; class IUserManager { public: - virtual Response loginUser(const Request &req) = 0; - virtual Response registerUser(const Request &req) = 0; + virtual http::message_generator loginUser(http::request&& req) = 0; + virtual http::message_generator registerUser(http::request&& req) = 0; }; #endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_IUserMANAGER_H_ diff --git a/server/internal/repository/include/SolutionRepository.hpp b/server/internal/repository/include/SolutionRepository.hpp index 04034d5..e7fb74f 100644 --- a/server/internal/repository/include/SolutionRepository.hpp +++ b/server/internal/repository/include/SolutionRepository.hpp @@ -10,7 +10,7 @@ using namespace pqxx; -class SolutionRepository : ISolutionRepository { +class SolutionRepository : public ISolutionRepository { Solution getSolutionById(size_t id) override; std::vector getSolutionsBySenderId(size_t sender_id) override; diff --git a/server/internal/repository/include/UserRepository.hpp b/server/internal/repository/include/UserRepository.hpp index a8bd86d..7b67746 100644 --- a/server/internal/repository/include/UserRepository.hpp +++ b/server/internal/repository/include/UserRepository.hpp @@ -9,7 +9,7 @@ #include using namespace pqxx; -class UserRepository : IUserRepository { +class UserRepository : public IUserRepository { public: explicit UserRepository(); diff --git a/server/internal/service/include/SolutionService.h b/server/internal/service/include/SolutionService.h index 86e432b..2ebcf72 100644 --- a/server/internal/service/include/SolutionService.h +++ b/server/internal/service/include/SolutionService.h @@ -10,7 +10,7 @@ class SolutionService : ISolutionService { std::unique_ptr solutionRepo; // std::unique_ptr antlr public: - explicit SolutionService(std::unique_ptr solutionRepo); + explicit SolutionService(); Solution createSolution(size_t userId, size_t taskId, std::string source) override; std::vector getSolutionsByUserAndTaskId(size_t userId, diff --git a/server/internal/service/include/TaskService.h b/server/internal/service/include/TaskService.h index bf04d3e..d2f67b9 100644 --- a/server/internal/service/include/TaskService.h +++ b/server/internal/service/include/TaskService.h @@ -10,7 +10,7 @@ class TaskService : public ITaskService { std::unique_ptr taskRepo; public: - TaskService(std::unique_ptr taskRepo); + TaskService(); ~TaskService() override = default; Task createTask(std::string desc) override; Task getTask(size_t id) override; diff --git a/server/internal/service/include/UserService.h b/server/internal/service/include/UserService.h index 719aa02..e5865c3 100644 --- a/server/internal/service/include/UserService.h +++ b/server/internal/service/include/UserService.h @@ -7,11 +7,11 @@ class UserService : IUserService { private: - std::unique_ptr userRepo; + std::unique_ptr userRepo = std::make_unique(); public: ~UserService() override = default; - explicit UserService(std::unique_ptr userRepo); + explicit UserService(); User createUser(std::string login, std::string username, std::string password) override; User getUserById(size_t id) override; diff --git a/server/internal/service/src/SolutionService.cpp b/server/internal/service/src/SolutionService.cpp index ba707c3..7e3701a 100644 --- a/server/internal/service/src/SolutionService.cpp +++ b/server/internal/service/src/SolutionService.cpp @@ -1,8 +1,9 @@ #include "SolutionService.h" -SolutionService::SolutionService( - std::unique_ptr solutionRepo) - : solutionRepo(std::move(solutionRepo)) {} +#include "SolutionRepository.hpp" + +SolutionService::SolutionService() + : solutionRepo(std::make_unique()) {} Solution SolutionService::createSolution(size_t userId, size_t taskId, std::string source) { diff --git a/server/internal/service/src/TaskService.cpp b/server/internal/service/src/TaskService.cpp index a3ce5ef..d083a79 100644 --- a/server/internal/service/src/TaskService.cpp +++ b/server/internal/service/src/TaskService.cpp @@ -1,7 +1,10 @@ #include "TaskService.h" -TaskService::TaskService(std::unique_ptr taskRepo) - : taskRepo(std::move(taskRepo)) {} +#include "TaskRepository.hpp" + +TaskService::TaskService() + : taskRepo(std::make_unique()) { +} Task TaskService::createTask(std::string desc) { size_t id = taskRepo->storeTask(Task(desc)); diff --git a/server/internal/service/src/UserService.cpp b/server/internal/service/src/UserService.cpp index 270f801..c2cfa72 100644 --- a/server/internal/service/src/UserService.cpp +++ b/server/internal/service/src/UserService.cpp @@ -1,9 +1,11 @@ #include "UserService.h" #include "Exeptions.h" +#include "UserRepository.hpp" -UserService::UserService(std::unique_ptr userRepo) - : userRepo(std::move(userRepo)) {} +UserService::UserService() + : userRepo(std::make_unique()) { +} User UserService::createUser(std::string login, std::string username, std::string password) { -- GitLab From ebfdd1ce7690ce1ccc9a71213d1fcbef3651632f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9=20=D0=A1=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Thu, 11 May 2023 11:02:21 +0300 Subject: [PATCH 4/8] Refactor HttpClient --- .../internal/httpClient/include/ClientTypes.h | 34 ----------- .../internal/httpClient/include/HttpClient.h | 46 +++++++------- .../httpClient/include/HttpClientManager.h | 16 ++--- .../internal/httpClient/include/Serializer.h | 2 - client/internal/httpClient/src/HttpClient.cpp | 60 ++++++++++--------- .../httpClient/src/HttpClientManager.cpp | 17 +++--- .../internal/httpClient/virtual/IHttpClient.h | 25 ++++---- 7 files changed, 80 insertions(+), 120 deletions(-) delete mode 100644 client/internal/httpClient/include/ClientTypes.h diff --git a/client/internal/httpClient/include/ClientTypes.h b/client/internal/httpClient/include/ClientTypes.h deleted file mode 100644 index 9ba6e87..0000000 --- a/client/internal/httpClient/include/ClientTypes.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef APP_HTTPCLIENT_HTTPCLIENT_CLIENTTYPES_H_ -#define APP_HTTPCLIENT_HTTPCLIENT_CLIENTTYPES_H_ - -#include -#include -#include -#include -#include - -using Response = boost::beast::http::response; -using Request = boost::beast::http::request; - -using Params = std::map; - -struct Header { - std::string name; - std::string values; -}; - -struct ResponseStruct { - unsigned int status; - std::string body; - std::vector
headers; -}; - -struct Host { - std::string domain; - std::string ip; - unsigned short port; - Host(std::string domain, std::string ip, unsigned short port) - : domain(std::move(domain)), ip(std::move(ip)), port(port) {} -}; - -#endif // APP_HTTPCLIENT_HTTPCLIENT_CLIENTTYPES_H_ diff --git a/client/internal/httpClient/include/HttpClient.h b/client/internal/httpClient/include/HttpClient.h index 99e7fb0..058c2b4 100644 --- a/client/internal/httpClient/include/HttpClient.h +++ b/client/internal/httpClient/include/HttpClient.h @@ -5,36 +5,30 @@ #include #include #include +#include -#include "ClientTypes.h" -#include "Serializer.h" #include "IHttpClient.h" +namespace beast = boost::beast; +namespace http = beast::http; +namespace net = boost::asio; +using tcp = net::ip::tcp; + class HttpClient : public IHttpClient { - public: - HttpClient(); - ResponseStruct makeGetRequest(const Host& host, const std::string& target, - const std::shared_ptr& params = nullptr, - const std::shared_ptr& headers = nullptr) override; - ResponseStruct makePostRequest(const Host& host, const std::string& target, - const std::shared_ptr& body, - const std::shared_ptr& headers = nullptr) override; - - private: - ResponseStruct parseResponse(Response response) override; - std::string createURL(const std::string& target, const std::shared_ptr& params = nullptr) override; - bool connect(unsigned short port) override; - ResponseStruct makeRequest(const Host& host, const std::string& target, boost::beast::http::verb method, - const std::shared_ptr& params = nullptr, - const std::shared_ptr& body = nullptr, - const std::shared_ptr& headers = nullptr) override; - - boost::asio::io_context context; - boost::asio::ip::tcp::resolver resolver; - boost::asio::ip::tcp::socket socket; - std::string ip; - boost::beast::flat_buffer flat_buffer; - Serializer serializer; +public: + HttpClient(std::string_view host, std::string_view port); + http::response makeGetRequest(std::string_view target, std::string_view body) override; + http::response makePostRequest(std::string_view target, std::string_view body) override; + +private: + http::response makeRequest(std::string_view target, + http::verb method, + std::string_view body) override; + + net::io_context io_context{}; + tcp::resolver resolver; + beast::tcp_stream stream; + std::string host; }; diff --git a/client/internal/httpClient/include/HttpClientManager.h b/client/internal/httpClient/include/HttpClientManager.h index 1d31ce3..7c3ed33 100644 --- a/client/internal/httpClient/include/HttpClientManager.h +++ b/client/internal/httpClient/include/HttpClientManager.h @@ -10,23 +10,25 @@ #include "Solution.h" #include "Task.h" #include "Metric.h" +#include "Serializer.h" class HttpClientManager { - public: - HttpClientManager(const std::string &domain, const std::string &ip, const unsigned short &port, - std::string saved_path_); +public: + HttpClientManager(std::string_view host_, std::string_view port_, std::string_view saved_path_); + unsigned int loginUser(const std::string &login, const std::string &password); unsigned int registerUser(const std::string &login, const std::string &username, const std::string &password); - unsigned int submitSolution(const int& user_id, const std::string &path_to_sound); + unsigned int submitSolution(const int& user_id, const std::string &path_to_solution); unsigned int getAllSolutionsForTask(const int& user_id, const int& task_id); std::vector getAllTasks(); std::vector getMetrics(const int& sol_id); void setHttpClient(std::shared_ptr client_); - private: +private: std::string saved_path; - Host host; + std::string host; + std::string port; std::shared_ptr client; - Serializer serializer; + std::shared_ptr serializer; }; diff --git a/client/internal/httpClient/include/Serializer.h b/client/internal/httpClient/include/Serializer.h index 31d4468..4f4dc32 100644 --- a/client/internal/httpClient/include/Serializer.h +++ b/client/internal/httpClient/include/Serializer.h @@ -5,8 +5,6 @@ #include #include -#include "ClientTypes.h" - class Serializer {}; diff --git a/client/internal/httpClient/src/HttpClient.cpp b/client/internal/httpClient/src/HttpClient.cpp index 93881ff..d9f09fe 100644 --- a/client/internal/httpClient/src/HttpClient.cpp +++ b/client/internal/httpClient/src/HttpClient.cpp @@ -1,32 +1,38 @@ #include "httpClient.h" -#include #include -#include -#include -#include #include -using Error = boost::system::system_error; - -std::string HttpClient::createURL(const std::string& target, const std::shared_ptr& params) {} - -bool HttpClient::connect(unsigned short port = 80) {} - -HttpClient::HttpClient() : socket(context), resolver(context) {} - -ResponseStruct HttpClient::makeRequest(const Host &host, const std::string &target, - const boost::beast::http::verb method, - const std::shared_ptr& params, - const std::shared_ptr& body, - const std::shared_ptr& headers) {} - -ResponseStruct HttpClient::parseResponse(Response response) {} - -ResponseStruct HttpClient::makeGetRequest(const Host &host, const std::string &target, - const std::shared_ptr& params, - const std::shared_ptr& headers) {} - -ResponseStruct HttpClient::makePostRequest(const Host &host, const std::string &target, - const std::shared_ptr& body, - const std::shared_ptr& headers) {} +HttpClient::HttpClient(std::string_view host_, std::string_view port) : + host(host_), + resolver(io_context), + stream(io_context) { + auto const results = resolver.resolve(host, port); + stream.connect(results); +} + +http::response HttpClient::makeRequest(std::string_view target, + http::verb method, + std::string_view body) { + http::request req{http::verb::get, target, 10}; + req.set(http::field::host, host); + req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING); + + http::write(stream, req); + + beast::flat_buffer buffer; + http::response res; + http::read(stream, buffer, res); + + return res; +} + +http::response HttpClient::makeGetRequest(std::string_view target, + std::string_view body) { + return makeRequest(target, http::verb::get, body); +} + +http::response HttpClient::makePostRequest(std::string_view target, + std::string_view body) { + return makeRequest(target, http::verb::post, body); +} diff --git a/client/internal/httpClient/src/HttpClientManager.cpp b/client/internal/httpClient/src/HttpClientManager.cpp index 57e1a88..9d7b1e4 100644 --- a/client/internal/httpClient/src/HttpClientManager.cpp +++ b/client/internal/httpClient/src/HttpClientManager.cpp @@ -1,19 +1,18 @@ -#include "httpClientManager.h" +#include "HttpClientManager.h" -#include -#include #include #include #include -HttpClientManager::HttpClientManager(const std::string &domain, - const std::string &ip, - const unsigned short &port, - std::string saved_path_) - : host(domain, ip, port), client(), serializer(), saved_path(std::move(saved_path_)) {} +#include "HttpClient.h" + +HttpClientManager::HttpClientManager(std::string_view host_, std::string_view port_, std::string_view saved_path_) : + host(host_), port(port_), saved_path(saved_path_), + client(std::make_shared(host_, port_)), + serializer(std::make_shared()) {} unsigned int HttpClientManager::loginUser(const std::string &login, const std::string &password) { - return 0; + } unsigned int HttpClientManager::registerUser(const std::string &login, const std::string &username, diff --git a/client/internal/httpClient/virtual/IHttpClient.h b/client/internal/httpClient/virtual/IHttpClient.h index e24e15d..9de99fc 100644 --- a/client/internal/httpClient/virtual/IHttpClient.h +++ b/client/internal/httpClient/virtual/IHttpClient.h @@ -5,27 +5,22 @@ #include #include #include +#include -#include "clientTypes.h" -#include "serializer.h" +namespace beast = boost::beast; +namespace http = beast::http; +namespace net = boost::asio; +using tcp = net::ip::tcp; class IHttpClient { public: - virtual ResponseStruct makeGetRequest(const Host& host, const std::string& target, - const std::shared_ptr& params = nullptr, - const std::shared_ptr& headers = nullptr) = 0; - virtual ResponseStruct makePostRequest(const Host& host, const std::string& target, - const std::shared_ptr& body, - const std::shared_ptr& headers = nullptr) = 0; + virtual http::response makeGetRequest(std::string_view target, std::string_view body) = 0; + virtual http::response makePostRequest(std::string_view target, std::string_view body) = 0; protected: - virtual ResponseStruct parseResponse(Response response) = 0; - virtual std::string createURL(const std::string& target, const std::shared_ptr& params = nullptr) = 0; - virtual bool connect(unsigned short port) = 0; - virtual ResponseStruct makeRequest(const Host& host, const std::string& target, boost::beast::http::verb method, - const std::shared_ptr& params = nullptr, - const std::shared_ptr& body = nullptr, - const std::shared_ptr& headers = nullptr) = 0; + virtual http::response makeRequest(std::string_view target, + http::verb method, + std::string_view body) = 0; }; -- GitLab From 2e3d634c77391ae7ab2e441667378c04840030bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9=20=D0=A1=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Thu, 11 May 2023 17:06:00 +0300 Subject: [PATCH 5/8] add gui --- client/internal/entities/include/Task.h | 22 +--- client/internal/entities/src/Task.cpp | 21 ---- client/internal/gui/CMakeLists.txt | 6 + client/internal/gui/include/AuthDialog.h | 18 +-- client/internal/gui/include/EntryWindow.h | 20 ++-- client/internal/gui/include/SignUpDialog.h | 30 ++--- client/internal/gui/include/SolutionsWindow.h | 43 +++++++ client/internal/gui/include/StatsDialog.h | 25 ---- client/internal/gui/include/TasksWindow.h | 45 ++++++++ client/internal/gui/include/UIManager.h | 17 +-- client/internal/gui/include/UserWindow.h | 46 -------- client/internal/gui/main.cpp | 13 +++ client/internal/gui/src/AuthDialog.cpp | 81 ++++++++++++- client/internal/gui/src/EntryWindow.cpp | 86 ++++++++++++-- client/internal/gui/src/SignUpDialog.cpp | 102 ++++++++++++++++- client/internal/gui/src/SolutionsWindow.cpp | 80 +++++++++++++ client/internal/gui/src/TasksWindow.cpp | 107 ++++++++++++++++++ client/internal/gui/src/UIManager.cpp | 16 ++- client/internal/gui/src/UserWindow.cpp | 9 -- client/internal/gui/tests/main.cpp | 6 +- 20 files changed, 601 insertions(+), 192 deletions(-) delete mode 100644 client/internal/entities/src/Task.cpp create mode 100644 client/internal/gui/include/SolutionsWindow.h delete mode 100644 client/internal/gui/include/StatsDialog.h create mode 100644 client/internal/gui/include/TasksWindow.h delete mode 100644 client/internal/gui/include/UserWindow.h create mode 100644 client/internal/gui/main.cpp create mode 100644 client/internal/gui/src/SolutionsWindow.cpp create mode 100644 client/internal/gui/src/TasksWindow.cpp delete mode 100644 client/internal/gui/src/UserWindow.cpp diff --git a/client/internal/entities/include/Task.h b/client/internal/entities/include/Task.h index d51c17f..9d87ca6 100644 --- a/client/internal/entities/include/Task.h +++ b/client/internal/entities/include/Task.h @@ -1,23 +1,11 @@ #ifndef SOURCEDOUT_TASK_HPP #define SOURCEDOUT_TASK_HPP -#include -#include -class Task{ -private: - size_t id; - std::string description; - -public: - Task()=default; - ~Task() = default; - Task(size_t id, std::string description); - - explicit Task(std::string description); - [[nodiscard]] size_t getId() const; - - [[nodiscard]] const std::string &getDescription() const; +#include - void setDescription(const std::string &description); +struct Task{ + std::size_t id; + std::string description; }; + #endif //SOURCEDOUT_TASK_HPP \ No newline at end of file diff --git a/client/internal/entities/src/Task.cpp b/client/internal/entities/src/Task.cpp deleted file mode 100644 index 7dd9bfe..0000000 --- a/client/internal/entities/src/Task.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "Task.h" -#include -#include - -unsigned long Task::getId() const { - return id; -} - -Task::Task(size_t id, std::string description) : id(id), description(std::move(description)) {} - -Task::Task(std::string description) : id(0), description(std::move(description)) {} - -const std::string &Task::getDescription() const { - return description; -} - -void Task::setDescription(const std::string &description_) { - Task::description = description_; -} \ No newline at end of file diff --git a/client/internal/gui/CMakeLists.txt b/client/internal/gui/CMakeLists.txt index 60da13c..1f206bf 100644 --- a/client/internal/gui/CMakeLists.txt +++ b/client/internal/gui/CMakeLists.txt @@ -1,6 +1,9 @@ project("GuiLib") set(CMAKE_CXX_STANDARD 20) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) file(GLOB INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include) @@ -20,5 +23,8 @@ set(GUI_lib_LIB ${GUI_lib_LIB} PARENT_SCOPE) set(GUI_lib_INCLUDE_DIRS ${INCLUDE_DIRS}) set(GUI_lib_INCLUDE_DIRS ${GUI_lib_INCLUDE_DIRS} PARENT_SCOPE) +add_executable(gui_run main.cpp) +target_link_libraries(gui_run ${GUI_lib_LIB}) + enable_testing() add_subdirectory(tests) \ No newline at end of file diff --git a/client/internal/gui/include/AuthDialog.h b/client/internal/gui/include/AuthDialog.h index 76b3f9b..b8917b8 100644 --- a/client/internal/gui/include/AuthDialog.h +++ b/client/internal/gui/include/AuthDialog.h @@ -6,38 +6,32 @@ #include #include #include +#include +#include class AuthDialog : public QDialog { Q_OBJECT public: explicit AuthDialog(QWidget *parent = nullptr); - ~AuthDialog() override; -signals: - void showMainWindow(); - void showUserWindow(); - -private slots: +public slots: void on_loginButton_clicked(); void on_backButton_clicked(); private: - QGroupBox *groupBox = nullptr; - QWidget *layoutWidget = nullptr; QVBoxLayout *verticalLayout = nullptr; - QHBoxLayout *horizontalLayout = nullptr; + QWidget *fields = nullptr; + QFormLayout* fieldsLayout = nullptr; QLabel *loginLabel = nullptr; QLineEdit *login = nullptr; - QHBoxLayout *horizontalLayout_2 = nullptr; QLabel *passwordLabel = nullptr; QLineEdit *password = nullptr; QPushButton *loginButton = nullptr; QPushButton *backButton = nullptr; void setupUi(QDialog *AuthDialog); - - void setTexts(QDialog *AuthDialog); + void retranslateUi(QDialog *AuthDialog); }; #endif // AUTH_DIALOG_H diff --git a/client/internal/gui/include/EntryWindow.h b/client/internal/gui/include/EntryWindow.h index b7acbd0..4bc4f11 100644 --- a/client/internal/gui/include/EntryWindow.h +++ b/client/internal/gui/include/EntryWindow.h @@ -14,19 +14,17 @@ Q_OBJECT public: EntryWindow(QWidget *parent = nullptr); - ~EntryWindow() override; - std::shared_ptr getSignUpDialog(); - std::shared_ptr getAuthDialog(); +signals: + void showTasksWindow(); -private slots: - static void onExitButtonClicked(); - void onLoginButtonClicked(); - void onSignUpButtonClicked(); +public slots: + void on_exitButton_clicked(); + void on_loginButton_clicked(); + void on_signUpButton_clicked(); private: - std::shared_ptr authDialog = nullptr; - std::shared_ptr signUpDialog = nullptr; + QWidget *centralwidget = nullptr; QVBoxLayout *verticalLayout = nullptr; QLabel *introLabel = nullptr; @@ -38,8 +36,8 @@ private: QMenuBar *menubar = nullptr; QStatusBar *statusbar = nullptr; - void setupUi(QMainWindow *MainWindow); - void retranslateUi(QMainWindow *MainWindow); + void setupUi(QMainWindow *EntryWindow); + void retranslateUi(QMainWindow *EntryWindow); }; #endif // MAINWINDOW_H diff --git a/client/internal/gui/include/SignUpDialog.h b/client/internal/gui/include/SignUpDialog.h index 2882b24..f9da4f5 100644 --- a/client/internal/gui/include/SignUpDialog.h +++ b/client/internal/gui/include/SignUpDialog.h @@ -6,36 +6,30 @@ #include #include #include +#include class SignUpDialog : public QDialog { Q_OBJECT public: explicit SignUpDialog(QWidget *parent = nullptr); - ~SignUpDialog() override; - -signals: - void showEntryWindow(); - void showUserWindow(); private slots: - void on_signUpButton_clicked() {}; - void on_backButton_clicked() {}; + void on_signUpButton_clicked(); + void on_backButton_clicked(); private: - QGroupBox *groupBox = nullptr; - QWidget *layoutWidget = nullptr; - QVBoxLayout *verticalLayout_2 = nullptr; QVBoxLayout *verticalLayout = nullptr; - QGridLayout *gridLayout = nullptr; - QLabel *enterLoginLabel = nullptr; + QWidget *fields = nullptr; + QFormLayout* fieldsLayout = nullptr; + QLabel *loginLabel = nullptr; QLineEdit *login = nullptr; - QGridLayout *gridLayout_2 = nullptr; - QLineEdit *pass = nullptr; - QLabel *enterPasswordLabel = nullptr; - QHBoxLayout *horizontalLayout_3 = nullptr; - QLabel *repeatPasswordLabel = nullptr; - QLineEdit *passRepeat = nullptr; + QLabel* usernameLabel = nullptr; + QLineEdit *username = nullptr; + QLabel *passwordLabel = nullptr; + QLineEdit *password = nullptr; + QLabel *passwordRepeatLabel = nullptr; + QLineEdit *passwordRepeat = nullptr; QPushButton *signUpButton = nullptr; QPushButton *backButton = nullptr; diff --git a/client/internal/gui/include/SolutionsWindow.h b/client/internal/gui/include/SolutionsWindow.h new file mode 100644 index 0000000..103c2fb --- /dev/null +++ b/client/internal/gui/include/SolutionsWindow.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Task.h" +#include "TasksWindow.h" + +class SolutionsWindow : public QMainWindow { +Q_OBJECT + +public: + explicit SolutionsWindow(Task task, QWidget *parent = nullptr); + +private slots: + void on_backButton_clicked(); + void on_chooseFileButton_clicked(); + void on_sendButton_clicked(); + +private: + + Task task; + std::string source; + + QWidget *centralwidget = nullptr; + QGroupBox* taskBox = nullptr; + QVBoxLayout* taskLayout = nullptr; + QVBoxLayout* verticalLayout = nullptr; + QLabel* taskDescription = nullptr; + QPushButton* chooseFileButton = nullptr; + QLabel* filename = nullptr; + QPushButton* sendButton = nullptr; + QLabel* result = nullptr; + QPushButton* backButton = nullptr; + + void setupUi(QMainWindow *UserWindow); +}; diff --git a/client/internal/gui/include/StatsDialog.h b/client/internal/gui/include/StatsDialog.h deleted file mode 100644 index 8a10038..0000000 --- a/client/internal/gui/include/StatsDialog.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Created by Николай Степанов on 04.05.2023. -// - -#ifndef SOURCEDOUT_STATSDIALOG_H -#define SOURCEDOUT_STATSDIALOG_H - -#include -#include -#include "Metric.h" - -class StatsDialog : public QDialog { - Q_OBJECT - -public: - explicit StatsDialog(QWidget *parent = nullptr) {}; - ~StatsDialog() override {}; - -private: - QTableView* tableView = nullptr; - QTableWidget* tableWidget = nullptr; - QVector metrics; -}; - -#endif //SOURCEDOUT_STATSDIALOG_H diff --git a/client/internal/gui/include/TasksWindow.h b/client/internal/gui/include/TasksWindow.h new file mode 100644 index 0000000..c8f96bd --- /dev/null +++ b/client/internal/gui/include/TasksWindow.h @@ -0,0 +1,45 @@ +#ifndef USERWINDOW_H +#define USERWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Task.h" + +class TasksWindow : public QMainWindow { +Q_OBJECT + +public: + explicit TasksWindow(QWidget *parent = nullptr); + +public slots: + void on_backButton_clicked(); + void on_goToTaskButton_clicked(); + void indexChanged(); + +private: + + QWidget *centralwidget = nullptr; + QVBoxLayout* verticalLayout = nullptr; + QGroupBox *taskChooseGroupBox = nullptr; + QVBoxLayout* taskVerticalLayout = nullptr; + QLabel* label = nullptr; + QComboBox* tasks = nullptr; + QLabel* taskDescription = nullptr; + QPushButton* goToTaskButton = nullptr; + QPushButton* backButton = nullptr; + QWidget* buttonsWidget = nullptr; + QHBoxLayout* buttonsLayout = nullptr; + + std::vector tasks_vector; + + void setupUi(QMainWindow *UserWindow); +}; + +#endif // USERWINDOW_H diff --git a/client/internal/gui/include/UIManager.h b/client/internal/gui/include/UIManager.h index 3d030f2..bc6e071 100644 --- a/client/internal/gui/include/UIManager.h +++ b/client/internal/gui/include/UIManager.h @@ -1,21 +1,22 @@ #ifndef INCLUDE_UIMANAGER_H_ #define INCLUDE_UIMANAGER_H_ +#include #include "EntryWindow.h" -#include "UserWindow.h" +#include "TasksWindow.h" -class UIManager { +class UIManager : public QWidget { +Q_OBJECT public: - UIManager(); - - ~UIManager() = default; + UIManager(QWidget *parent = nullptr); +public slots: void showEntryWindow(); - void showUserWindow(); + void showTasksWindow(); private: - EntryWindow entryWindow; - UserWindow userWindow; + EntryWindow* entryWindow = nullptr; + TasksWindow* userWindow = nullptr; }; #endif // INCLUDE_UIMANAGER_H_ diff --git a/client/internal/gui/include/UserWindow.h b/client/internal/gui/include/UserWindow.h deleted file mode 100644 index 859d69e..0000000 --- a/client/internal/gui/include/UserWindow.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef USERWINDOW_H -#define USERWINDOW_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "StatsDialog.h" - -class UserWindow : public QMainWindow { -Q_OBJECT - -public: - explicit UserWindow(QWidget *parent = nullptr); - ~UserWindow() override = default; - -signals: - void logout(); - -private slots: - void onBackButtonClicked(); - void onListElementClicked(); - void onSendButtonClicked(); - -private: - - QTabWidget* tabs = nullptr; - StatsDialog* statsDialog = nullptr; - QPushButton *backButton = nullptr; - QPushButton *sendButton = nullptr; - QComboBox* comboBox = nullptr; - QVBoxLayout* verticalLayout = nullptr; - QLabel* label = nullptr; - QLabel* description = nullptr; - QFileDialog* fileDialog = nullptr; - QStringList* list = nullptr; - - QWidget *centralwidget = nullptr; -}; - -#endif // USERWINDOW_H diff --git a/client/internal/gui/main.cpp b/client/internal/gui/main.cpp new file mode 100644 index 0000000..b348568 --- /dev/null +++ b/client/internal/gui/main.cpp @@ -0,0 +1,13 @@ +#include "EntryWindow.h" +#include "TasksWindow.h" + +#include + +#include "UIManager.h" + +int main(int argc, char *argv[]) { + QApplication a(argc, argv); + UIManager uiManager; + uiManager.showEntryWindow(); + return a.exec(); +} diff --git a/client/internal/gui/src/AuthDialog.cpp b/client/internal/gui/src/AuthDialog.cpp index 0e57d4d..5227149 100644 --- a/client/internal/gui/src/AuthDialog.cpp +++ b/client/internal/gui/src/AuthDialog.cpp @@ -1,15 +1,86 @@ #include "AuthDialog.h" +#include +#include + AuthDialog::AuthDialog(QWidget *parent) : QDialog(parent) { setupUi(this); } -AuthDialog::~AuthDialog() {} +void AuthDialog::setupUi(QDialog *AuthDialog) { + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(AuthDialog->sizePolicy().hasHeightForWidth()); + AuthDialog->setSizePolicy(sizePolicy); + + verticalLayout = new QVBoxLayout(AuthDialog); + + fields = new QWidget(AuthDialog); + fields->setEnabled(true); + + fieldsLayout = new QFormLayout(fields); + + loginLabel = new QLabel(this); + login = new QLineEdit(this); + + fieldsLayout->addRow(loginLabel, login); + + passwordLabel = new QLabel(this); + password = new QLineEdit(this); + password->setEchoMode(QLineEdit::Password); + + fieldsLayout->addRow(passwordLabel, password); + + verticalLayout->addWidget(fields); -void AuthDialog::on_loginButton_clicked() {} + loginButton = new QPushButton(AuthDialog); + loginButton->setDefault(true); -void AuthDialog::setupUi(QDialog *AuthDialog) {} + verticalLayout->addWidget(loginButton); -void AuthDialog::setTexts(QDialog *AuthDialog) {} + backButton = new QPushButton(AuthDialog); -void AuthDialog::on_backButton_clicked() {} + verticalLayout->addWidget(backButton); + + retranslateUi(AuthDialog); + + connect(loginButton, &QPushButton::clicked, this, &AuthDialog::on_loginButton_clicked); + connect(backButton, &QPushButton::clicked, this, &AuthDialog::on_backButton_clicked); +} + +void AuthDialog::retranslateUi(QDialog *AuthDialog) { + AuthDialog->setWindowTitle("Вход"); + loginLabel->setText("Логин"); + passwordLabel->setText("Пароль"); + loginButton->setText("Войти"); + backButton->setText("Назад"); +} + +void AuthDialog::on_loginButton_clicked() { + std::string log = login->text().toUtf8().constData(); + std::string pass = password->text().toUtf8().constData(); + if (log.empty() || pass.empty()) { + QMessageBox::warning(this, "Ошибка авторизации", "Логин и пароль не могут быть пустыми"); + return; + } +// unsigned result = Core::login(log, pass); + unsigned result = 200; + switch (result) { + case 200: + QMessageBox::warning(this, "Успешная авторизации", "Работает"); + accept(); + close(); + break; + case 403: + QMessageBox::warning(this, "Ошибка авторизации","Неправильный логин или пароль"); + break; + default: + QMessageBox::critical(this, "Авторизация невозможна", "Нет соединения с сервером"); + } +} + +void AuthDialog::on_backButton_clicked() { + reject(); + close(); +} diff --git a/client/internal/gui/src/EntryWindow.cpp b/client/internal/gui/src/EntryWindow.cpp index 8bf9bc3..1c5d246 100644 --- a/client/internal/gui/src/EntryWindow.cpp +++ b/client/internal/gui/src/EntryWindow.cpp @@ -6,22 +6,90 @@ #include #include "AuthDialog.h" #include "SignUpDialog.h" +#include "UIManager.h" -EntryWindow::EntryWindow(QWidget *parent) : QMainWindow(parent) {} +EntryWindow::EntryWindow(QWidget *parent) : QMainWindow(parent) { + setupUi(this); +} -EntryWindow::~EntryWindow() {} +void EntryWindow::setupUi(QMainWindow *EntryWindow) { + EntryWindow->resize(600, 600); + QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(EntryWindow->sizePolicy().hasHeightForWidth()); + EntryWindow->setSizePolicy(sizePolicy); -void EntryWindow::setupUi(QMainWindow *MainWindow) {} -void EntryWindow::retranslateUi(QMainWindow *MainWindow) {} + centralwidget = new QWidget(EntryWindow); + verticalLayout = new QVBoxLayout(centralwidget); -void EntryWindow::onExitButtonClicked() {} + introLabel = new QLabel(centralwidget); + introLabel->setText("Добро пожаловать в Noiseground!"); + introLabel->setGeometry(QRect(140, 200, 331, 31)); -void EntryWindow::onLoginButtonClicked() {} + verticalLayout->addWidget(introLabel, 0, Qt::AlignHCenter); + loginButton = new QPushButton(centralwidget); + QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Preferred); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(loginButton->sizePolicy().hasHeightForWidth()); + loginButton->setSizePolicy(sizePolicy1); + verticalLayout->addWidget(loginButton); -void EntryWindow::onSignUpButtonClicked() {} + horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); -std::shared_ptr EntryWindow::getSignUpDialog() {} + verticalLayout->addItem(horizontalSpacer); -std::shared_ptr EntryWindow::getAuthDialog() {} + signUpButton = new QPushButton(centralwidget); + sizePolicy1.setHeightForWidth(signUpButton->sizePolicy().hasHeightForWidth()); + signUpButton->setSizePolicy(sizePolicy1); + + verticalLayout->addWidget(signUpButton); + + horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + + verticalLayout->addItem(horizontalSpacer_2); + + exitButton = new QPushButton(centralwidget); + sizePolicy1.setHeightForWidth(exitButton->sizePolicy().hasHeightForWidth()); + exitButton->setSizePolicy(sizePolicy1); + + verticalLayout->addWidget(exitButton); + + EntryWindow->setCentralWidget(centralwidget); + + connect(signUpButton, &QPushButton::clicked, this, &EntryWindow::on_signUpButton_clicked); + connect(loginButton, &QPushButton::clicked, this, &EntryWindow::on_loginButton_clicked); + connect(exitButton, &QPushButton::clicked, this, &EntryWindow::on_exitButton_clicked); + + retranslateUi(EntryWindow); +} + +void EntryWindow::retranslateUi(QMainWindow *EntryWindow) { + EntryWindow->setWindowTitle(QCoreApplication::translate("EntryWindow", "Главное окно", nullptr)); + loginButton->setText(QCoreApplication::translate("EntryWindow", "Войти", nullptr)); + signUpButton->setText(QCoreApplication::translate("EntryWindow", "Зарегистрироваться", nullptr)); + exitButton->setText(QCoreApplication::translate("EntryWindow", "Выйти", nullptr)); +} + +void EntryWindow::on_exitButton_clicked() { + QApplication::quit(); +} + +void EntryWindow::on_loginButton_clicked() { + AuthDialog authDialog(this); + if (authDialog.exec() == QDialog::Accepted) { + hide(); + qobject_cast(parent())->showTasksWindow(); + } +} + +void EntryWindow::on_signUpButton_clicked() { + SignUpDialog signupDialog( this ); + if (signupDialog.exec() == QDialog::Accepted) { + hide(); + qobject_cast(parent())->showTasksWindow(); + } +} diff --git a/client/internal/gui/src/SignUpDialog.cpp b/client/internal/gui/src/SignUpDialog.cpp index 8750c80..015f65f 100644 --- a/client/internal/gui/src/SignUpDialog.cpp +++ b/client/internal/gui/src/SignUpDialog.cpp @@ -6,12 +6,106 @@ //#include "Core.h" -SignUpDialog::SignUpDialog(QWidget *parent) : QDialog(parent) {} +SignUpDialog::SignUpDialog(QWidget *parent) : QDialog(parent) { + setupUi(this); +} -SignUpDialog::~SignUpDialog() {} +void SignUpDialog::setupUi(QDialog *SignUpDialog) { + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(SignUpDialog->sizePolicy().hasHeightForWidth()); + SignUpDialog->setSizePolicy(sizePolicy); -void SignUpDialog::retranslateUi(QDialog *SignUpDialog) {} + verticalLayout = new QVBoxLayout(SignUpDialog); -void SignUpDialog::setupUi(QDialog *SignUpDialog) {} + fields = new QWidget(SignUpDialog); + fields->setEnabled(true); + + fieldsLayout = new QFormLayout(fields); + + loginLabel = new QLabel(this); + login = new QLineEdit(this); + + fieldsLayout->addRow(loginLabel, login); + + usernameLabel = new QLabel(this); + username = new QLineEdit(this); + + fieldsLayout->addRow(usernameLabel, username); + + passwordLabel = new QLabel(this); + password = new QLineEdit(this); + password->setEchoMode(QLineEdit::Password); + + fieldsLayout->addRow(passwordLabel, password); + + passwordRepeatLabel = new QLabel(this); + passwordRepeat = new QLineEdit(this); + passwordRepeat->setEchoMode(QLineEdit::Password); + + fieldsLayout->addRow(passwordRepeatLabel, passwordRepeat); + + verticalLayout->addWidget(fields); + + signUpButton = new QPushButton(SignUpDialog); + signUpButton->setDefault(true); + + verticalLayout->addWidget(signUpButton); + + backButton = new QPushButton(SignUpDialog); + + verticalLayout->addWidget(backButton); + + retranslateUi(SignUpDialog); + + connect(signUpButton, &QPushButton::clicked, this, &SignUpDialog::on_signUpButton_clicked); + connect(backButton, &QPushButton::clicked, this, &SignUpDialog::on_backButton_clicked); +} + +void SignUpDialog::retranslateUi(QDialog *SignUpDialog) { + SignUpDialog->setWindowTitle("Регистрация"); + loginLabel->setText("Введите логин"); + usernameLabel->setText("Введите имя"); + passwordLabel->setText("Введите пароль"); + passwordRepeatLabel->setText("Повторите пароль"); + signUpButton->setText("Зарегистрироваться"); + backButton->setText("Назад"); +} + +void SignUpDialog::on_signUpButton_clicked() { + std::string login = this->login->text().toUtf8().constData(); + std::string username = this->username->text().toUtf8().constData(); + std::string password = this->password->text().toUtf8().constData(); + std::string passwordRepeat = this->passwordRepeat->text().toUtf8().constData(); + if (password == passwordRepeat && !login.empty() && !username.empty()) { +// unsigned response = Core::signUp(log.toStdString(), pass.toStdString()); + unsigned response = 200; + switch (response) { + case 200: + QMessageBox::information(this, "Успех!", "Вы успешно зарегистрированы!"); + accept(); + close(); + break; + case 403: + QMessageBox::warning(this, "Регистрация невозможна", "Логин уже занят!"); + break; + default: + QMessageBox::critical(this, "Регистрация невозможна!", "Нет соединения с сервером!"); + } + + } else if (login.empty()) { + QMessageBox::warning(this, "Ошибка!", "Логин не может быть пустым!"); + } else if (username.empty()) { + QMessageBox::warning(this, "Ошибка!", "Имя не может быть пустым!"); + } else { + QMessageBox::warning(this, "Ошибка!", "Пароли не совпадают!"); + } +} + +void SignUpDialog::on_backButton_clicked() { + reject(); + close(); +} // setupUi diff --git a/client/internal/gui/src/SolutionsWindow.cpp b/client/internal/gui/src/SolutionsWindow.cpp new file mode 100644 index 0000000..33743ee --- /dev/null +++ b/client/internal/gui/src/SolutionsWindow.cpp @@ -0,0 +1,80 @@ +#include "SolutionsWindow.h" + +#include +#include +#include +#include + +SolutionsWindow::SolutionsWindow(Task task, QWidget *parent) : QMainWindow(parent), task(std::move(task)) { + setupUi(this); + connect(backButton, &QPushButton::clicked, this, &SolutionsWindow::on_backButton_clicked); + connect(chooseFileButton, &QPushButton::clicked, this, &SolutionsWindow::on_chooseFileButton_clicked); + connect(sendButton, &QPushButton::clicked, this, &SolutionsWindow::on_sendButton_clicked); +} + +void SolutionsWindow::setupUi(QMainWindow *SolutionsWindow) { + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(SolutionsWindow->sizePolicy().hasHeightForWidth()); + SolutionsWindow->setSizePolicy(sizePolicy); + + centralwidget = new QWidget(SolutionsWindow); + verticalLayout = new QVBoxLayout(centralwidget); + + taskBox = new QGroupBox(centralwidget); + taskLayout = new QVBoxLayout(taskBox); + + taskDescription = new QLabel(taskBox); + std::string description = task.description; + taskDescription->setText(QString(description.c_str())); + + taskLayout->addWidget(taskDescription); + + filename = new QLabel(this); + + chooseFileButton = new QPushButton(this); + chooseFileButton->setText(QString::fromUtf8("Выбирите файл")); + + sendButton = new QPushButton(this); + sendButton->setText(QString::fromUtf8("Отправить")); + + result = new QLabel(this); + result->setText(QString::fromUtf8("Отправьте для принятия решения")); + + backButton = new QPushButton(this); + backButton->setText(QString::fromUtf8("Назад")); + + verticalLayout->addWidget(taskBox); + verticalLayout->addWidget(filename); + verticalLayout->addWidget(chooseFileButton); + verticalLayout->addWidget(sendButton); + verticalLayout->addWidget(result); + verticalLayout->addWidget(backButton); + + SolutionsWindow->setCentralWidget(centralwidget); +} + +void SolutionsWindow::on_backButton_clicked() { + close(); + qobject_cast(parent())->show(); +} + +void SolutionsWindow::on_chooseFileButton_clicked() { + QString fileName = QFileDialog::getOpenFileName(this, tr("Choose a file to send"), QDir::homePath()); + filename->setText(QFileInfo(fileName).fileName()); + std::ifstream file(fileName.toUtf8().constData()); + std::ostringstream sstr; + sstr << file.rdbuf(); + source = sstr.str(); +} + +void SolutionsWindow::on_sendButton_clicked() { + if (source.empty()) { + QMessageBox::warning(this, "Ошибка отправки", "Нельзя отправить пустое решение"); + return; + } + std::cout << source; +} + + diff --git a/client/internal/gui/src/TasksWindow.cpp b/client/internal/gui/src/TasksWindow.cpp new file mode 100644 index 0000000..f5c4884 --- /dev/null +++ b/client/internal/gui/src/TasksWindow.cpp @@ -0,0 +1,107 @@ +#include "TasksWindow.h" + +#include +#include +#include + +#include "SolutionsWindow.h" +#include "UIManager.h" + +TasksWindow::TasksWindow(QWidget *parent) : QMainWindow(parent) { + tasks_vector.push_back({1, "1 description 1\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "8\n" + "9\n" + "10\n" + "11\n" + "12\n" + "13\n" + "14\n"}); + tasks_vector.push_back({2, "2 description"}); + tasks_vector.push_back({3, "3 description"}); + + setupUi(this); + connect(tasks, &QComboBox::currentIndexChanged, this, &TasksWindow::indexChanged); + connect(goToTaskButton, &QPushButton::clicked, this, &TasksWindow::on_goToTaskButton_clicked); + connect(backButton, &QPushButton::clicked, this, &TasksWindow::on_backButton_clicked); +} + + + +void TasksWindow::setupUi(QMainWindow *UserWindow) { + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(UserWindow->sizePolicy().hasHeightForWidth()); + UserWindow->setSizePolicy(sizePolicy); + + centralwidget = new QWidget(UserWindow); + verticalLayout = new QVBoxLayout(centralwidget); + + taskChooseGroupBox = new QGroupBox(centralwidget); + sizePolicy.setHeightForWidth(taskChooseGroupBox->sizePolicy().hasHeightForWidth()); + taskChooseGroupBox->setFixedHeight(85); + taskChooseGroupBox->setSizePolicy(sizePolicy); + + taskVerticalLayout = new QVBoxLayout(taskChooseGroupBox); + + label = new QLabel(this); + label->setText(QString::fromUtf8("Выберите номер задания:")); + + tasks = new QComboBox(this); + for (int i = 0; i < tasks_vector.size(); i++) { + tasks->insertItem(i, QString::number(tasks_vector[i].id)); + } + tasks->setCurrentIndex(0); + + taskVerticalLayout->addWidget(label); + taskVerticalLayout->addWidget(tasks); + + taskDescription = new QLabel(this); + std::string description = tasks_vector[0].description; + taskDescription->setText(QString(description.c_str())); + + buttonsWidget = new QWidget(centralwidget); + sizePolicy.setHeightForWidth(buttonsWidget->sizePolicy().hasHeightForWidth()); + buttonsWidget->setFixedHeight(45); + + buttonsLayout = new QHBoxLayout(buttonsWidget); + + goToTaskButton = new QPushButton(this); + goToTaskButton->setText(QString::fromUtf8("Перейти к сдаче")); + + backButton = new QPushButton(this); + backButton->setText(QString::fromUtf8("Выйти")); + + buttonsLayout->addWidget(goToTaskButton); + buttonsLayout->addWidget(backButton); + + verticalLayout->addWidget(taskChooseGroupBox); + verticalLayout->addWidget(taskDescription); + verticalLayout->addWidget(buttonsWidget); + + UserWindow->setCentralWidget(centralwidget); +} + +void TasksWindow::indexChanged() { + std::string description = tasks_vector[tasks->currentIndex()].description; + taskDescription->setText(QString(description.c_str())); +} + +void TasksWindow::on_backButton_clicked() { + // Core::logout(); + close(); + qobject_cast(parent())->showEntryWindow(); +} + +void TasksWindow::on_goToTaskButton_clicked() { + hide(); + auto* solutionsWindow = new SolutionsWindow(tasks_vector[tasks->currentIndex()], this); + solutionsWindow->show(); +} diff --git a/client/internal/gui/src/UIManager.cpp b/client/internal/gui/src/UIManager.cpp index fc23301..101e034 100644 --- a/client/internal/gui/src/UIManager.cpp +++ b/client/internal/gui/src/UIManager.cpp @@ -1,11 +1,19 @@ #include "UIManager.h" #include "EntryWindow.h" -#include "UserWindow.h" +#include "TasksWindow.h" #include "SignUpDialog.h" +#include "AuthDialog.h" -void UIManager::showEntryWindow() {} +void UIManager::showEntryWindow() { + entryWindow->show(); +} -void UIManager::showUserWindow() {} +void UIManager::showTasksWindow() { + userWindow->show(); +} -UIManager::UIManager() = default; +UIManager::UIManager(QWidget *parent) : QWidget(parent) { + userWindow = new TasksWindow(this); + entryWindow = new EntryWindow(this); +} diff --git a/client/internal/gui/src/UserWindow.cpp b/client/internal/gui/src/UserWindow.cpp deleted file mode 100644 index 8e6169b..0000000 --- a/client/internal/gui/src/UserWindow.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "UserWindow.h" - -#include -#include -#include - -UserWindow::UserWindow(QWidget *parent) : QMainWindow(parent) {} - -void UserWindow::onBackButtonClicked() {} diff --git a/client/internal/gui/tests/main.cpp b/client/internal/gui/tests/main.cpp index d9f4b73..2348fac 100644 --- a/client/internal/gui/tests/main.cpp +++ b/client/internal/gui/tests/main.cpp @@ -3,7 +3,7 @@ #include "UIManager.h" #include "EntryWindow.h" -#include "UserWindow.h" +#include "TasksWindow.h" #include @@ -18,7 +18,7 @@ TEST(ConstructorTest, EntryWindow) { TEST(ConstructorTest, UserWindow) { int fake = 0; QApplication a(fake, nullptr); - UserWindow uw; + TasksWindow uw; EXPECT_NO_FATAL_FAILURE(uw.show()); a.exec(); } @@ -35,7 +35,7 @@ TEST(ConstructorTest, UIManagerUW) { int fake_argc = 0; QApplication a(fake_argc, nullptr); UIManager um; - EXPECT_NO_FATAL_FAILURE(um.showUserWindow()); + EXPECT_NO_FATAL_FAILURE(um.showTasksWindow()); a.exec(); } -- GitLab From 22700025bb6d7dd8fd8cd97687753cdb3b70e5d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9=20=D0=A1=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Thu, 11 May 2023 19:41:13 +0300 Subject: [PATCH 6/8] add core and login/register requests on client --- client/internal/CMakeLists.txt | 6 +- client/internal/core/CMakeLists.txt | 18 +++++ client/internal/core/include/Core.h | 20 +++++ client/internal/core/src/Core.cpp | 26 +++++++ client/internal/entities/include/Metric.h | 5 +- client/internal/entities/include/Solution.h | 54 +------------- client/internal/entities/include/Task.h | 7 +- client/internal/entities/include/User.h | 33 +-------- client/internal/entities/src/Solution.cpp | 73 ------------------- client/internal/entities/src/Task.cpp | 3 + client/internal/entities/src/User.cpp | 43 ----------- .../httpClient/include/HttpClientManager.h | 8 +- .../internal/httpClient/include/Serializer.h | 14 ++-- .../httpClient/src/HttpClientManager.cpp | 30 ++++++-- client/internal/httpClient/src/Serializer.cpp | 39 ++++++++++ 15 files changed, 157 insertions(+), 222 deletions(-) create mode 100644 client/internal/core/CMakeLists.txt create mode 100644 client/internal/core/include/Core.h create mode 100644 client/internal/core/src/Core.cpp delete mode 100644 client/internal/entities/src/Solution.cpp create mode 100644 client/internal/entities/src/Task.cpp delete mode 100644 client/internal/entities/src/User.cpp create mode 100644 client/internal/httpClient/src/Serializer.cpp diff --git a/client/internal/CMakeLists.txt b/client/internal/CMakeLists.txt index f76cc95..790ec14 100644 --- a/client/internal/CMakeLists.txt +++ b/client/internal/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(entities) add_subdirectory(httpClient) add_subdirectory(gui) +add_subdirectory(core) set(libClientEntities_LIB ${libClientEntities_LIB} PARENT_SCOPE) set(libClientEntities_INCLUDE_DIRS ${libClientEntities_INCLUDE_DIRS} PARENT_SCOPE) @@ -9,4 +10,7 @@ set(HTTPCLIENT_lib_LIB ${HTTPCLIENT_lib_LIB} PARENT_SCOPE) set(HTTPCLIENT_lib_INCLUDE_DIRS ${HTTPCLIENT_lib_INCLUDE_DIRS} PARENT_SCOPE) set(GUI_lib_LIB ${GUI_lib_LIB} PARENT_SCOPE) -set(GUI_lib_INCLUDE_DIRS ${GUI_lib_INCLUDE_DIRS} PARENT_SCOPE) \ No newline at end of file +set(GUI_lib_INCLUDE_DIRS ${GUI_lib_INCLUDE_DIRS} PARENT_SCOPE) + +set(CORE_lib_LIB ${CORE_lib_LIB} PARENT_SCOPE) +set(CORE_lib_INCLUDE_DIRS ${CORE_lib_INCLUDE_DIRS} PARENT_SCOPE) \ No newline at end of file diff --git a/client/internal/core/CMakeLists.txt b/client/internal/core/CMakeLists.txt new file mode 100644 index 0000000..8a2af66 --- /dev/null +++ b/client/internal/core/CMakeLists.txt @@ -0,0 +1,18 @@ +project("CoreLib") + +set(CMAKE_CXX_STANDARD 20) + +file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include) +file(GLOB INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) + +include_directories(${INCLUDE_DIRS} ${libClientEntities_INCLUDE_DIRS} ${HTTPCLIENT_lib_INCLUDE_DIRS}) + +add_library(${PROJECT_NAME} ${SOURCES} ${INCLUDES}) +target_link_libraries(${PROJECT_NAME} ${libClientEntities_LIB} ${HTTPCLIENT_lib_LIB}) + +set(CORE_lib_LIB ${PROJECT_NAME}) +set(CORE_lib_LIB ${CORE_lib_LIB} PARENT_SCOPE) + +set(CORE_lib_INCLUDE_DIRS ${INCLUDE_DIRS}) +set(CORE_lib_INCLUDE_DIRS ${CORE_lib_INCLUDE_DIRS} PARENT_SCOPE) \ No newline at end of file diff --git a/client/internal/core/include/Core.h b/client/internal/core/include/Core.h new file mode 100644 index 0000000..d88af4d --- /dev/null +++ b/client/internal/core/include/Core.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +#include "Task.h" + +class Core { +public: + Core() { user_id = -1; }; + + static unsigned signUp(const std::string &login, const std::string &username, const std::string &pass); + + static unsigned login(const std::string &login, const std::string &pass); + + static void logout(); + +private: + static std::size_t user_id; +}; diff --git a/client/internal/core/src/Core.cpp b/client/internal/core/src/Core.cpp new file mode 100644 index 0000000..bf3d43d --- /dev/null +++ b/client/internal/core/src/Core.cpp @@ -0,0 +1,26 @@ +// +// Created by Николай Степанов on 11.05.2023. +// +#include "Core.h" +#include "HttpClientManager.h" + +const std::string CLIENT_IP = "0.0.0.0"; +const std::string CLIENT_PORT = "80"; +HttpClientManager client(CLIENT_IP, CLIENT_PORT); + +unsigned Core::signUp(const std::string &login, const std::string &username, const std::string &pass) { + auto res = client.registerUser(login, username, pass); + user_id = res.second.id; + return res.first; +} + +unsigned Core::login(const std::string &login, const std::string &pass) { + auto res = client.loginUser(login, pass); + user_id = res.second.id; + return res.first; +} + +void Core::logout() { + user_id = -1; +} + diff --git a/client/internal/entities/include/Metric.h b/client/internal/entities/include/Metric.h index 3ab8ea7..db320cf 100644 --- a/client/internal/entities/include/Metric.h +++ b/client/internal/entities/include/Metric.h @@ -1,5 +1,4 @@ -#ifndef SOURCEDOUT_METRIC_H -#define SOURCEDOUT_METRIC_H +#pragma once #include @@ -7,5 +6,3 @@ struct Metric { std::string name; unsigned int value; }; - -#endif //SOURCEDOUT_METRIC_H diff --git a/client/internal/entities/include/Solution.h b/client/internal/entities/include/Solution.h index 6282f47..384e648 100644 --- a/client/internal/entities/include/Solution.h +++ b/client/internal/entities/include/Solution.h @@ -1,58 +1,10 @@ -#ifndef SOURCEDOUT_SOLUTION_HPP -#define SOURCEDOUT_SOLUTION_HPP +#pragma once #include #include #include -class Solution { -public: - Solution() =default; - Solution(size_t id, std::string sendDate, size_t senderId, std::string source, - std::string tokens, std::string astTree, size_t taskId, std::string result); - - [[nodiscard]] size_t getId() const; - - - [[nodiscard]] const std::string &getSendDate() const; - - void setSendDate(const std::string &sendDate); - - [[nodiscard]] size_t getSenderId() const; - - void setSenderId(size_t senderId); - - [[nodiscard]] const std::string &getSource() const; - - void setSource(const std::string &source); - - [[nodiscard]] const std::string &getTokens() const; - - void setTokens(const std::string &tokens); - - [[nodiscard]] const std::string &getAstTree() const; - - void setAstTree(const std::string &astTree); - - [[nodiscard]] size_t getTaskId() const; - - void setTaskId(size_t taskId); - - [[nodiscard]] const std::string &getResult() const; - - void setResult(const std::string &result); - -private: +struct Solution { size_t id; - std::string send_date; - size_t sender_id; std::string source; - std::string tokens; - std::string astTree; - size_t task_id; - std::string result; -public: - -}; - -#endif //SOURCEDOUT_SOLUTION_HPP \ No newline at end of file +}; \ No newline at end of file diff --git a/client/internal/entities/include/Task.h b/client/internal/entities/include/Task.h index 9d87ca6..de9c488 100644 --- a/client/internal/entities/include/Task.h +++ b/client/internal/entities/include/Task.h @@ -1,11 +1,10 @@ -#ifndef SOURCEDOUT_TASK_HPP -#define SOURCEDOUT_TASK_HPP +#pragma once #include struct Task{ std::size_t id; std::string description; -}; -#endif //SOURCEDOUT_TASK_HPP \ No newline at end of file + Task(std::size_t id, std::string_view desc); +}; diff --git a/client/internal/entities/include/User.h b/client/internal/entities/include/User.h index 5802df2..9482540 100644 --- a/client/internal/entities/include/User.h +++ b/client/internal/entities/include/User.h @@ -1,38 +1,11 @@ -#ifndef SOURCEDOUT_USER_HPP +#pragma once #include #include -#define SOURCEDOUT_USER_HPP - -class User { -private: +struct User { size_t id; std::string login; std::string password; std::string username; - -public: - User()=default; - User(size_t id_, std::string login_, std::string password_, std::string username_); - - User(std::string login_, std::string password_, std::string username_); - - [[nodiscard]] const std::string &getLogin() const; - - void setLogin(const std::string &login); - - [[nodiscard]] const std::string &getPassword() const; - - void setPassword(const std::string &password); - - [[nodiscard]] const std::string &getUsername() const; - - void setUsername(const std::string &username); - - [[nodiscard]] size_t getId() const; - - friend std::ostream &operator<<(std::ostream &os, const User &user); -}; - -#endif //SOURCEDOUT_USER_HPP \ No newline at end of file +}; \ No newline at end of file diff --git a/client/internal/entities/src/Solution.cpp b/client/internal/entities/src/Solution.cpp deleted file mode 100644 index 2e9b1e8..0000000 --- a/client/internal/entities/src/Solution.cpp +++ /dev/null @@ -1,73 +0,0 @@ - -#include -#include -#include "Solution.h" - -Solution::Solution(unsigned long id, std::string sendDate, unsigned long senderId, - std::string source, std::string tokens, - std::string astTree, unsigned long taskId, - std::string result) : id(id), send_date(std::move(sendDate)), sender_id(senderId), - source(std::move(source)), tokens(std::move(tokens)), - astTree(std::move(astTree)), - task_id(taskId), result(std::move(result)) {} - -size_t Solution::getId() const { - return id; -} - - -const std::string &Solution::getSendDate() const { - return send_date; -} - -void Solution::setSendDate(const std::string &sendDate) { - send_date = sendDate; -} - -size_t Solution::getSenderId() const { - return sender_id; -} - -void Solution::setSenderId(size_t senderId) { - sender_id = senderId; -} - -const std::string &Solution::getSource() const { - return source; -} - -void Solution::setSource(const std::string &source_) { - Solution::source = source_; -} - -const std::string &Solution::getTokens() const { - return tokens; -} - -void Solution::setTokens(const std::string &tokens_) { - Solution::tokens = tokens_; -} - -const std::string &Solution::getAstTree() const { - return astTree; -} - -void Solution::setAstTree(const std::string &astTree_) { - Solution::astTree = astTree_; -} - -size_t Solution::getTaskId() const { - return task_id; -} - -void Solution::setTaskId(size_t taskId) { - task_id = taskId; -} - -const std::string &Solution::getResult() const { - return result; -} - -void Solution::setResult(const std::string &result_) { - Solution::result = result_; -} \ No newline at end of file diff --git a/client/internal/entities/src/Task.cpp b/client/internal/entities/src/Task.cpp new file mode 100644 index 0000000..496fddc --- /dev/null +++ b/client/internal/entities/src/Task.cpp @@ -0,0 +1,3 @@ +#include "Task.h" + +Task::Task(std::size_t id, std::string_view desc) : id(id), description(desc); \ No newline at end of file diff --git a/client/internal/entities/src/User.cpp b/client/internal/entities/src/User.cpp deleted file mode 100644 index 53706e2..0000000 --- a/client/internal/entities/src/User.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include "User.h" - -User::User(size_t id_, std::string login_, std::string password_, std::string username_) : - id(id_), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { -} -User::User(std::string login_, std::string password_, std::string username_) : - id(0), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { -} - -const std::string &User::getLogin() const { - return login; -} - -void User::setLogin(const std::string &login_) { - User::login = login_; -} - -const std::string &User::getPassword() const { - return password; -} - -void User::setPassword(const std::string &password_) { - User::password = password_; -} - -const std::string &User::getUsername() const { - return username; -} - -void User::setUsername(const std::string &username_) { - User::username = username_; -} - -size_t User::getId() const { - return id; -} - -std::ostream &operator<<(std::ostream &os, const User &user) { - os << "id: " << user.id << " login: " << user.login << " password: " << user.password << " username: " - << user.username; - return os; -} \ No newline at end of file diff --git a/client/internal/httpClient/include/HttpClientManager.h b/client/internal/httpClient/include/HttpClientManager.h index 7c3ed33..eb93fcb 100644 --- a/client/internal/httpClient/include/HttpClientManager.h +++ b/client/internal/httpClient/include/HttpClientManager.h @@ -14,17 +14,17 @@ class HttpClientManager { public: - HttpClientManager(std::string_view host_, std::string_view port_, std::string_view saved_path_); + HttpClientManager(std::string_view host_, std::string_view port_); - unsigned int loginUser(const std::string &login, const std::string &password); - unsigned int registerUser(const std::string &login, const std::string &username, const std::string &password); + std::pair loginUser(const std::string &login, const std::string &password); + std::pair registerUser(const std::string &login, const std::string &username, + const std::string &password); unsigned int submitSolution(const int& user_id, const std::string &path_to_solution); unsigned int getAllSolutionsForTask(const int& user_id, const int& task_id); std::vector getAllTasks(); std::vector getMetrics(const int& sol_id); void setHttpClient(std::shared_ptr client_); private: - std::string saved_path; std::string host; std::string port; std::shared_ptr client; diff --git a/client/internal/httpClient/include/Serializer.h b/client/internal/httpClient/include/Serializer.h index 4f4dc32..42be6c8 100644 --- a/client/internal/httpClient/include/Serializer.h +++ b/client/internal/httpClient/include/Serializer.h @@ -1,12 +1,14 @@ -#ifndef APP_HTTPCLIENT_HTTPCLIENT_SERIALIZER_H_ -#define APP_HTTPCLIENT_HTTPCLIENT_SERIALIZER_H_ +#pragma once #include #include #include +#include "User.h" -class Serializer {}; +class Serializer { +public: + std::string serialLoginData(std::string_view login, std::string_view password); + std::string serialRegisterData(std::string_view login, std::string_view username, std::string_view password); + User deserialUserData(std::string_view body); +}; - - -#endif // APP_HTTPCLIENT_HTTPCLIENT_SERIALIZER_H_ diff --git a/client/internal/httpClient/src/HttpClientManager.cpp b/client/internal/httpClient/src/HttpClientManager.cpp index 9d7b1e4..a269f65 100644 --- a/client/internal/httpClient/src/HttpClientManager.cpp +++ b/client/internal/httpClient/src/HttpClientManager.cpp @@ -6,18 +6,36 @@ #include "HttpClient.h" -HttpClientManager::HttpClientManager(std::string_view host_, std::string_view port_, std::string_view saved_path_) : - host(host_), port(port_), saved_path(saved_path_), +HttpClientManager::HttpClientManager(std::string_view host_, std::string_view port_) : + host(host_), port(port_), client(std::make_shared(host_, port_)), serializer(std::make_shared()) {} -unsigned int HttpClientManager::loginUser(const std::string &login, const std::string &password) { - +std::pair HttpClientManager::loginUser(const std::string &login, const std::string &password) { + std::string body = serializer->serialLoginData(login, password); + http::response res = client->makeGetRequest("/user/login", body); + unsigned status = res.result_int(); + std::string res_body; + for (auto seq : res.body().data()) { + auto* cbuf = boost::asio::buffer_cast(seq); + res_body.append(cbuf, boost::asio::buffer_size(seq)); + } + User user = serializer->deserialUserData(res_body); + return {status, user}; } -unsigned int HttpClientManager::registerUser(const std::string &login, const std::string &username, +std::pair HttpClientManager::registerUser(const std::string &login, const std::string &username, const std::string &password) { - return 0; + std::string body = serializer->serialRegisterData(login, username, password); + http::response res = client->makeGetRequest("/user/register", body); + unsigned status = res.result_int(); + std::string res_body; + for (auto seq : res.body().data()) { + auto* cbuf = boost::asio::buffer_cast(seq); + res_body.append(cbuf, boost::asio::buffer_size(seq)); + } + User user = serializer->deserialUserData(res_body); + return {status, user}; } unsigned int HttpClientManager::submitSolution(const int &user_id, const std::string &path_to_sound) { diff --git a/client/internal/httpClient/src/Serializer.cpp b/client/internal/httpClient/src/Serializer.cpp new file mode 100644 index 0000000..c2d5567 --- /dev/null +++ b/client/internal/httpClient/src/Serializer.cpp @@ -0,0 +1,39 @@ +#include "Serializer.h" + +#include +#include +#include + +std::string Serializer::serialLoginData(std::string_view login, std::string_view password) { + boost::property_tree::ptree json; + json.put("login", login); + json.put("password", password); + std::stringstream out; + boost::property_tree::write_json(out, json); + return out.str(); +} + +User Serializer::deserialUserData(std::string_view body) { + std::stringstream ss; + ss << body; + boost::property_tree::ptree json; + boost::property_tree::read_json(ss, json); + User res = { + json.get("user_id"), + json.get("login"), + json.get("password"), + json.get("username") + }; + return res; +} + +std::string +Serializer::serialRegisterData(std::string_view login, std::string_view username, std::string_view password) { + boost::property_tree::ptree json; + json.put("login", login); + json.put("username", username); + json.put("password", password); + std::stringstream out; + boost::property_tree::write_json(out, json); + return out.str(); +} -- GitLab From d7b3cad1f97abaa4fe1f7de0f1ff9c52ae0cf170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9=20=D0=A1=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Thu, 11 May 2023 19:54:36 +0300 Subject: [PATCH 7/8] fix login/register on server --- .../internal/httpServer/include/Serializer.h | 1 + .../internal/httpServer/include/UserManager.h | 4 ++ server/internal/httpServer/src/Serializer.cpp | 11 +++++ .../internal/httpServer/src/UserManager.cpp | 48 ++++++++++++------- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/server/internal/httpServer/include/Serializer.h b/server/internal/httpServer/include/Serializer.h index 34cb67a..9af1b01 100644 --- a/server/internal/httpServer/include/Serializer.h +++ b/server/internal/httpServer/include/Serializer.h @@ -20,6 +20,7 @@ public: std::string serialSolutions(const std::vector& solutions); std::string serialAllTasks(const std::vector& tasks); + std::string serialUserData(const User& user); }; diff --git a/server/internal/httpServer/include/UserManager.h b/server/internal/httpServer/include/UserManager.h index 01a16de..9cf0900 100644 --- a/server/internal/httpServer/include/UserManager.h +++ b/server/internal/httpServer/include/UserManager.h @@ -17,6 +17,10 @@ class UserManager : public IUserManager { private: std::shared_ptr userService; std::shared_ptr serializer; + + // for tests with client + int count = 0; + std::vector users; }; #endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_USERMANAGER_H_ diff --git a/server/internal/httpServer/src/Serializer.cpp b/server/internal/httpServer/src/Serializer.cpp index 8d2569a..108430a 100644 --- a/server/internal/httpServer/src/Serializer.cpp +++ b/server/internal/httpServer/src/Serializer.cpp @@ -101,3 +101,14 @@ std::string Serializer::serialAllTasks(const std::vector &tasks) { boost::property_tree::write_json(out, json); return out.str(); } + +std::string Serializer::serialUserData(const User &user) { + boost::property_tree::ptree json; + json.put("id", user.getId()); + json.put("login", user.getLogin()); + json.put("username", user.getUsername()); + json.put("password", user.getPassword()); + std::stringstream out; + boost::property_tree::write_json(out, json); + return out.str(); +} diff --git a/server/internal/httpServer/src/UserManager.cpp b/server/internal/httpServer/src/UserManager.cpp index 4048afd..335ad4d 100644 --- a/server/internal/httpServer/src/UserManager.cpp +++ b/server/internal/httpServer/src/UserManager.cpp @@ -10,32 +10,46 @@ http::message_generator UserManager::loginUser(http::request std::string login, password; std::tie(login, password) = serializer->deserialUserData(req.body()); - /// TODO - - auto const bad_request = - [&req](beast::string_view why) - { - http::response res{http::status::bad_request, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, "text/html"); - res.keep_alive(req.keep_alive()); - res.body() = std::string(why); - res.prepare_payload(); - return res; - }; - - return bad_request("123"); + bool found = false; + User user; + for (const auto& i : users) { + if (i.getPassword() == password && i.getLogin() == login && !found) { + user = i; + found = true; + } + } + if (found) { + http::response res{http::status::ok, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/plain"); + res.keep_alive(req.keep_alive()); + res.body() = serializer->serialUserData(user); + res.prepare_payload(); + return res; + } else { + http::response res{http::status::not_found, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/plain"); + res.keep_alive(req.keep_alive()); + res.body() = serializer->serialUserData(user); + res.prepare_payload(); + return res; + } } http::message_generator UserManager::registerUser(http::request &&req) { std::string login, password, username; std::tie(login, password, username) = serializer->deserialNewUserData(req.body()); - User user = userService->createUser(login, username, password); +// User user = userService->createUser(login, username, password); + count++; + User user = User(count, login, password, username); + std::cout << user << std::endl; + users.push_back(user); http::response res{http::status::ok, req.version()}; res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, "text/plain"); res.keep_alive(req.keep_alive()); - res.body() = std::to_string(user.getId()); + res.body() = serializer->serialUserData(user); res.prepare_payload(); return res; } -- GitLab From b1ceee88ff01fd20d39533b52d80f8fd29f15c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9=20=D0=A1=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Sun, 14 May 2023 14:15:17 +0300 Subject: [PATCH 8/8] Create mvp for http_server, http_client and gui --- client/internal/CMakeLists.txt | 10 ++-- client/internal/core/CMakeLists.txt | 6 +- client/internal/core/include/Core.h | 9 ++- client/internal/core/src/Core.cpp | 22 +++++-- client/internal/entities/include/Solution.h | 1 + client/internal/entities/src/Task.cpp | 2 +- client/internal/gui/CMakeLists.txt | 4 +- client/internal/gui/include/AddTaskDialog.h | 29 +++++++++ client/internal/gui/include/SolutionsWindow.h | 2 +- client/internal/gui/include/TasksWindow.h | 3 + client/internal/gui/src/AddTaskDialog.cpp | 60 +++++++++++++++++++ client/internal/gui/src/AuthDialog.cpp | 8 +-- client/internal/gui/src/SignUpDialog.cpp | 19 +++--- client/internal/gui/src/SolutionsWindow.cpp | 15 ++--- client/internal/gui/src/TasksWindow.cpp | 48 +++++++++------ .../internal/httpClient/include/HttpClient.h | 3 +- .../httpClient/include/HttpClientManager.h | 5 +- .../internal/httpClient/include/Serializer.h | 7 +++ client/internal/httpClient/src/HttpClient.cpp | 15 +++-- .../httpClient/src/HttpClientManager.cpp | 37 +++++++++--- client/internal/httpClient/src/Serializer.cpp | 49 +++++++++++++++ .../internal/httpServer/include/Serializer.h | 1 + .../httpServer/include/SolutionManager.h | 1 - .../internal/httpServer/include/TaskManager.h | 5 +- .../httpServer/include/TmpSolutionService.h | 25 ++++++++ .../httpServer/include/TmpTaskService.h | 40 +++++++++++++ .../httpServer/include/TmpUserService.h | 34 +++++++++++ server/internal/httpServer/src/Router.cpp | 4 -- server/internal/httpServer/src/Serializer.cpp | 12 +++- .../httpServer/src/SolutionManager.cpp | 25 ++------ .../internal/httpServer/src/TaskManager.cpp | 7 ++- .../internal/httpServer/src/UserManager.cpp | 22 +++---- .../httpServer/virtual/ISolutionManager.h | 1 - 33 files changed, 405 insertions(+), 126 deletions(-) create mode 100644 client/internal/gui/include/AddTaskDialog.h create mode 100644 client/internal/gui/src/AddTaskDialog.cpp create mode 100644 server/internal/httpServer/include/TmpSolutionService.h create mode 100644 server/internal/httpServer/include/TmpTaskService.h create mode 100644 server/internal/httpServer/include/TmpUserService.h diff --git a/client/internal/CMakeLists.txt b/client/internal/CMakeLists.txt index 790ec14..b540366 100644 --- a/client/internal/CMakeLists.txt +++ b/client/internal/CMakeLists.txt @@ -1,7 +1,7 @@ add_subdirectory(entities) add_subdirectory(httpClient) -add_subdirectory(gui) add_subdirectory(core) +add_subdirectory(gui) set(libClientEntities_LIB ${libClientEntities_LIB} PARENT_SCOPE) set(libClientEntities_INCLUDE_DIRS ${libClientEntities_INCLUDE_DIRS} PARENT_SCOPE) @@ -9,8 +9,8 @@ set(libClientEntities_INCLUDE_DIRS ${libClientEntities_INCLUDE_DIRS} PARENT_SCOP set(HTTPCLIENT_lib_LIB ${HTTPCLIENT_lib_LIB} PARENT_SCOPE) set(HTTPCLIENT_lib_INCLUDE_DIRS ${HTTPCLIENT_lib_INCLUDE_DIRS} PARENT_SCOPE) -set(GUI_lib_LIB ${GUI_lib_LIB} PARENT_SCOPE) -set(GUI_lib_INCLUDE_DIRS ${GUI_lib_INCLUDE_DIRS} PARENT_SCOPE) - set(CORE_lib_LIB ${CORE_lib_LIB} PARENT_SCOPE) -set(CORE_lib_INCLUDE_DIRS ${CORE_lib_INCLUDE_DIRS} PARENT_SCOPE) \ No newline at end of file +set(CORE_lib_INCLUDE_DIRS ${CORE_lib_INCLUDE_DIRS} PARENT_SCOPE) + +set(GUI_lib_LIB ${GUI_lib_LIB} PARENT_SCOPE) +set(GUI_lib_INCLUDE_DIRS ${GUI_lib_INCLUDE_DIRS} PARENT_SCOPE) \ No newline at end of file diff --git a/client/internal/core/CMakeLists.txt b/client/internal/core/CMakeLists.txt index 8a2af66..a493beb 100644 --- a/client/internal/core/CMakeLists.txt +++ b/client/internal/core/CMakeLists.txt @@ -6,13 +6,13 @@ file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) file(GLOB INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include) file(GLOB INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) -include_directories(${INCLUDE_DIRS} ${libClientEntities_INCLUDE_DIRS} ${HTTPCLIENT_lib_INCLUDE_DIRS}) +include_directories(${INCLUDE_DIRS} ${libClientEntities_INCLUDE_DIRS} ${HTTPCLIENT_lib_INCLUDE_DIRS} ${Boost_INCLUDE_DIR}) add_library(${PROJECT_NAME} ${SOURCES} ${INCLUDES}) -target_link_libraries(${PROJECT_NAME} ${libClientEntities_LIB} ${HTTPCLIENT_lib_LIB}) +target_link_libraries(${PROJECT_NAME} ${libClientEntities_LIB} ${HTTPCLIENT_lib_LIB} ${Boost_LIBRARIES}) set(CORE_lib_LIB ${PROJECT_NAME}) set(CORE_lib_LIB ${CORE_lib_LIB} PARENT_SCOPE) -set(CORE_lib_INCLUDE_DIRS ${INCLUDE_DIRS}) +set(CORE_lib_INCLUDE_DIRS ${LIB_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/include) set(CORE_lib_INCLUDE_DIRS ${CORE_lib_INCLUDE_DIRS} PARENT_SCOPE) \ No newline at end of file diff --git a/client/internal/core/include/Core.h b/client/internal/core/include/Core.h index d88af4d..f28be4a 100644 --- a/client/internal/core/include/Core.h +++ b/client/internal/core/include/Core.h @@ -4,15 +4,20 @@ #include #include "Task.h" +#include "Solution.h" class Core { public: - Core() { user_id = -1; }; - static unsigned signUp(const std::string &login, const std::string &username, const std::string &pass); static unsigned login(const std::string &login, const std::string &pass); + static std::vector getAllTasks(); + + static Solution submitSolution(const int& task_id, const std::string& path_to_file); + + static unsigned int createTask(const std::string &desc); + static void logout(); private: diff --git a/client/internal/core/src/Core.cpp b/client/internal/core/src/Core.cpp index bf3d43d..52baa40 100644 --- a/client/internal/core/src/Core.cpp +++ b/client/internal/core/src/Core.cpp @@ -5,22 +5,36 @@ #include "HttpClientManager.h" const std::string CLIENT_IP = "0.0.0.0"; -const std::string CLIENT_PORT = "80"; +const std::string CLIENT_PORT = "8080"; HttpClientManager client(CLIENT_IP, CLIENT_PORT); +std::size_t Core::user_id = -1; + unsigned Core::signUp(const std::string &login, const std::string &username, const std::string &pass) { auto res = client.registerUser(login, username, pass); - user_id = res.second.id; + Core::user_id = res.second.id; return res.first; } unsigned Core::login(const std::string &login, const std::string &pass) { auto res = client.loginUser(login, pass); - user_id = res.second.id; + Core::user_id = res.second.id; return res.first; } void Core::logout() { - user_id = -1; + Core::user_id = -1; +} + +std::vector Core::getAllTasks() { + return client.getAllTasks(); +} + +Solution Core::submitSolution(const int &task_id, const std::string &path_to_file) { + return client.submitSolution(user_id, task_id, path_to_file); +} + +unsigned int Core::createTask(const std::string &desc) { + return client.createTask(desc); } diff --git a/client/internal/entities/include/Solution.h b/client/internal/entities/include/Solution.h index 384e648..4cf7061 100644 --- a/client/internal/entities/include/Solution.h +++ b/client/internal/entities/include/Solution.h @@ -7,4 +7,5 @@ struct Solution { size_t id; std::string source; + std::string result; }; \ No newline at end of file diff --git a/client/internal/entities/src/Task.cpp b/client/internal/entities/src/Task.cpp index 496fddc..e1de440 100644 --- a/client/internal/entities/src/Task.cpp +++ b/client/internal/entities/src/Task.cpp @@ -1,3 +1,3 @@ #include "Task.h" -Task::Task(std::size_t id, std::string_view desc) : id(id), description(desc); \ No newline at end of file +Task::Task(std::size_t id, std::string_view desc) : id(id), description(desc) {}; \ No newline at end of file diff --git a/client/internal/gui/CMakeLists.txt b/client/internal/gui/CMakeLists.txt index 1f206bf..419c4dd 100644 --- a/client/internal/gui/CMakeLists.txt +++ b/client/internal/gui/CMakeLists.txt @@ -12,10 +12,10 @@ file(GLOB INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) set(CMAKE_PREFIX_PATH "~/Qt/6.5.0/macos/lib/cmake") find_package(Qt6 REQUIRED COMPONENTS Widgets Core Gui) -include_directories(${INCLUDE_DIRS} ${libClientEntities_INCLUDE_DIRS}) +include_directories(${INCLUDE_DIRS} ${libClientEntities_INCLUDE_DIRS} ${CORE_lib_INCLUDE_DIRS}) add_library(${PROJECT_NAME} ${SOURCES} ${INCLUDES}) -target_link_libraries(${PROJECT_NAME} ${libClientEntities_LIB} Qt6::Widgets Qt6::Core Qt6::Gui) +target_link_libraries(${PROJECT_NAME} ${libClientEntities_LIB} ${CORE_lib_LIB} Qt6::Widgets Qt6::Core Qt6::Gui) set(GUI_lib_LIB ${PROJECT_NAME}) set(GUI_lib_LIB ${GUI_lib_LIB} PARENT_SCOPE) diff --git a/client/internal/gui/include/AddTaskDialog.h b/client/internal/gui/include/AddTaskDialog.h new file mode 100644 index 0000000..c5b6547 --- /dev/null +++ b/client/internal/gui/include/AddTaskDialog.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +class AddTaskDialog : public QDialog { +Q_OBJECT + +public: + explicit AddTaskDialog(QWidget *parent = nullptr); + +public slots: + void on_createButton_clicked(); + void on_backButton_clicked(); + +private: + QVBoxLayout* verticalLayout = nullptr; + QLabel* label = nullptr; + QTextEdit* editor = nullptr; + QPushButton *createButton = nullptr; + QPushButton *backButton = nullptr; + + void setupUi(QDialog *AddTaskDialog); +}; diff --git a/client/internal/gui/include/SolutionsWindow.h b/client/internal/gui/include/SolutionsWindow.h index 103c2fb..80544e5 100644 --- a/client/internal/gui/include/SolutionsWindow.h +++ b/client/internal/gui/include/SolutionsWindow.h @@ -26,7 +26,7 @@ private slots: private: Task task; - std::string source; + std::string path_to_file; QWidget *centralwidget = nullptr; QGroupBox* taskBox = nullptr; diff --git a/client/internal/gui/include/TasksWindow.h b/client/internal/gui/include/TasksWindow.h index c8f96bd..1a897fd 100644 --- a/client/internal/gui/include/TasksWindow.h +++ b/client/internal/gui/include/TasksWindow.h @@ -20,6 +20,7 @@ public: public slots: void on_backButton_clicked(); + void on_addTaskButton_clicked(); void on_goToTaskButton_clicked(); void indexChanged(); @@ -33,6 +34,7 @@ private: QComboBox* tasks = nullptr; QLabel* taskDescription = nullptr; QPushButton* goToTaskButton = nullptr; + QPushButton* addTaskButton = nullptr; QPushButton* backButton = nullptr; QWidget* buttonsWidget = nullptr; QHBoxLayout* buttonsLayout = nullptr; @@ -40,6 +42,7 @@ private: std::vector tasks_vector; void setupUi(QMainWindow *UserWindow); + void updateTasks(); }; #endif // USERWINDOW_H diff --git a/client/internal/gui/src/AddTaskDialog.cpp b/client/internal/gui/src/AddTaskDialog.cpp new file mode 100644 index 0000000..3fefa31 --- /dev/null +++ b/client/internal/gui/src/AddTaskDialog.cpp @@ -0,0 +1,60 @@ +#include "AddTaskDialog.h" + +#include +#include + +#include "Core.h" + +AddTaskDialog::AddTaskDialog(QWidget *parent) : QDialog(parent) { + setupUi(this); + + connect(createButton, &QPushButton::clicked, this, &AddTaskDialog::on_createButton_clicked); + connect(backButton, &QPushButton::clicked, this, &AddTaskDialog::on_backButton_clicked); +} + +void AddTaskDialog::setupUi(QDialog *AddTaskDialog) { + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(AddTaskDialog->sizePolicy().hasHeightForWidth()); + AddTaskDialog->setSizePolicy(sizePolicy); + + verticalLayout = new QVBoxLayout(AddTaskDialog); + + label = new QLabel(AddTaskDialog); + label->setText(QString::fromUtf8("Введите текст задания")); + verticalLayout->addWidget(label); + + editor = new QTextEdit(AddTaskDialog); + verticalLayout->addWidget(editor); + + createButton = new QPushButton(AddTaskDialog); + createButton->setText(QString::fromUtf8("Создать задание")); + verticalLayout->addWidget(createButton); + + backButton = new QPushButton(AddTaskDialog); + backButton->setText(QString::fromUtf8("Назад")); + verticalLayout->addWidget(backButton); +} + +void AddTaskDialog::on_createButton_clicked() { + std::string desc = editor->toPlainText().toUtf8().constData(); + if (desc.empty()) { + QMessageBox::warning(this, "Ошибка отправки", "Описание не может быть пустыми"); + return; + } + unsigned result = Core::createTask(desc); + switch (result) { + case 200: + accept(); + close(); + break; + default: + QMessageBox::critical(this, "Отправка невозможна", "Нет соединения с сервером"); + } +} + +void AddTaskDialog::on_backButton_clicked() { + reject(); + close(); +} diff --git a/client/internal/gui/src/AuthDialog.cpp b/client/internal/gui/src/AuthDialog.cpp index 5227149..2f35768 100644 --- a/client/internal/gui/src/AuthDialog.cpp +++ b/client/internal/gui/src/AuthDialog.cpp @@ -3,6 +3,8 @@ #include #include +#include "Core.h" + AuthDialog::AuthDialog(QWidget *parent) : QDialog(parent) { setupUi(this); } @@ -64,15 +66,13 @@ void AuthDialog::on_loginButton_clicked() { QMessageBox::warning(this, "Ошибка авторизации", "Логин и пароль не могут быть пустыми"); return; } -// unsigned result = Core::login(log, pass); - unsigned result = 200; + unsigned result = Core::login(std::string(log), std::string(pass)); switch (result) { case 200: - QMessageBox::warning(this, "Успешная авторизации", "Работает"); accept(); close(); break; - case 403: + case 404: QMessageBox::warning(this, "Ошибка авторизации","Неправильный логин или пароль"); break; default: diff --git a/client/internal/gui/src/SignUpDialog.cpp b/client/internal/gui/src/SignUpDialog.cpp index 015f65f..1cdc2a3 100644 --- a/client/internal/gui/src/SignUpDialog.cpp +++ b/client/internal/gui/src/SignUpDialog.cpp @@ -4,7 +4,7 @@ #include #include -//#include "Core.h" +#include "Core.h" SignUpDialog::SignUpDialog(QWidget *parent) : QDialog(parent) { setupUi(this); @@ -74,13 +74,12 @@ void SignUpDialog::retranslateUi(QDialog *SignUpDialog) { } void SignUpDialog::on_signUpButton_clicked() { - std::string login = this->login->text().toUtf8().constData(); - std::string username = this->username->text().toUtf8().constData(); - std::string password = this->password->text().toUtf8().constData(); - std::string passwordRepeat = this->passwordRepeat->text().toUtf8().constData(); - if (password == passwordRepeat && !login.empty() && !username.empty()) { -// unsigned response = Core::signUp(log.toStdString(), pass.toStdString()); - unsigned response = 200; + std::string log = this->login->text().toUtf8().constData(); + std::string usr = this->username->text().toUtf8().constData(); + std::string pass = this->password->text().toUtf8().constData(); + std::string passRepeat = this->passwordRepeat->text().toUtf8().constData(); + if (pass == passRepeat && !log.empty() && !usr.empty()) { + unsigned response = Core::signUp(log, usr, pass); switch (response) { case 200: QMessageBox::information(this, "Успех!", "Вы успешно зарегистрированы!"); @@ -94,9 +93,9 @@ void SignUpDialog::on_signUpButton_clicked() { QMessageBox::critical(this, "Регистрация невозможна!", "Нет соединения с сервером!"); } - } else if (login.empty()) { + } else if (log.empty()) { QMessageBox::warning(this, "Ошибка!", "Логин не может быть пустым!"); - } else if (username.empty()) { + } else if (usr.empty()) { QMessageBox::warning(this, "Ошибка!", "Имя не может быть пустым!"); } else { QMessageBox::warning(this, "Ошибка!", "Пароли не совпадают!"); diff --git a/client/internal/gui/src/SolutionsWindow.cpp b/client/internal/gui/src/SolutionsWindow.cpp index 33743ee..17832a3 100644 --- a/client/internal/gui/src/SolutionsWindow.cpp +++ b/client/internal/gui/src/SolutionsWindow.cpp @@ -5,6 +5,9 @@ #include #include +#include "Solution.h" +#include "Core.h" + SolutionsWindow::SolutionsWindow(Task task, QWidget *parent) : QMainWindow(parent), task(std::move(task)) { setupUi(this); connect(backButton, &QPushButton::clicked, this, &SolutionsWindow::on_backButton_clicked); @@ -63,18 +66,12 @@ void SolutionsWindow::on_backButton_clicked() { void SolutionsWindow::on_chooseFileButton_clicked() { QString fileName = QFileDialog::getOpenFileName(this, tr("Choose a file to send"), QDir::homePath()); filename->setText(QFileInfo(fileName).fileName()); - std::ifstream file(fileName.toUtf8().constData()); - std::ostringstream sstr; - sstr << file.rdbuf(); - source = sstr.str(); + path_to_file = fileName.toUtf8().constData(); } void SolutionsWindow::on_sendButton_clicked() { - if (source.empty()) { - QMessageBox::warning(this, "Ошибка отправки", "Нельзя отправить пустое решение"); - return; - } - std::cout << source; + Solution sol = Core::submitSolution(task.id, path_to_file); + result->setText(QString::fromStdString(sol.result)); } diff --git a/client/internal/gui/src/TasksWindow.cpp b/client/internal/gui/src/TasksWindow.cpp index f5c4884..04cebc7 100644 --- a/client/internal/gui/src/TasksWindow.cpp +++ b/client/internal/gui/src/TasksWindow.cpp @@ -5,36 +5,23 @@ #include #include "SolutionsWindow.h" +#include "AddTaskDialog.h" #include "UIManager.h" +#include "Core.h" TasksWindow::TasksWindow(QWidget *parent) : QMainWindow(parent) { - tasks_vector.push_back({1, "1 description 1\n" - "1\n" - "2\n" - "3\n" - "4\n" - "5\n" - "6\n" - "7\n" - "8\n" - "9\n" - "10\n" - "11\n" - "12\n" - "13\n" - "14\n"}); - tasks_vector.push_back({2, "2 description"}); - tasks_vector.push_back({3, "3 description"}); - setupUi(this); connect(tasks, &QComboBox::currentIndexChanged, this, &TasksWindow::indexChanged); connect(goToTaskButton, &QPushButton::clicked, this, &TasksWindow::on_goToTaskButton_clicked); connect(backButton, &QPushButton::clicked, this, &TasksWindow::on_backButton_clicked); + connect(addTaskButton, &QPushButton::clicked, this, &TasksWindow::on_addTaskButton_clicked); } void TasksWindow::setupUi(QMainWindow *UserWindow) { + tasks_vector = Core::getAllTasks(); + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); @@ -76,10 +63,14 @@ void TasksWindow::setupUi(QMainWindow *UserWindow) { goToTaskButton = new QPushButton(this); goToTaskButton->setText(QString::fromUtf8("Перейти к сдаче")); + addTaskButton = new QPushButton(this); + addTaskButton->setText(QString::fromUtf8("Добавить задание")); + backButton = new QPushButton(this); backButton->setText(QString::fromUtf8("Выйти")); buttonsLayout->addWidget(goToTaskButton); + buttonsLayout->addWidget(addTaskButton); buttonsLayout->addWidget(backButton); verticalLayout->addWidget(taskChooseGroupBox); @@ -95,7 +86,7 @@ void TasksWindow::indexChanged() { } void TasksWindow::on_backButton_clicked() { - // Core::logout(); + Core::logout(); close(); qobject_cast(parent())->showEntryWindow(); } @@ -105,3 +96,22 @@ void TasksWindow::on_goToTaskButton_clicked() { auto* solutionsWindow = new SolutionsWindow(tasks_vector[tasks->currentIndex()], this); solutionsWindow->show(); } + +void TasksWindow::on_addTaskButton_clicked() { + AddTaskDialog addTaskDialog(this); + if (addTaskDialog.exec() == QDialog::Accepted) { + updateTasks(); + } +} + +void TasksWindow::updateTasks() { + tasks_vector = Core::getAllTasks(); + tasks->clear(); + for (int i = 0; i < tasks_vector.size(); i++) { + tasks->insertItem(i, QString::number(tasks_vector[i].id)); + } + tasks->setCurrentIndex(0); + + std::string description = tasks_vector[0].description; + taskDescription->setText(QString(description.c_str())); +} diff --git a/client/internal/httpClient/include/HttpClient.h b/client/internal/httpClient/include/HttpClient.h index 058c2b4..42c5f6d 100644 --- a/client/internal/httpClient/include/HttpClient.h +++ b/client/internal/httpClient/include/HttpClient.h @@ -16,7 +16,7 @@ using tcp = net::ip::tcp; class HttpClient : public IHttpClient { public: - HttpClient(std::string_view host, std::string_view port); + HttpClient(std::string_view host_, std::string_view port_); http::response makeGetRequest(std::string_view target, std::string_view body) override; http::response makePostRequest(std::string_view target, std::string_view body) override; @@ -29,6 +29,7 @@ private: tcp::resolver resolver; beast::tcp_stream stream; std::string host; + std::string port; }; diff --git a/client/internal/httpClient/include/HttpClientManager.h b/client/internal/httpClient/include/HttpClientManager.h index eb93fcb..80e73b9 100644 --- a/client/internal/httpClient/include/HttpClientManager.h +++ b/client/internal/httpClient/include/HttpClientManager.h @@ -19,10 +19,11 @@ public: std::pair loginUser(const std::string &login, const std::string &password); std::pair registerUser(const std::string &login, const std::string &username, const std::string &password); - unsigned int submitSolution(const int& user_id, const std::string &path_to_solution); + Solution submitSolution(const int& user_id, const int &task_id, const std::string &path_to_solution); unsigned int getAllSolutionsForTask(const int& user_id, const int& task_id); std::vector getAllTasks(); - std::vector getMetrics(const int& sol_id); + unsigned int createTask(const std::string& desc); +// std::vector getMetrics(const int& sol_id); void setHttpClient(std::shared_ptr client_); private: std::string host; diff --git a/client/internal/httpClient/include/Serializer.h b/client/internal/httpClient/include/Serializer.h index 42be6c8..80bdb42 100644 --- a/client/internal/httpClient/include/Serializer.h +++ b/client/internal/httpClient/include/Serializer.h @@ -4,11 +4,18 @@ #include #include #include "User.h" +#include "Task.h" +#include "Solution.h" class Serializer { public: std::string serialLoginData(std::string_view login, std::string_view password); std::string serialRegisterData(std::string_view login, std::string_view username, std::string_view password); + std::string serialSolutionData(const int& user_id, const int& task_id, const std::string& path_to_file); + std::string serialNewTaskData(std::string_view desc); + User deserialUserData(std::string_view body); + Solution deserialSolutionData(std::string_view body); + std::vector deserialAllTasks(std::string_view body); }; diff --git a/client/internal/httpClient/src/HttpClient.cpp b/client/internal/httpClient/src/HttpClient.cpp index d9f09fe..2dd0245 100644 --- a/client/internal/httpClient/src/HttpClient.cpp +++ b/client/internal/httpClient/src/HttpClient.cpp @@ -3,20 +3,23 @@ #include #include -HttpClient::HttpClient(std::string_view host_, std::string_view port) : +HttpClient::HttpClient(std::string_view host_, std::string_view port_) : host(host_), + port(port_), resolver(io_context), - stream(io_context) { - auto const results = resolver.resolve(host, port); - stream.connect(results); -} + stream(io_context) {} http::response HttpClient::makeRequest(std::string_view target, http::verb method, std::string_view body) { - http::request req{http::verb::get, target, 10}; + auto const results = resolver.resolve(host, port); + stream.connect(results); + http::request req{http::verb::get, target, 11}; req.set(http::field::host, host); req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING); + req.set(http::field::content_type, "text/plain"); + req.content_length(body.size()); + req.body() = body; http::write(stream, req); diff --git a/client/internal/httpClient/src/HttpClientManager.cpp b/client/internal/httpClient/src/HttpClientManager.cpp index a269f65..7d6da4f 100644 --- a/client/internal/httpClient/src/HttpClientManager.cpp +++ b/client/internal/httpClient/src/HttpClientManager.cpp @@ -20,7 +20,9 @@ std::pair HttpClientManager::loginUser(const std::string &login, auto* cbuf = boost::asio::buffer_cast(seq); res_body.append(cbuf, boost::asio::buffer_size(seq)); } - User user = serializer->deserialUserData(res_body); + User user{0, "", "", ""}; + if (status == 200) + user = serializer->deserialUserData(res_body); return {status, user}; } @@ -38,22 +40,41 @@ std::pair HttpClientManager::registerUser(const std::string &log return {status, user}; } -unsigned int HttpClientManager::submitSolution(const int &user_id, const std::string &path_to_sound) { - return 0; +Solution HttpClientManager::submitSolution(const int &user_id, const int &task_id, const std::string &path_to_sound) { + std::string body = serializer->serialSolutionData(user_id, task_id, path_to_sound); + http::response res = client->makeGetRequest("/solution/submit", body); + unsigned status = res.result_int(); + std::string res_body; + for (auto seq : res.body().data()) { + auto* cbuf = boost::asio::buffer_cast(seq); + res_body.append(cbuf, boost::asio::buffer_size(seq)); + } + Solution sol = serializer->deserialSolutionData(res_body); + return sol; } unsigned int HttpClientManager::getAllSolutionsForTask(const int &user_id, const int &task_id) { return 0; } -std::vector HttpClientManager::getMetrics(const int &sol_id) { - return std::vector(); -} - void HttpClientManager::setHttpClient(std::shared_ptr client_) { client = client_; } std::vector HttpClientManager::getAllTasks() { - return std::vector(); + http::response res = client->makeGetRequest("/task/all", ""); + std::string res_body; + for (auto seq : res.body().data()) { + auto* cbuf = boost::asio::buffer_cast(seq); + res_body.append(cbuf, boost::asio::buffer_size(seq)); + } + std::vector tasks = serializer->deserialAllTasks(res_body); + return tasks; +} + +unsigned int HttpClientManager::createTask(const std::string &desc) { + std::string body = serializer->serialNewTaskData(desc); + http::response res = client->makeGetRequest("/task/create", body); + unsigned int result = res.result_int(); + return result; } diff --git a/client/internal/httpClient/src/Serializer.cpp b/client/internal/httpClient/src/Serializer.cpp index c2d5567..e76eca4 100644 --- a/client/internal/httpClient/src/Serializer.cpp +++ b/client/internal/httpClient/src/Serializer.cpp @@ -1,6 +1,7 @@ #include "Serializer.h" #include +#include #include #include @@ -37,3 +38,51 @@ Serializer::serialRegisterData(std::string_view login, std::string_view username boost::property_tree::write_json(out, json); return out.str(); } + +std::vector Serializer::deserialAllTasks(std::string_view body) { + std::stringstream ss; + ss << body; + boost::property_tree::ptree json; + boost::property_tree::read_json(ss, json); + std::vector tasks; + for (auto &sound : json.get_child("tasks")) { + Task new_task(sound.second.get("task_id"), sound.second.get("description")); + tasks.push_back(new_task); + } + return tasks; +} + +std::string Serializer::serialSolutionData(const int &user_id, const int &task_id, const std::string& path_to_file) { + boost::property_tree::ptree json; + json.put("user_id", user_id); + json.put("task_id", task_id); + std::ifstream file(path_to_file); + std::ostringstream sstr; + sstr << file.rdbuf(); + std::string source = sstr.str(); + json.put("source", source); + std::stringstream out; + boost::property_tree::write_json(out, json); + return out.str(); +} + +Solution Serializer::deserialSolutionData(std::string_view body) { + std::stringstream ss; + ss << body; + boost::property_tree::ptree json; + boost::property_tree::read_json(ss, json); + Solution res = { + json.get("sol_id"), + json.get("source"), + json.get("result"), + }; + return res; +} + +std::string Serializer::serialNewTaskData(std::string_view desc) { + boost::property_tree::ptree json; + json.put("description", desc); + std::stringstream out; + boost::property_tree::write_json(out, json); + return out.str(); +} diff --git a/server/internal/httpServer/include/Serializer.h b/server/internal/httpServer/include/Serializer.h index 9af1b01..19120d1 100644 --- a/server/internal/httpServer/include/Serializer.h +++ b/server/internal/httpServer/include/Serializer.h @@ -21,6 +21,7 @@ public: std::string serialSolutions(const std::vector& solutions); std::string serialAllTasks(const std::vector& tasks); std::string serialUserData(const User& user); + std::string serialSolution(const Solution& sol); }; diff --git a/server/internal/httpServer/include/SolutionManager.h b/server/internal/httpServer/include/SolutionManager.h index 2c69a61..166aee3 100644 --- a/server/internal/httpServer/include/SolutionManager.h +++ b/server/internal/httpServer/include/SolutionManager.h @@ -17,7 +17,6 @@ class SolutionManager : public ISolutionManager { SolutionManager(); http::message_generator getAllSolutions(http::request&& req) override; http::message_generator createSolution(http::request&& req) override; - http::message_generator getMetrics(http::request&& req) override; void setService(std::shared_ptr service); private: diff --git a/server/internal/httpServer/include/TaskManager.h b/server/internal/httpServer/include/TaskManager.h index 3adecd4..361c7a8 100644 --- a/server/internal/httpServer/include/TaskManager.h +++ b/server/internal/httpServer/include/TaskManager.h @@ -1,5 +1,4 @@ -#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_TaskMANAGER_H_ -#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_TaskMANAGER_H_ +#pragma once #include #include @@ -18,5 +17,3 @@ private: std::shared_ptr taskService; std::shared_ptr serializer; }; - -#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_TaskMANAGER_H_ diff --git a/server/internal/httpServer/include/TmpSolutionService.h b/server/internal/httpServer/include/TmpSolutionService.h new file mode 100644 index 0000000..63cab8d --- /dev/null +++ b/server/internal/httpServer/include/TmpSolutionService.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include "Solution.hpp" + +class TmpSolutionService { +public: + static Solution createSolution(std::size_t user_id, std::size_t task_id, std::string source) { + count++; + Solution sol(count, "", user_id, source, "", "", task_id, "ok"); + for (auto& i: solutions) { + if (i.getSource() == source && i.getTaskId() == task_id && i.getSenderId() != user_id) + sol.setResult("plagiat"); + } + solutions.push_back(sol); + return sol; + } + + static std::size_t count; + static std::vector solutions; +}; + +std::vector TmpSolutionService::solutions = {}; +std::size_t TmpSolutionService::count = 3; diff --git a/server/internal/httpServer/include/TmpTaskService.h b/server/internal/httpServer/include/TmpTaskService.h new file mode 100644 index 0000000..90f2f76 --- /dev/null +++ b/server/internal/httpServer/include/TmpTaskService.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include "Task.hpp" + +class TmpTaskService { +public: + static void createTask(std::string description) { + count++; + Task task(count, description); + tasks.push_back(task); + } + + static std::vector getAllTasks() { + return tasks; + } + + static std::size_t count; + static std::vector tasks; +}; + +std::vector TmpTaskService::tasks = {Task(1, "1 description 1\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "14\n"), + Task(2, "2 description"), + Task(3, "3 description")}; +std::size_t TmpTaskService::count = 3; \ No newline at end of file diff --git a/server/internal/httpServer/include/TmpUserService.h b/server/internal/httpServer/include/TmpUserService.h new file mode 100644 index 0000000..cd60903 --- /dev/null +++ b/server/internal/httpServer/include/TmpUserService.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include "User.hpp" + +class TmpUserService { +public: + static std::pair login(std::string_view login, std::string_view password) { + bool found = false; + User user; + for (const auto& i : tasks) { + if (i.getPassword() == password && i.getLogin() == login && !found) { + user = i; + found = true; + } + } + return {user, found}; + } + + static User registerUser(std::string login, std::string password, std::string username) { + count++; + User user(count, login, password, username); + std::cout << user << std::endl; + tasks.push_back(user); + return user; + } + + static std::size_t count; + static std::vector tasks; +}; + +std::vector TmpUserService::tasks = {}; +std::size_t TmpUserService::count = 0; diff --git a/server/internal/httpServer/src/Router.cpp b/server/internal/httpServer/src/Router.cpp index 59b5791..88d83c2 100644 --- a/server/internal/httpServer/src/Router.cpp +++ b/server/internal/httpServer/src/Router.cpp @@ -33,12 +33,8 @@ http::message_generator Router::handleRequest(http::request & return getBadRequest(req, "Illegal request-target"); } - std::cout << req.target() << std::endl; - if (req.target() == "/solution/submit") { return solutionManager->createSolution(std::move(req)); - } else if (req.target() == "/solution/metrics") { - return solutionManager->getMetrics(std::move(req)); } else if (req.target() == "/solution/all") { return solutionManager->getAllSolutions(std::move(req)); } else if (req.target() == "/user/register") { diff --git a/server/internal/httpServer/src/Serializer.cpp b/server/internal/httpServer/src/Serializer.cpp index 108430a..8d1905c 100644 --- a/server/internal/httpServer/src/Serializer.cpp +++ b/server/internal/httpServer/src/Serializer.cpp @@ -104,7 +104,7 @@ std::string Serializer::serialAllTasks(const std::vector &tasks) { std::string Serializer::serialUserData(const User &user) { boost::property_tree::ptree json; - json.put("id", user.getId()); + json.put("user_id", user.getId()); json.put("login", user.getLogin()); json.put("username", user.getUsername()); json.put("password", user.getPassword()); @@ -112,3 +112,13 @@ std::string Serializer::serialUserData(const User &user) { boost::property_tree::write_json(out, json); return out.str(); } + +std::string Serializer::serialSolution(const Solution &sol) { + boost::property_tree::ptree json; + json.put("sol_id", sol.getId()); + json.put("source", sol.getSource()); + json.put("result", sol.getResult()); + std::stringstream out; + boost::property_tree::write_json(out, json); + return out.str(); +} diff --git a/server/internal/httpServer/src/SolutionManager.cpp b/server/internal/httpServer/src/SolutionManager.cpp index e83c027..c85dc98 100644 --- a/server/internal/httpServer/src/SolutionManager.cpp +++ b/server/internal/httpServer/src/SolutionManager.cpp @@ -4,6 +4,7 @@ #include "SolutionManager.h" #include +#include "TmpSolutionService.h" SolutionManager::SolutionManager() : serializer(std::make_shared()) {}; @@ -13,17 +14,16 @@ void SolutionManager::setService(std::shared_ptr service) { } http::message_generator SolutionManager::createSolution(http::request&& req) { - size_t user_id, task_id; std::string source; std::tie(user_id, source, task_id) = serializer->deserialNewSolutionData(req.body()); - Solution sol; - sol = solutionService->createSolution(user_id, task_id, source); + Solution sol = TmpSolutionService::createSolution(user_id, task_id, source); +// sol = solutionService->createSolution(user_id, task_id, source); http::response res{http::status::ok, req.version()}; res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, "text/plain"); res.keep_alive(req.keep_alive()); - res.body() = std::to_string(sol.getId()); + res.body() = serializer->serialSolution(sol); res.prepare_payload(); return res; } @@ -40,22 +40,5 @@ http::message_generator SolutionManager::getAllSolutions(http::requestserialSolutions(solutions); res.prepare_payload(); return res; - -} - -http::message_generator SolutionManager::getMetrics(http::request&& req) { - auto const bad_request = - [&req](beast::string_view why) - { - http::response res{http::status::bad_request, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, "text/html"); - res.keep_alive(req.keep_alive()); - res.body() = std::string(why); - res.prepare_payload(); - return res; - }; - - return bad_request("123"); } diff --git a/server/internal/httpServer/src/TaskManager.cpp b/server/internal/httpServer/src/TaskManager.cpp index 2b45867..91ca64b 100644 --- a/server/internal/httpServer/src/TaskManager.cpp +++ b/server/internal/httpServer/src/TaskManager.cpp @@ -2,6 +2,7 @@ // Created by Николай Степанов on 03.05.2023. // #include "TaskManager.h" +#include "TmpTaskService.h" TaskManager::TaskManager() : serializer(std::make_shared()) {} @@ -11,7 +12,8 @@ void TaskManager::setService(std::shared_ptr service) { http::message_generator TaskManager::createTask(http::request &&req) { std::string description = serializer->deserialNewTaskData(req.body()); - taskService->createTask(description); +// taskService->createTask(description); + TmpTaskService::createTask(description); http::response res{http::status::ok, req.version()}; res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, "text/plain"); @@ -21,7 +23,8 @@ http::message_generator TaskManager::createTask(http::request &&req) { - std::vector tasks = taskService->getAllTasks(); +// std::vector tasks = taskService->getAllTasks(); + std::vector tasks = TmpTaskService::getAllTasks(); http::response res{http::status::ok, req.version()}; res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, "text/plain"); diff --git a/server/internal/httpServer/src/UserManager.cpp b/server/internal/httpServer/src/UserManager.cpp index 335ad4d..dcff74b 100644 --- a/server/internal/httpServer/src/UserManager.cpp +++ b/server/internal/httpServer/src/UserManager.cpp @@ -1,5 +1,7 @@ #include "UserManager.h" +#include "TmpUserService.h" + UserManager::UserManager() : serializer(std::make_shared()) {} void UserManager::setService(std::shared_ptr service) { @@ -10,20 +12,13 @@ http::message_generator UserManager::loginUser(http::request std::string login, password; std::tie(login, password) = serializer->deserialUserData(req.body()); - bool found = false; - User user; - for (const auto& i : users) { - if (i.getPassword() == password && i.getLogin() == login && !found) { - user = i; - found = true; - } - } - if (found) { + auto result = TmpUserService::login(login, password); + if (result.second) { http::response res{http::status::ok, req.version()}; res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, "text/plain"); res.keep_alive(req.keep_alive()); - res.body() = serializer->serialUserData(user); + res.body() = serializer->serialUserData(result.first); res.prepare_payload(); return res; } else { @@ -31,7 +26,7 @@ http::message_generator UserManager::loginUser(http::request res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, "text/plain"); res.keep_alive(req.keep_alive()); - res.body() = serializer->serialUserData(user); + res.body() = serializer->serialUserData(result.first); res.prepare_payload(); return res; } @@ -41,10 +36,7 @@ http::message_generator UserManager::registerUser(http::request deserialNewUserData(req.body()); // User user = userService->createUser(login, username, password); - count++; - User user = User(count, login, password, username); - std::cout << user << std::endl; - users.push_back(user); + User user = TmpUserService::registerUser(login, password, username); http::response res{http::status::ok, req.version()}; res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, "text/plain"); diff --git a/server/internal/httpServer/virtual/ISolutionManager.h b/server/internal/httpServer/virtual/ISolutionManager.h index ab86bc6..62f0f2a 100644 --- a/server/internal/httpServer/virtual/ISolutionManager.h +++ b/server/internal/httpServer/virtual/ISolutionManager.h @@ -10,7 +10,6 @@ class ISolutionManager { public: virtual http::message_generator getAllSolutions(http::request&& req) = 0; virtual http::message_generator createSolution(http::request&& req) = 0; - virtual http::message_generator getMetrics(http::request&& req) = 0; }; #endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_ISolutionMANAGER_H_ -- GitLab