Compare commits
104 Commits
drogoncms-
...
master
Author | SHA1 | Date | |
---|---|---|---|
014e39e5ef | |||
|
ce58668f22 | ||
f1ac5817f8 | |||
|
8273ba0217 | ||
384a175659 | |||
|
65da95ffa0 | ||
|
b7690af06e | ||
48a7c3fbb3 | |||
|
43c9cbb39b | ||
|
6227ab9bc3 | ||
|
cae339e982 | ||
c3e65babe6 | |||
|
f0c5df763d | ||
0881980d42 | |||
|
2e82e6b5a1 | ||
|
9584e57b90 | ||
ab95a14957 | |||
|
24fe6569d9 | ||
b2cd158c1c | |||
|
6ade0faebb | ||
94361da4bc | |||
|
11deec3ea5 | ||
|
a5c4ebb65b | ||
223c21198b | |||
|
092b56b16f | ||
1614b6332c | |||
|
1f7f6a569c | ||
|
002ffe3b0f | ||
|
04444a75ab | ||
fdb3df1b32 | |||
|
f44cc9b9bf | ||
4ca10f27a0 | |||
|
7260ecf164 | ||
0526e75a31 | |||
|
f6e897c3bf | ||
|
829e06a4d0 | ||
4e95142715 | |||
|
a6fb6d5833 | ||
d3940036a2 | |||
|
8cfaa64896 | ||
|
6bc4593f2f | ||
5fd2fd89e3 | |||
|
a72cfa8a09 | ||
4f8b500ce8 | |||
|
cfab45ab1c | ||
2385a4e878 | |||
|
8beeb99518 | ||
f75efeb0af | |||
|
fdfb2c7cad | ||
b8adcfdc30 | |||
|
07c87ea811 | ||
6518f7c9c6 | |||
|
3525c55e81 | ||
f7c389e6d5 | |||
|
3bf5be976e | ||
31af62a55d | |||
|
1fbeedd4c2 | ||
0698556a7e | |||
|
708f4907c0 | ||
ee4872a1fa | |||
|
78d6407050 | ||
125a6ebf8e | |||
|
74c44a6fc3 | ||
b75a1f867e | |||
|
b3dbd3884a | ||
701349a115 | |||
|
f2ac577c50 | ||
022bcc2af8 | |||
|
ad8989f395 | ||
|
a911189edd | ||
|
27534a1412 | ||
|
9c16448922 | ||
|
3df620c709 | ||
|
ab344e0014 | ||
|
033c7d69f4 | ||
|
4c9f3c654d | ||
|
f4f7fc2029 | ||
|
c4a531886a | ||
|
e610be0ba1 | ||
|
0fcc062bdb | ||
|
c756d3e3e3 | ||
|
ed386b1c89 | ||
|
92db44d9be | ||
|
9e4982aec4 | ||
|
0d52a3c382 | ||
|
9413b13d86 | ||
|
ff48c8947d | ||
|
6d63ea13b3 | ||
|
efcb3a1961 | ||
|
46bfbdb46c | ||
|
7ac031fc5f | ||
|
1242170439 | ||
|
8dfe403cf9 | ||
|
f619516c6b | ||
|
04f2207e2c | ||
|
942af8a3c0 | ||
|
b8e26dff9c | ||
|
1d051d4a3a | ||
|
138313f9ce | ||
|
76c2bfc873 | ||
|
9d432b3ac0 | ||
|
88b448f5d9 | ||
|
9e291c3504 | ||
|
a47b1a8b28 |
26
.gitignore
vendored
26
.gitignore
vendored
@ -15,6 +15,7 @@ autom4te.cache
|
||||
/autoscan.log
|
||||
/autoscan-*.log
|
||||
/aclocal.m4
|
||||
build
|
||||
/compile
|
||||
/config.cache
|
||||
/config.guess
|
||||
@ -30,7 +31,26 @@ autom4te.cache
|
||||
/stamp-h1
|
||||
configure~
|
||||
build-aux
|
||||
build
|
||||
build/
|
||||
cmake_install.cmake
|
||||
CTestTestfile.cmake
|
||||
CMakeFiles/
|
||||
CMakeCache.txt
|
||||
CMakeDoxyfile.in
|
||||
CMakeDoxygenDefaults.cmake
|
||||
CPackConfig.cmake
|
||||
CPackSourceConfig.cmake
|
||||
vendors/drogon/Doxyfile.doc_drogon
|
||||
vendors/drogon/DrogonConfigVersion.cmake
|
||||
vendors/drogon/drogon/
|
||||
vendors/drogon/exports/
|
||||
vendors/drogon/trantor/Doxyfile.doc_trantor
|
||||
vendors/drogon/trantor/TrantorConfigVersion.cmake
|
||||
vendors/drogon/trantor/exports/
|
||||
vendors/database/
|
||||
postgresql-prefix/
|
||||
CPM_modules/
|
||||
_deps/
|
||||
|
||||
# https://www.gnu.org/software/libtool/
|
||||
|
||||
@ -51,6 +71,10 @@ m4/lt~obsolete.m4
|
||||
# exclude executables
|
||||
|
||||
/drogon_dashboard
|
||||
/DrogonCMS
|
||||
vendors/api-server/DrogonCMS_API_Server
|
||||
vendors/api-server/test/local-server_test
|
||||
vendors/simple-reverse-proxy/DrogonCMS_Reverse_Proxy
|
||||
|
||||
# Generated Makefile
|
||||
# (meta build system like autotools,
|
||||
|
224
CMakeLists.txt
Normal file
224
CMakeLists.txt
Normal file
@ -0,0 +1,224 @@
|
||||
# This is a Drogon Content Management System(CMS) built on GTK4.
|
||||
# Copyright (C) 2024-PRESENT SHARPETRONICS, LLC
|
||||
# Copyright (C) 2024-PRESENT ODINZU WENKI(CHARLES)
|
||||
|
||||
# This is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# Under Section 7 of GPL version 3, you are granted additional
|
||||
# permissions described in the GCC Runtime Library Exception, version
|
||||
# 3.1, as published by the Free Software Foundation.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; see the files LICENSE and LICENSE_EXCEPTION respectively.
|
||||
# If not, see <http://www.gnu.org/licenses/>.
|
||||
#===============================================================================
|
||||
# AUTHORED DATE: 01.14.2024
|
||||
|
||||
# Almost all CMake files should start with this
|
||||
# You should always specify a range with the newest
|
||||
# and oldest tested versions of CMake. This will ensure
|
||||
# you pick up the best policies.
|
||||
cmake_minimum_required(VERSION 3.1...3.28)
|
||||
file(GLOB_RECURSE SOURCES RELATIVE ${CMAKE_SOURCE_DIR} "src/*.c")
|
||||
|
||||
# If you set any CMAKE_ variables, that can go here.
|
||||
# (But usually don't do this, except maybe for C++ standard)
|
||||
set(CMAKE_PROJECT_DESCRIPTION "A GTK Drogon CMS")
|
||||
set(CMAKE_PROJECT_HOMEPAGE_URL "https://github.com/odinzu/drogoncms")
|
||||
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/vendors/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# add CPM Deps. for C
|
||||
# Note: only packages that have a CMakeLists.txt..
|
||||
include(vendors/cmake/CPM_0.38.7.cmake)
|
||||
|
||||
#CPMAddPackage("gh:postgres/postgres#7.1.3")
|
||||
#CPMAddPackage("gh:nlohmann/json@3.10.5")
|
||||
|
||||
# This is your project statement. You should always list languages;
|
||||
# Listing the version is nice here since it sets lots of useful variables
|
||||
# we removed LANGUAGES C from project to allow for automatic compiler/linker checks; we will use C and C++ libraries for this project.
|
||||
project(
|
||||
DrogonCMS
|
||||
VERSION 1.0.0
|
||||
)
|
||||
|
||||
# Adding something we can run - Output name matches target name
|
||||
add_executable(DrogonCMS ${SOURCES})
|
||||
|
||||
#===============================================================================
|
||||
# Setting compilation flags for various compilers and build types:
|
||||
#===============================================================================
|
||||
|
||||
# some test warning levels for GCC
|
||||
set(WARNING_LEVELS_GCC
|
||||
#-Werror
|
||||
)
|
||||
set(WARNING_LEVELS_GCC_DEBUG
|
||||
#-Wfloat-equal
|
||||
#-Wextra
|
||||
-Wall
|
||||
-Wdeprecated-declarations
|
||||
#-Wundef
|
||||
#-Wshadow
|
||||
#-Wpointer-arith
|
||||
#-Wcast-align
|
||||
#-Wstrict-overflow=5
|
||||
#-Wwrite-strings
|
||||
#-Waggregate-return
|
||||
#-Wcast-qual
|
||||
#-Wswitch-default
|
||||
#-Wswitch-enum
|
||||
#-Wconversion
|
||||
)
|
||||
|
||||
# Print system, compiler CMake ID, version and path:
|
||||
#message(STATUS "System: ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION} ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
#message(STATUS "Compiler: ${CMAKE_Fortran_COMPILER_ID} ${CMAKE_Fortran_COMPILER_VERSION} ${CMAKE_Fortran_COMPILER}")
|
||||
#message(STATUS "Build type is: ${CMAKE_BUILD_TYPE}")
|
||||
|
||||
#===============================================================================
|
||||
# Default build type is release
|
||||
# Uncomment this to debug or use "cmake -D CMAKE_BUILD_TYPE=debug .."
|
||||
#===============================================================================
|
||||
# External projects go here i.e. a project that isn't using cmake build
|
||||
#include(ExternalProject)
|
||||
#ExternalProject_Add(PostgreSQL
|
||||
# GIT_REPOSITORY https://github.com/postgres/postgres.git
|
||||
# GIT_TAG REL_16_1
|
||||
# SOURCE_DIR ${CMAKE_SOURCE_DIR}/vendors/database/
|
||||
# CONFIGURE_COMMAND ./configure
|
||||
# CMAKE_ARGS ""
|
||||
# INSTALL_COMMAND ""
|
||||
# BUILD_IN_SOURCE 1
|
||||
# BUILD_COMMAND $(MAKE) MAKELEVEL=0
|
||||
# LOG_CONFIGURE 1
|
||||
# LOG_BUILD 1
|
||||
# LOG_INSTALL 1
|
||||
#)
|
||||
|
||||
# set(CMAKE_BUILD_TYPE debug)
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING
|
||||
"Choose build type: None Debug Release"
|
||||
FORCE)
|
||||
endif()
|
||||
|
||||
# Find PkgConfig.
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
pkg_check_modules(GTK4 REQUIRED gtk4>=4.0)
|
||||
message("GTK4 include dir: ${GTK4_INCLUDE_DIRS}")
|
||||
message("GTK4 libraries: ${GTK4_LIBRARY_DIRS}")
|
||||
message("GTK4 other Cflags: ${GTK4_CFLAGS_OTHER}")
|
||||
|
||||
pkg_check_modules(ADW REQUIRED libadwaita-1>=1.3.5)
|
||||
message("ADW include dir: ${ADW_INCLUDE_DIRS}")
|
||||
message("ADW libraries: ${ADW_LIBRARY_DIRS}")
|
||||
message("ADW other Cflags: ${ADW_CFLAGS_OTHER}")
|
||||
|
||||
#pkg_check_modules(SSL REQUIRED openssl>=3.1.2)
|
||||
#message("SSL libraries: ${SSL_LIBRARY_DIRS}")
|
||||
#pkg_check_modules(SSL REQUIRED zlib>=1.3)
|
||||
|
||||
# Make use of PostgreSQL if FOUND, else use SQLite3
|
||||
find_package (PostgreSQL)
|
||||
if (PostgreSQL_FOUND)
|
||||
message("POSTGRESQL include dir: ${PostgreSQL_INCLUDE_DIRS}")
|
||||
message("POSTGRESQL libraries: ${PostgreSQL_LIBRARIES}")
|
||||
include_directories(${PostgreSQL_INCLUDE_DIRS} ${PostgreSQL_SERVER_INCLUDE_DIRS})
|
||||
target_link_libraries (${PROJECT_NAME} PUBLIC ${PostgreSQL_LIBRARIES})
|
||||
|
||||
#pkg_check_modules(SQLite3 REQUIRED sqlite3>=3.43.1)
|
||||
elseif (SQLITE3_FOUND)
|
||||
find_package (SQLite3)
|
||||
message("SQLITE3 include dir: ${SQLITE3_INCLUDE_DIRS}")
|
||||
message("SQLITE3 libraries: ${SQLITE3_LIBRARIES}")
|
||||
include_directories(${SQLITE3_INCLUDE_DIRS})
|
||||
target_link_libraries (${PROJECT_NAME} PUBLIC ${SQLITE3_LIBRARIES})
|
||||
endif (PostgreSQL_FOUND)
|
||||
# Setup CMake to use GTK+, tell the compiler where to look for headers
|
||||
# and to the linker where to look for libraries
|
||||
include_directories(${GTK4_INCLUDE_DIRS} ${ADW_INCLUDE_DIRS})
|
||||
link_directories(${GTK4_LIBRARY_DIRS} ${ADW_LIBRARY_DIRS})
|
||||
add_definitions(${GTK4_CFLAGS_OTHER} ${ADW_CFLAGS_OTHER})
|
||||
|
||||
# Include vendor source code locally/manually
|
||||
add_subdirectory(vendors/api-server/)
|
||||
add_subdirectory(vendors/simple-reverse-proxy/)
|
||||
|
||||
# This is a "default" library, and will match the *** variable setting.
|
||||
# Other common choices are STATIC, SHARED, and MODULE
|
||||
# Including header files here helps IDEs but is not required.
|
||||
# Output libname matches target name, with the usual extensions on your system
|
||||
#add_library(MyLibExample simple_lib.cpp simple_lib.hpp)
|
||||
|
||||
# Link each target with other targets or add options, etc.
|
||||
# Make sure you link your targets with this command. It can also link libraries and
|
||||
# even flags, so linking a target that does not exist will not give a configure-time error.
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${GTK4_LIBRARIES} ${ADW_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${GTK4_LIBRARIES} ${ADW_LIBRARIES})
|
||||
|
||||
# Target Compile Options
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_LEVELS_GCC} $<$<CONFIG:DEBUG>:${WARNING_LEVELS_GCC_DEBUG}>)
|
||||
|
||||
#===============================================================================
|
||||
# Package generation:
|
||||
#===============================================================================
|
||||
#set(CPACK_PACKAGE_CHECKSUM SHA256)
|
||||
#set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
#set(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README.md")
|
||||
#set(CPACK_GENERATOR "TGZ")
|
||||
#set(CPACK_SOURCE_GENERATOR "TGZ")
|
||||
#include(CPack)
|
||||
|
||||
#===============================================================================
|
||||
# Add subdirectories to build:
|
||||
#===============================================================================
|
||||
#add_subdirectory(src)
|
||||
|
||||
# include directory for third party libraries
|
||||
include_directories(vendors/)
|
||||
|
||||
###############################################################################
|
||||
## PACKAGING ##################################################################
|
||||
###############################################################################
|
||||
|
||||
# all install commands get the same destination. this allows us to use paths
|
||||
# relative to the executable.
|
||||
#install(TARGETS example DESTINATION example_destination)
|
||||
# this is basically a repeat of the file copy instruction that copies the
|
||||
# resources in the build directory, but here we tell CMake that we want it
|
||||
# in the package
|
||||
#install(DIRECTORY resources DESTINATION example_destination)
|
||||
|
||||
#set(CPACK_PACKAGE_CHECKSUM SHA256)
|
||||
#set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
#set(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README.md")
|
||||
#set(CPACK_GENERATOR "TGZ")
|
||||
#set(CPACK_SOURCE_GENERATOR "TGZ")
|
||||
|
||||
# now comes everything we need, to create a package
|
||||
# there are a lot more variables you can set, and some
|
||||
# you need to set for some package types, but we want to
|
||||
# be minimal here
|
||||
#set(CPACK_PACKAGE_NAME "MyExample")
|
||||
#set(CPACK_PACKAGE_VERSION "1.0.0")
|
||||
|
||||
# we don't want to split our program up into several things
|
||||
#set(CPACK_MONOLITHIC_INSTALL 1)
|
||||
|
||||
# This must be last
|
||||
#include(CPack)
|
2
COPYING
2
COPYING
@ -3,7 +3,7 @@
|
||||
|
||||
# Copyright (C) SharpeTronics, Inc. - 2013-PRESENT
|
||||
|
||||
# Author(s): SharpeTronics, Inc.
|
||||
# Author(s): SharpeTronics, LLC.
|
||||
# License: GPL-3.0
|
||||
# Version: 0.0.1
|
||||
|
||||
|
89
DEV_README.md
Normal file
89
DEV_README.md
Normal file
@ -0,0 +1,89 @@
|
||||
# DEVELOPER JOURNAL
|
||||
# V1.0.0
|
||||
|
||||
# The Design Flow/Pattern of the GTK4/C Application
|
||||
|
||||
|
||||
# Cambalche Update, Configure & Meson Install Instructions:
|
||||
|
||||
So, instructions that worked for me on Arch Linux if you want to manually build/install Cambalache v0.93.
|
||||
|
||||
|
||||
0. `git clone https://gitlab.gnome.org/jpu/cambalache.git && cd cambalache`
|
||||
1. `meson setup --wipe --prefix=~/.local _build .`
|
||||
2. `ninja -C _build install`
|
||||
|
||||
3. Update `~/.bashrc paths`
|
||||
|
||||
```
|
||||
# Add paths for Cambalache app
|
||||
export PYTHONPATH=~/.local/lib/python3.12/site-packages/
|
||||
export GI_TYPELIB_PATH=~/.local/lib/girepository-1.0/
|
||||
export LD_LIBRARY_PATH=~/.local/lib/
|
||||
```
|
||||
|
||||
4. *Optional* Add `~/.local/bin` to $PATH via `~/.bashrc` profile directly
|
||||
```
|
||||
# Then, export and append .local/bin PATH to PATHS for launching Cambalache application
|
||||
export PATH=/home/username/.local/bin:$PATH
|
||||
EXIT and SAVE the .bashrc file
|
||||
```
|
||||
4a. In the terminal/CLI, refresh .bashrc profile
|
||||
`source ~/.bashrc`
|
||||
|
||||
4b. Launch Cambalache via terminal (CLI)
|
||||
`cambalache`
|
||||
|
||||
Note 1: You also may need to copy libs over from local `./_build/cambalache/private` directory to `/home/username/.local/lib`.
|
||||
|
||||
### The specific files I copied
|
||||
|
||||
* CambalachePrivate-3.0.gir
|
||||
* CambalachePrivate-3.0.typelib
|
||||
* CambalachePrivate-4.0.gir
|
||||
* CambalachePrivate-4.0.typelib
|
||||
* libcambalacheprivate-3.so.p (DIR)
|
||||
* libcambalacheprivate-4.so.p (DIR)
|
||||
|
||||
# Steps to Build *DrogonCMS* from Source Code
|
||||
|
||||
0. Clone the repository `git clone https://git.sharpetronics.com/sharpetronics/DrogonCMS` and `cd DrogonCMS/`
|
||||
1. *optional* checkout correct branch e.g. `git checkout drogonCMS-cmake`
|
||||
2. Run `cmake -D CMAKE_BUILD_TYPE=Release .`
|
||||
3. Then, to build the executable, we do `cmake --build .`
|
||||
4. Run the app with `./DrogonCMS`
|
||||
|
||||
## Developer Requirements
|
||||
|
||||
*Drogon* framework compile/build dependencies.
|
||||
* Drogon >= 1.9.1 https://github.com/drogonframework/drogon/wiki/ENG-02-Installation#System-Preparation-Examples
|
||||
|
||||
## Developer Recommendations
|
||||
|
||||
A GTK4 editor is a recommended tool for this project; all UI's and project files **.cmb** are stored in `./src/ui/`.
|
||||
* Cambalache >= 0.93 https://gitlab.gnome.org/jpu/cambalache
|
||||
|
||||
An optional recommendation is Geany IDE.
|
||||
* Geany IDE https://www.geany.org/
|
||||
|
||||
## IDE build commands via Geany `Build -> Set Build Commands`
|
||||
|
||||
### This is what my build commands look like in *Geany IDE* with **GNU Automake Tools**.
|
||||
|
||||
| Name | Command | Working Directory |
|
||||
| ----------- | ------------------ | -------------------------------------------------------------------- |
|
||||
| Configure | ../configure | /home/username/Desktop/Local-Development/cplusplus/drogon-dash/build |
|
||||
| AutoReconf | autoreconf -vi | /home/username/Desktop/Local-Development/cplusplus/drogon-dash |
|
||||
| Make | make | /home/username/Desktop/Local-Development/cplusplus/drogon-dash/build |
|
||||
| Run | ./drogon_dashboard | /home/username/Desktop/Local-Development/cplusplus/drogon-dash/build |
|
||||
| Make Bins | make dist | /home/username/Desktop/Local-Development/cplusplus/drogon-dash/build |
|
||||
|
||||
### This is what my build commands look like in Geany IDE with **BSD CMake Tools**.
|
||||
|
||||
| Name | Command | Working Directory |
|
||||
| ----------- | ------------------ | -------------------------------------------------------------------- |
|
||||
| Configure | cmake -D CMAKE_BUILD_TYPE=Release | /home/username/Desktop/Local-Development/cplusplus/DrogonCMS/ |
|
||||
| Build | cmake --build . | /home/username/Desktop/Local-Development/cplusplus/DrogonCMS |
|
||||
| Run GUI | ./DrogonCMS | /home/username/Desktop/Local-Development/cplusplus/DrogonCMS/ |
|
||||
| Run API | ./DrogonCMS-API-Server | /home/username/Desktop/Local-Development/cplusplus/DrogonCMS/vendors/api-server/ |
|
||||
| Install | cmake --install | /home/username/Desktop/Local-Development/cplusplus/DrogonCMS/ |
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
# Copyright (C) SharpeTronics, Inc. 2013-PRESENT
|
||||
|
||||
# Author(s): SharpeTronics, Inc.
|
||||
# Author(s): SharpeTronics, LLC.
|
||||
# License: GPL-3.0
|
||||
|
||||
# This is Free Software released under GPL-3.0. Any misuse of this software
|
||||
|
16
Makefile.am
16
Makefile.am
@ -1,16 +0,0 @@
|
||||
# TODO: organize files more
|
||||
|
||||
# reduce warnings/errors for subdirectory objects
|
||||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
|
||||
# the name of the binary file
|
||||
bin_PROGRAMS = drogon_dashboard
|
||||
|
||||
# Uses shell pkg-config CLI to find and include required libs
|
||||
AM_CFLAGS = $(shell pkg-config --cflags gtk4)
|
||||
LIBS = $(shell pkg-config --libs libadwaita-1 gtk4)
|
||||
|
||||
# various *.cpp and *.hpp files for the root project; the '\' implies a *newline*
|
||||
drogon_dashboard_SOURCES = \
|
||||
src/base.c
|
||||
|
138
README.md
138
README.md
@ -1,42 +1,113 @@
|
||||
## A Drogon Dashboard built with C, Drogon, GNU Autotools, Adwaita and Gtk4.
|
||||
This software creates a local/remote Drogon content management system (CMS) application.
|
||||
## A Drogon CMS built with C, Drogon, CMake, Adwaita and GTK4.
|
||||
This is a Drogon Content Management System(CMS).
|
||||
|
||||
### License
|
||||
* GPL-3.0
|
||||
|
||||
### Developer Environment Requirements
|
||||
* GCC (GNU C/C++ Compiler) 13.2.1
|
||||
* GNU Autotools
|
||||
* GNU Make 4.4.1
|
||||
* Pkg-Config 1.8.1
|
||||
* Gtk4 >= 4.0
|
||||
* Adwaita >= 1.3.5
|
||||
* *Optional* Cambalache >= 0.14 (Gtk4 Editor) [SEE REQUIREMENTS]
|
||||
* *Optional* Geany IDE
|
||||
* Basic CLI Experience
|
||||
## Prominent Features and Strengths
|
||||
- Faster than NginX, WordPress and Strapi
|
||||
- Built on CMake/C/C++/GTK4/Drogon
|
||||
- Built on Freedom Software
|
||||
- Lightning Fast Architecture
|
||||
- Headless CMS Ready for Site Generators
|
||||
- Lightweight Reverse Proxy Security
|
||||
- Database Ready for SQLite3 & PostgreSQL 15
|
||||
- Custom API Configurations
|
||||
- C Package Manager (CPM)
|
||||
- Excellent Documentation
|
||||
|
||||
### Steps to build the Drogon Dashboard Application
|
||||
## Community Plugins
|
||||
- Proxy/Local Caching Support
|
||||
- Website Builder
|
||||
- Website Preview/Drafts
|
||||
- WYSIWYG Editor
|
||||
- Image Gallery
|
||||
- ...
|
||||
|
||||
1. Run `autoreconf -vi`. **Tip:** Run this command each time you modify configure.ac
|
||||
2. Create a `build` directory and auto configure the app `cd build && ../configure`.
|
||||
3. Compile the app with `make`. **Tip:** Be certain you are in the **build** directory
|
||||
4. Run the app with `./drogon_dashboard`.
|
||||
5. *Optional:* Install the app to core system `make install`. **Tip:** Root permissions may be needed depending on where you --prefix the install directory
|
||||
6. *Optional:* `make dist` creates and packages the binaries for **distribution**.
|
||||
## Benchmarks
|
||||
|
||||
### A NodeJs Server Test on 2 IO threads
|
||||
```
|
||||
wrk -c200 -d5 -t2 http://localhost:3000
|
||||
Running 5s test @ http://localhost:3000
|
||||
2 threads and 200 connections
|
||||
Thread Stats Avg Stdev Max +/- Stdev
|
||||
Latency 51.58ms 159.51ms 1.43s 93.61%
|
||||
Req/Sec 7.56k 1.00k 8.24k 94.00%
|
||||
75277 requests in 5.01s, 11.56MB read
|
||||
Requests/sec: 15033.66
|
||||
Transfer/sec: 2.31MB
|
||||
```
|
||||
|
||||
### A drogon server with web sockets and drogon proxy on 2 IO threads
|
||||
```
|
||||
wrk -c200 -d5 -t2 ws://localhost:8088/
|
||||
Running 5s test @ ws://localhost:8088/
|
||||
2 threads and 200 connections
|
||||
Thread Stats Avg Stdev Max +/- Stdev
|
||||
Latency 2.67ms 6.11ms 47.94ms 94.97%
|
||||
Req/Sec 57.95k 4.90k 69.61k 74.00%
|
||||
576699 requests in 5.01s, 394.34MB read
|
||||
Non-2xx or 3xx responses: 576699
|
||||
Requests/sec: 115151.94
|
||||
Transfer/sec: 78.74MB
|
||||
```
|
||||
|
||||
### Getting a JSON token with web sockets and Drogon proxy on 2 IO threads.
|
||||
```
|
||||
wrk -c200 -d5 -t2 ws://localhost:8088/get-token
|
||||
Running 5s test @ ws://localhost:8088/get-token
|
||||
2 threads and 200 connections
|
||||
Thread Stats Avg Stdev Max +/- Stdev
|
||||
Latency 1.91ms 402.84us 4.23ms 69.21%
|
||||
Req/Sec 50.74k 3.58k 56.43k 61.00%
|
||||
504657 requests in 5.01s, 106.36MB read
|
||||
Requests/sec: 100798.10
|
||||
Transfer/sec: 21.24MB
|
||||
```
|
||||
|
||||
## Development & Contributing
|
||||
|
||||
### Developer Dependency Requirements
|
||||
* GCC (GNU C/C++ Compiler) >= 13.2.1
|
||||
* PostgreSQL >= 15.1(*Priority*) or SQLite3(*Default*) >= 3.43.1 [SEE 3RD PARTY SITE DEPENDENCIES]
|
||||
* CMake >= 3.28
|
||||
* Drogon >= 1.9.1 [SEE 3RD PARTY SITE DEPENDENCIES]
|
||||
* Pkg-Config >= 1.8.1
|
||||
* Gtk4 >= 4.0
|
||||
* Adwaita >= 1.3.5
|
||||
* OpenSSL >= 3.1.2
|
||||
* *Optional* Cambalache >= 0.93 (Gtk4 Editor) [SEE 3RD PARTY SITE DEPENDENCIES]
|
||||
* *Optional* Geany IDE >= 1.38
|
||||
* CLI Experience
|
||||
* Git/Github Experience
|
||||
|
||||
*Note: This has been built and tested on Arch Linux*
|
||||
|
||||
### Steps to Build *DrogonCMS* from Source Code
|
||||
|
||||
0. Clone the repository `git clone https://git.sharpetronics.com/sharpetronics/DrogonCMS` and `cd DrogonCMS/`
|
||||
1. *optional* checkout correct branch e.g. `git checkout drogonCMS-cmake`
|
||||
2. Run `cmake -D CMAKE_BUILD_TYPE=Release .`
|
||||
3. Then, to build the executable, we do `cmake --build .`
|
||||
4. Run the app with `./DrogonCMS`
|
||||
|
||||
### Requirements
|
||||
|
||||
*Drogon* framework compile/build dependencies.
|
||||
* Drogon >= 1.9.1 https://github.com/drogonframework/drogon/wiki/ENG-02-Installation#System-Preparation-Examples
|
||||
|
||||
### Recommendations
|
||||
|
||||
A GTK4 editor is a recommended tool for this project; all UI's and project files **.cmb** are stored in `./src/ui/`.
|
||||
* Cambalache >= 0.14 https://gitlab.gnome.org/jpu/cambalache
|
||||
* Cambalache >= 0.93 https://gitlab.gnome.org/jpu/cambalache
|
||||
|
||||
An optional recommendation is Geany IDE.
|
||||
* Geany IDE https://www.geany.org/
|
||||
|
||||
### Note: Update your build commands via `Build -> Set Build Commands`.
|
||||
### IDE build commands via Geany `Build -> Set Build Commands`
|
||||
|
||||
This is what my build commands look like in Geany IDE.
|
||||
#### This is what my build commands look like in *Geany IDE* with **GNU Automake Tools**.
|
||||
|
||||
| Name | Command | Working Directory |
|
||||
| ----------- | ------------------ | -------------------------------------------------------------------- |
|
||||
@ -46,14 +117,24 @@ This is what my build commands look like in Geany IDE.
|
||||
| Run | ./drogon_dashboard | /home/username/Desktop/Local-Development/cplusplus/drogon-dash/build |
|
||||
| Make Bins | make dist | /home/username/Desktop/Local-Development/cplusplus/drogon-dash/build |
|
||||
|
||||
#### This is what my build commands look like in Geany IDE with **BSD CMake Tools**.
|
||||
|
||||
| Name | Command | Working Directory |
|
||||
| ----------- | ------------------ | -------------------------------------------------------------------- |
|
||||
| Configure | cmake -D CMAKE_BUILD_TYPE=Release | /home/username/Desktop/Local-Development/cplusplus/DrogonCMS/ |
|
||||
| Build | cmake --build . | /home/username/Desktop/Local-Development/cplusplus/DrogonCMS |
|
||||
| Run GUI | ./DrogonCMS | /home/username/Desktop/Local-Development/cplusplus/DrogonCMS/ |
|
||||
| Run API | ./DrogonCMS-API-Server | /home/username/Desktop/Local-Development/cplusplus/DrogonCMS/vendors/api-server/ |
|
||||
| Install | cmake --install | /home/username/Desktop/Local-Development/cplusplus/DrogonCMS/ |
|
||||
|
||||
## Authors
|
||||
|
||||
* SharpeTronics, Inc.
|
||||
* oDinZu WenKi
|
||||
* SharpeTronics, LLC
|
||||
* oDinZu WenKi(Charles)
|
||||
|
||||
## Financial Support & Donations
|
||||
|
||||
oDinZu WenKi https://liberapay.com/oDinZu/
|
||||
oDinZu WenKi(Charles) https://liberapay.com/oDinZu/
|
||||
|
||||
* Liberapay is a recurrent donations platform
|
||||
* Run by a non-profit organization
|
||||
@ -65,6 +146,8 @@ oDinZu WenKi https://liberapay.com/oDinZu/
|
||||
* Adawaita Documentation https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/index.html
|
||||
* Cambalache https://gitlab.gnome.org/jpu/cambalache
|
||||
* C References https://en.cppreference.com/w/c
|
||||
* CMake Documentation https://cmake.org/cmake/help/book/mastering-cmake/index.html
|
||||
* CPM Make Github https://github.com/cpm-cmake/CPM.cmake#snippets
|
||||
* Drogon Web Server https://github.com/drogonframework/drogon
|
||||
* Geany IDE https://www.geany.org/
|
||||
* Gio Documentation https://docs.gtk.org/gio/index.html
|
||||
@ -72,6 +155,7 @@ oDinZu WenKi https://liberapay.com/oDinZu/
|
||||
* GObject Documentation https://docs.gtk.org/gobject/index.html
|
||||
* GTK 4 Demos https://gitlab.gnome.org/GNOME/gtk/-/tree/main/demos
|
||||
* GTK 4 Documentation https://docs.gtk.org/gtk4/
|
||||
* GNU Autotools Documentation https://www.gnu.org/software/automake/manual/automake.html#Autotools-Introduction
|
||||
* PostgreSQL 15 Documentation https://www.postgresql.org/docs/15/index.html
|
||||
* SQLite3 Documentation https://www.sqlite.org/capi3ref.html
|
||||
|
||||
Notice: We focus implementation with the C programming language and only add various features of C ++ code.
|
||||
*Notice: We focus implementation with the C programming language and only add various features of C ++ code.*
|
||||
|
33
configure.ac
33
configure.ac
@ -1,33 +0,0 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.71])
|
||||
AC_INIT([drogon_dashboard], [0.0.1], [odinzu@sharpetronics.com])
|
||||
|
||||
# When a package contains more than a few tests that define C preprocessor symbols, the command lines to pass -D options to the compiler can get quite long.
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_SRCDIR([src/base.c])
|
||||
|
||||
# Organize root project build-aux files
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
||||
# USED by automake to work with autoconf; Enables all warnings, plus foreign disables warnings/errors for mandatory files like README.md
|
||||
AM_INIT_AUTOMAKE([-Wall -Wdeprecated-declarations foreign])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
|
||||
# Checks for libraries.
|
||||
|
||||
# Checks for header files.
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
|
||||
# Checks for library functions.
|
||||
|
||||
# Checks for all the given modules, setting a variety of result variables in the calling scope.
|
||||
PKG_CHECK_MODULES([GTK4], [gtk4 >= 4.0])
|
||||
PKG_CHECK_MODULES([ADWAITA], [libadwaita-1 >= 1.3.5])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
3
cpm-package-lock.cmake
Normal file
3
cpm-package-lock.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
# CPM Package Lock
|
||||
# This file should be committed to version control
|
||||
|
205
src/base.c
205
src/base.c
@ -1,16 +1,15 @@
|
||||
/*
|
||||
# This software creates a local/remote Drogon content management system (CMS) application with Gtk-4.0 GUI and the Drogon framework.
|
||||
# A Drogon Dashboard built with C, Drogon, GNU Autotools, Adwaita and Gtk4.
|
||||
# A Drogon CMS built with C, Drogon, GNU Autotools, Adwaita and Gtk4.
|
||||
#
|
||||
# Copyright (C) SharpeTronics, Inc. - 2013-PRESENT
|
||||
# Copyright (C) SharpeTronics, LLC. - 2013-PRESENT
|
||||
#
|
||||
# Author(s): SharpeTronics, Inc.
|
||||
# Author(s): SharpeTronics, LLC.
|
||||
# oDinZu WenKi
|
||||
#
|
||||
# License: GPL-3.0
|
||||
# Version: 0.0.1
|
||||
|
||||
|
||||
# This is Free Software released under GPL-3.0. Any misuse of this software
|
||||
# will be followed up with GPL enforcement via Software Freedom Law Center:
|
||||
# https://www.softwarefreedom.org/
|
||||
@ -33,35 +32,183 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/*
|
||||
Functions
|
||||
*/
|
||||
|
||||
/* Launch the application from activate */
|
||||
static void
|
||||
activate (GtkApplication *app,
|
||||
gpointer user_data)
|
||||
quit_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
/* Construct a GtkBuilder instance */
|
||||
GtkBuilder *builder = gtk_builder_new();
|
||||
|
||||
/* Loads the UI objects */
|
||||
gtk_builder_add_from_file(builder, "../src/ui/admin-register.ui", NULL);
|
||||
GtkWidget *window = user_data;
|
||||
|
||||
/* Register the ID of gtk_object from admin-register.ui */
|
||||
GObject *window = gtk_builder_get_object(builder, "register_window");
|
||||
|
||||
/* Connect the actions of XML UI objects's with Gtk Signals */
|
||||
|
||||
|
||||
/* Sets the app window with *app GtkApplication */
|
||||
gtk_window_set_application(GTK_WINDOW(window), app);
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
/* Display the Gtk GUI */
|
||||
gtk_widget_set_visible(window, TRUE);
|
||||
static void
|
||||
about_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *window = user_data;
|
||||
GtkWidget *about_dlg;
|
||||
|
||||
about_dlg = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "about"));
|
||||
gtk_window_present (GTK_WINDOW (about_dlg));
|
||||
}
|
||||
|
||||
static void
|
||||
remove_timeout (gpointer data)
|
||||
{
|
||||
guint id = GPOINTER_TO_UINT (data);
|
||||
|
||||
g_source_remove (id);
|
||||
}
|
||||
|
||||
static int
|
||||
pop_message (gpointer data)
|
||||
{
|
||||
GtkWidget *status = data;
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (status), "");
|
||||
g_object_set_data (G_OBJECT (status), "timeout", GUINT_TO_POINTER (0));
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
status_message (GtkWidget *status,
|
||||
const char *text)
|
||||
{
|
||||
guint id;
|
||||
|
||||
id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (status), "timeout"));
|
||||
if (id)
|
||||
g_source_remove (id);
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (status), text);
|
||||
|
||||
id = g_timeout_add (5000, pop_message, status);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (status), "timeout", GUINT_TO_POINTER (id), remove_timeout);
|
||||
}
|
||||
|
||||
static void
|
||||
help_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *status;
|
||||
|
||||
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
|
||||
status_message (status, "Help not available");
|
||||
}
|
||||
|
||||
static void
|
||||
not_implemented (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *status;
|
||||
char *text;
|
||||
|
||||
text = g_strdup_printf ("Action “%s” not implemented", g_action_get_name (G_ACTION (action)));
|
||||
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
|
||||
status_message (status, text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static GActionEntry win_entries[] = {
|
||||
{ "new", not_implemented, NULL, NULL, NULL },
|
||||
{ "open", not_implemented, NULL, NULL, NULL },
|
||||
{ "save", not_implemented, NULL, NULL, NULL },
|
||||
{ "save-as", not_implemented, NULL, NULL, NULL },
|
||||
{ "copy", not_implemented, NULL, NULL, NULL },
|
||||
{ "cut", not_implemented, NULL, NULL, NULL },
|
||||
{ "paste", not_implemented, NULL, NULL, NULL },
|
||||
{ "quit", quit_activate, NULL, NULL, NULL },
|
||||
{ "about", about_activate, NULL, NULL, NULL },
|
||||
{ "help", help_activate, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
activate(GtkApplication *app)
|
||||
{
|
||||
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
GActionGroup *actions;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *about;
|
||||
GtkWidget *status;
|
||||
GtkEventController *controller;
|
||||
|
||||
/* Construct a GtkBuilder instance */
|
||||
GtkBuilder *builder = gtk_builder_new();
|
||||
|
||||
/* Loads the UI objects */
|
||||
gtk_builder_add_from_file(builder, "src/ui/admin-register.ui", NULL);
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_application (GTK_WINDOW (window),app);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
actions = (GActionGroup*)g_simple_action_group_new ();
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions),
|
||||
win_entries, G_N_ELEMENTS (win_entries),
|
||||
window);
|
||||
gtk_widget_insert_action_group (window, "win", actions);
|
||||
|
||||
controller = gtk_shortcut_controller_new ();
|
||||
gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
GTK_SHORTCUT_SCOPE_GLOBAL);
|
||||
gtk_widget_add_controller (window, controller);
|
||||
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_n, GDK_CONTROL_MASK),
|
||||
gtk_named_action_new ("win.new")));
|
||||
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_o, GDK_CONTROL_MASK),
|
||||
gtk_named_action_new ("win.open")));
|
||||
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_s, GDK_CONTROL_MASK),
|
||||
gtk_named_action_new ("win.save")));
|
||||
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_s, GDK_CONTROL_MASK|GDK_SHIFT_MASK),
|
||||
gtk_named_action_new ("win.save-as")));
|
||||
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_q, GDK_CONTROL_MASK),
|
||||
gtk_named_action_new ("win.quit")));
|
||||
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_c, GDK_CONTROL_MASK),
|
||||
gtk_named_action_new ("win.copy")));
|
||||
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_x, GDK_CONTROL_MASK),
|
||||
gtk_named_action_new ("win.cut")));
|
||||
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_v, GDK_CONTROL_MASK),
|
||||
gtk_named_action_new ("win.paste")));
|
||||
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_F1, 0),
|
||||
gtk_named_action_new ("win.help")));
|
||||
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_F7, 0),
|
||||
gtk_named_action_new ("win.about")));
|
||||
|
||||
about = GTK_WIDGET (gtk_builder_get_object (builder, "aboutdialog1"));
|
||||
gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (window));
|
||||
gtk_window_set_hide_on_close (GTK_WINDOW (about), TRUE);
|
||||
g_object_set_data_full (G_OBJECT (window), "about",
|
||||
about, (GDestroyNotify)gtk_window_destroy);
|
||||
|
||||
status = GTK_WIDGET (gtk_builder_get_object (builder, "statusbar1"));
|
||||
g_object_set_data (G_OBJECT (window), "status", status);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_set_visible (window, TRUE);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
/* Dereference and free computer memory */
|
||||
g_object_unref(builder);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -72,7 +219,7 @@ main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
/* Create an instance of a Gtk application */
|
||||
GtkApplication *app = gtk_application_new("org.gtk.drogondashboard", G_APPLICATION_DEFAULT_FLAGS);
|
||||
GtkApplication *app = gtk_application_new("org.gtk.drogoncms", G_APPLICATION_DEFAULT_FLAGS);
|
||||
|
||||
/* Signal the "activate" function */
|
||||
g_signal_connect(app, "activate", G_CALLBACK (activate), NULL);
|
||||
|
@ -1,63 +0,0 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "drogondashboardapplication.h"
|
||||
#include "drogondashboardwindow.h"
|
||||
|
||||
struct _DrogonDashboardApp
|
||||
{
|
||||
GtkApplication parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(DrogonDashboardApp, drogondashboard_app, GTK_TYPE_APPLICATION);
|
||||
|
||||
static void
|
||||
drogondashboard_app_init (DrogonDashboardApp *app)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
drogondashboard_app_activate (GApplication *app)
|
||||
{
|
||||
DrogonDashboardAppWindow *win;
|
||||
|
||||
win = drogondashboard_app_window_new (DROGONDASHBOARD_APP (app));
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
|
||||
static void
|
||||
drogondashboard_app_open (GApplication *app,
|
||||
GFile **files,
|
||||
int n_files,
|
||||
const char *hint)
|
||||
{
|
||||
GList *windows;
|
||||
DrogonDashboardAppWindow *win;
|
||||
int i;
|
||||
|
||||
windows = gtk_application_get_windows (GTK_APPLICATION (app));
|
||||
if (windows)
|
||||
win = DROGONDASHBOARD_APP_WINDOW (windows->data);
|
||||
else
|
||||
win = drogondashboard_app_window_new (DROGONDASHBOARD_APP (app));
|
||||
|
||||
for (i = 0; i < n_files; i++)
|
||||
drogondashboard_app_window_open (win, files[i]);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
|
||||
static void
|
||||
drogondashboard_app_class_init (DrogonDashboardAppClass *class)
|
||||
{
|
||||
G_APPLICATION_CLASS (class)->activate = drogondashboard_app_activate;
|
||||
G_APPLICATION_CLASS (class)->open = drogondashboard_app_open;
|
||||
}
|
||||
|
||||
DrogonDashboardApp *
|
||||
drogondashboard_app_new (void)
|
||||
{
|
||||
return g_object_new (DROGONDASHBOARD_APP_TYPE,
|
||||
"application-id", "org.gtk.exampleapp",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#ifndef __DROGONDASHBOARDAPP_H
|
||||
#define __DROGONDASHBOARDAPP_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define DROGONDASHBOARD_APP_TYPE (drogondashboard_app_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DrogonDashboardApp, drogondashboard_app, DROGONDASHBOARD, APP, GtkApplication)
|
||||
|
||||
DrogonDashboardApp *drogondashboard_app_new (void);
|
||||
|
||||
|
||||
#endif /* __DROGONDASHBOARDAPP_H */
|
@ -1,46 +0,0 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "drogondashboardapplication.h"
|
||||
#include "drogondashboardwindow.h"
|
||||
|
||||
struct _DrogonDashboardAppWindow
|
||||
{
|
||||
GtkApplicationWindow parent;
|
||||
|
||||
//GtkWidget *stack;
|
||||
|
||||
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(DrogonDashboardAppWindow, drogondashboard_app_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||
|
||||
static void
|
||||
drogondashboard_app_window_init (DrogonDashboardAppWindow *win)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *window;
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (win));
|
||||
builder = gtk_builder_new_from_file("../src/ui/admin-register.ui");
|
||||
//menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
|
||||
window = GTK_WIDGET(gtk_builder_get_object(builder, "registerWindow"));
|
||||
//gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (win->gears), menu);
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
static void
|
||||
drogondashboard_app_window_class_init (DrogonDashboardAppWindowClass *class)
|
||||
{
|
||||
}
|
||||
|
||||
DrogonDashboardAppWindow *
|
||||
drogondashboard_app_window_new (DrogonDashboardApp *app)
|
||||
{
|
||||
return g_object_new (DROGONDASHBOARD_APP_WINDOW_TYPE, "application", app, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
drogondashboard_app_window_open (DrogonDashboardAppWindow *win,
|
||||
GFile *file)
|
||||
{
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#ifndef __DROGONDASHBOARDAPPWIN_H
|
||||
#define __DROGONDASHBOARDAPPWIN_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "drogondashboardapplication.h"
|
||||
|
||||
|
||||
#define DROGONDASHBOARD_APP_WINDOW_TYPE (drogondashboard_app_window_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DrogonDashboardAppWindow, drogondashboard_app_window, DROGONDASHBOARD, APP_WINDOW, GtkApplicationWindow)
|
||||
|
||||
|
||||
DrogonDashboardAppWindow *drogondashboard_app_window_new (DrogonDashboardApp *app);
|
||||
void drogondashboard_app_window_open (DrogonDashboardAppWindow *win,
|
||||
GFile *file);
|
||||
|
||||
|
||||
#endif /* __DROGONDASHBOARDAPPWIN_H */
|
155
src/ui/DrogonCMS.cmb
Normal file
155
src/ui/DrogonCMS.cmb
Normal file
@ -0,0 +1,155 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
|
||||
<cambalache-project version="0.93.0" target_tk="gtk-4.0">
|
||||
<ui>
|
||||
(2,None,"admin-register.ui","admin-register.ui",None,None,None,None,None,None,None)
|
||||
</ui>
|
||||
<object>
|
||||
(2,1,"GtkListStore","liststore1",None,None,None,None,0,None,None),
|
||||
(2,2,"(menu)","menubar",None,None,None,None,1,None,None),
|
||||
(2,3,"(submenu)",None,2,None,None,None,0,None,None),
|
||||
(2,4,"(section)",None,3,None,None,None,0,None,None),
|
||||
(2,5,"(item)",None,4,None,None,None,0,None,None),
|
||||
(2,6,"(item)",None,4,None,None,None,1,None,None),
|
||||
(2,7,"(item)",None,4,None,None,None,2,None,None),
|
||||
(2,8,"(item)",None,4,None,None,None,3,None,None),
|
||||
(2,9,"(section)",None,3,None,None,None,1,None,None),
|
||||
(2,10,"(item)",None,9,None,None,None,0,None,None),
|
||||
(2,11,"(submenu)",None,2,None,None,None,1,None,None),
|
||||
(2,12,"(section)",None,11,None,None,None,0,None,None),
|
||||
(2,13,"(item)",None,12,None,None,None,0,None,None),
|
||||
(2,14,"(item)",None,12,None,None,None,1,None,None),
|
||||
(2,15,"(item)",None,12,None,None,None,2,None,None),
|
||||
(2,16,"(submenu)",None,2,None,None,None,2,None,None),
|
||||
(2,17,"(section)",None,16,None,None,None,0,None,None),
|
||||
(2,18,"(item)",None,17,None,None,None,0,None,None),
|
||||
(2,19,"(item)",None,17,None,None,None,1,None,None),
|
||||
(2,20,"GtkAboutDialog","aboutdialog1",None,None,None,None,2,None,None),
|
||||
(2,21,"GtkWindow","window1",None,None,None,None,3,None,None),
|
||||
(2,22,"GtkBox","vbox1",21,None,None,None,0,None,None),
|
||||
(2,23,"GtkPopoverMenuBar","menubar1",22,None,None,None,0,None,None),
|
||||
(2,24,"GtkBox","toolbar1",22,None,None,None,1,None,None),
|
||||
(2,25,"GtkButton",None,24,None,None,None,0,None,None),
|
||||
(2,26,"GtkButton",None,24,None,None,None,1,None,None),
|
||||
(2,27,"GtkButton",None,24,None,None,None,2,None,None),
|
||||
(2,28,"GtkSeparator",None,24,None,None,None,3,None,None),
|
||||
(2,29,"GtkButton",None,24,None,None,None,4,None,None),
|
||||
(2,30,"GtkButton",None,24,None,None,None,5,None,None),
|
||||
(2,31,"GtkButton",None,24,None,None,None,6,None,None),
|
||||
(2,32,"GtkScrolledWindow","scrolledwindow1",22,None,None,None,2,None,None),
|
||||
(2,33,"GtkTreeView","treeview1",32,None,None,None,0,None,None),
|
||||
(2,34,"GtkTreeViewColumn","column1",33,None,None,None,0,None,None),
|
||||
(2,35,"GtkCellRendererText","renderer1",34,None,None,None,0,None,"<attributes><attribute name=\"text\">0</attribute></attributes>"),
|
||||
(2,36,"GtkTreeViewColumn","column2",33,None,None,None,1,None,None),
|
||||
(2,37,"GtkCellRendererText","renderer2",36,None,None,None,0,None,"<attributes><attribute name=\"text\">1</attribute></attributes>"),
|
||||
(2,38,"GtkTreeViewColumn","column3",33,None,None,None,2,None,None),
|
||||
(2,39,"GtkCellRendererText","renderer3",38,None,None,None,0,None,"<attributes><attribute name=\"text\">2</attribute></attributes>"),
|
||||
(2,40,"GtkLabel","statusbar1",22,None,None,None,3,None,None)
|
||||
</object>
|
||||
<object_property>
|
||||
(2,3,"(submenu)","label","_File",1,None,None,None,None,None,None,None,None),
|
||||
(2,5,"(item)","action","win.new",0,None,None,None,None,None,None,None,None),
|
||||
(2,5,"(item)","label","_New",1,None,None,None,None,None,None,None,None),
|
||||
(2,6,"(item)","action","win.open",0,None,None,None,None,None,None,None,None),
|
||||
(2,6,"(item)","label","_Open",1,None,None,None,None,None,None,None,None),
|
||||
(2,7,"(item)","action","win.save",0,None,None,None,None,None,None,None,None),
|
||||
(2,7,"(item)","label","_Save",1,None,None,None,None,None,None,None,None),
|
||||
(2,8,"(item)","action","win.save-as",0,None,None,None,None,None,None,None,None),
|
||||
(2,8,"(item)","label","Save _As",1,None,None,None,None,None,None,None,None),
|
||||
(2,10,"(item)","action","win.quit",0,None,None,None,None,None,None,None,None),
|
||||
(2,10,"(item)","label","_Quit",1,None,None,None,None,None,None,None,None),
|
||||
(2,11,"(submenu)","label","_Edit",1,None,None,None,None,None,None,None,None),
|
||||
(2,13,"(item)","action","win.copy",0,None,None,None,None,None,None,None,None),
|
||||
(2,13,"(item)","label","_Copy",1,None,None,None,None,None,None,None,None),
|
||||
(2,14,"(item)","action","win.cut",0,None,None,None,None,None,None,None,None),
|
||||
(2,14,"(item)","label","_Cut",1,None,None,None,None,None,None,None,None),
|
||||
(2,15,"(item)","action","win.paste",0,None,None,None,None,None,None,None,None),
|
||||
(2,15,"(item)","label","_Paste",1,None,None,None,None,None,None,None,None),
|
||||
(2,16,"(submenu)","label","_Help",1,None,None,None,None,None,None,None,None),
|
||||
(2,18,"(item)","action","win.help",0,None,None,None,None,None,None,None,None),
|
||||
(2,18,"(item)","label","_Help",1,None,None,None,None,None,None,None,None),
|
||||
(2,19,"(item)","action","win.about",0,None,None,None,None,None,None,None,None),
|
||||
(2,19,"(item)","label","_About",1,None,None,None,None,None,None,None,None),
|
||||
(2,20,"GtkAboutDialog","logo-icon-name","org.gtk.Demo4",1,None,None,None,None,None,None,None,None),
|
||||
(2,20,"GtkAboutDialog","program-name","Builder demo",1,None,None,None,None,None,None,None,None),
|
||||
(2,20,"GtkWindow","modal","True",0,None,None,None,None,None,None,None,None),
|
||||
(2,21,"GtkWindow","default-height","250",0,None,None,None,None,None,None,None,None),
|
||||
(2,21,"GtkWindow","default-width","440",0,None,None,None,None,None,None,None,None),
|
||||
(2,21,"GtkWindow","title","Builder",1,None,None,None,None,None,None,None,None),
|
||||
(2,22,"GtkOrientable","orientation","vertical",0,None,None,None,None,None,None,None,None),
|
||||
(2,23,"CmbAccessibleProperty","cmb-a11y-property-label","Main Menu",0,None,None,None,None,None,None,None,None),
|
||||
(2,23,"GtkPopoverMenuBar","menu-model","2",0,None,None,None,None,None,None,None,None),
|
||||
(2,24,"CmbAccessibleProperty","cmb-a11y-property-label","Toolbar",0,None,None,None,None,None,None,None,None),
|
||||
(2,24,"GtkAccessible","accessible-role","toolbar",0,None,None,None,None,None,None,None,None),
|
||||
(2,24,"GtkWidget","css-classes","toolbar",0,None,None,None,None,None,None,None,None),
|
||||
(2,25,"GtkActionable","action-name","win.new",0,None,None,None,None,None,None,None,None),
|
||||
(2,25,"GtkButton","icon-name","document-new",0,None,None,None,None,None,None,None,None),
|
||||
(2,25,"GtkButton","label","New",1,None,None,None,None,None,None,None,None),
|
||||
(2,25,"GtkWidget","tooltip-text","Create a new file",1,None,None,None,None,None,None,None,None),
|
||||
(2,26,"GtkActionable","action-name","win.open",0,None,None,None,None,None,None,None,None),
|
||||
(2,26,"GtkButton","icon-name","document-open",0,None,None,None,None,None,None,None,None),
|
||||
(2,26,"GtkButton","label","Open",1,None,None,None,None,None,None,None,None),
|
||||
(2,26,"GtkWidget","tooltip-text","Open a file",1,None,None,None,None,None,None,None,None),
|
||||
(2,27,"GtkActionable","action-name","win.save",0,None,None,None,None,None,None,None,None),
|
||||
(2,27,"GtkButton","icon-name","document-save",0,None,None,None,None,None,None,None,None),
|
||||
(2,27,"GtkButton","label","Save",1,None,None,None,None,None,None,None,None),
|
||||
(2,27,"GtkWidget","tooltip-text","Save a file",1,None,None,None,None,None,None,None,None),
|
||||
(2,29,"GtkActionable","action-name","win.copy",0,None,None,None,None,None,None,None,None),
|
||||
(2,29,"GtkButton","icon-name","edit-copy",0,None,None,None,None,None,None,None,None),
|
||||
(2,29,"GtkButton","label","Copy",1,None,None,None,None,None,None,None,None),
|
||||
(2,29,"GtkWidget","tooltip-text","Copy selected object into the clipboard",1,None,None,None,None,None,None,None,None),
|
||||
(2,30,"GtkActionable","action-name","win.cut",0,None,None,None,None,None,None,None,None),
|
||||
(2,30,"GtkButton","icon-name","edit-cut",0,None,None,None,None,None,None,None,None),
|
||||
(2,30,"GtkButton","label","Cut",1,None,None,None,None,None,None,None,None),
|
||||
(2,30,"GtkWidget","tooltip-text","Cut selected object into the clipboard",1,None,None,None,None,None,None,None,None),
|
||||
(2,31,"GtkActionable","action-name","win.paste",0,None,None,None,None,None,None,None,None),
|
||||
(2,31,"GtkButton","icon-name","edit-paste",0,None,None,None,None,None,None,None,None),
|
||||
(2,31,"GtkButton","label","Paste",1,None,None,None,None,None,None,None,None),
|
||||
(2,31,"GtkWidget","tooltip-text","Paste object from the clipboard",1,None,None,None,None,None,None,None,None),
|
||||
(2,32,"GtkScrolledWindow","has-frame","1",0,None,None,None,None,None,None,None,None),
|
||||
(2,32,"GtkWidget","hexpand","1",0,None,None,None,None,None,None,None,None),
|
||||
(2,32,"GtkWidget","vexpand","1",0,None,None,None,None,None,None,None,None),
|
||||
(2,33,"GtkTreeView","model","1",0,None,None,None,None,None,None,None,None),
|
||||
(2,33,"GtkTreeView","tooltip-column","3",0,None,None,None,None,None,None,None,None),
|
||||
(2,34,"GtkTreeViewColumn","title","Name",0,None,None,None,None,None,None,None,None),
|
||||
(2,36,"GtkTreeViewColumn","title","Surname",0,None,None,None,None,None,None,None,None),
|
||||
(2,38,"GtkTreeViewColumn","title","Age",0,None,None,None,None,None,None,None,None),
|
||||
(2,40,"GtkLabel","xalign","0",0,None,None,None,None,None,None,None,None),
|
||||
(2,40,"GtkWidget","margin-bottom","2",0,None,None,None,None,None,None,None,None),
|
||||
(2,40,"GtkWidget","margin-end","2",0,None,None,None,None,None,None,None,None),
|
||||
(2,40,"GtkWidget","margin-start","2",0,None,None,None,None,None,None,None,None),
|
||||
(2,40,"GtkWidget","margin-top","2",0,None,None,None,None,None,None,None,None)
|
||||
</object_property>
|
||||
<object_data>
|
||||
(2,1,"GtkListStore",1,1,None,None,None,None,None,None),
|
||||
(2,1,"GtkListStore",2,2,None,1,None,None,None,None),
|
||||
(2,1,"GtkListStore",2,3,None,1,None,None,None,None),
|
||||
(2,1,"GtkListStore",2,4,None,1,None,None,None,None),
|
||||
(2,1,"GtkListStore",2,5,None,1,None,None,None,None),
|
||||
(2,1,"GtkListStore",3,6,None,None,None,None,None,None),
|
||||
(2,1,"GtkListStore",4,7,None,6,None,None,None,None),
|
||||
(2,1,"GtkListStore",5,8,"John",7,None,None,None,None),
|
||||
(2,1,"GtkListStore",5,9,"Doe",7,None,None,None,None),
|
||||
(2,1,"GtkListStore",5,10,"25",7,None,None,None,None),
|
||||
(2,1,"GtkListStore",5,11,"This is the John Doe row",7,None,None,None,None),
|
||||
(2,1,"GtkListStore",4,12,None,6,None,None,None,None),
|
||||
(2,1,"GtkListStore",5,13,"Mary",12,None,None,None,None),
|
||||
(2,1,"GtkListStore",5,14,"Unknown",12,None,None,None,None),
|
||||
(2,1,"GtkListStore",5,15,"50",12,None,None,None,None),
|
||||
(2,1,"GtkListStore",5,16,"This is the Mary Unknown row",12,None,None,None,None)
|
||||
</object_data>
|
||||
<object_data_arg>
|
||||
(2,1,"GtkListStore",2,2,"type","gchararray"),
|
||||
(2,1,"GtkListStore",2,3,"type","gchararray"),
|
||||
(2,1,"GtkListStore",2,4,"type","gint"),
|
||||
(2,1,"GtkListStore",2,5,"type","gchararray"),
|
||||
(2,1,"GtkListStore",5,8,"id","0"),
|
||||
(2,1,"GtkListStore",5,9,"id","1"),
|
||||
(2,1,"GtkListStore",5,10,"id","2"),
|
||||
(2,1,"GtkListStore",5,11,"id","3"),
|
||||
(2,1,"GtkListStore",5,13,"id","0"),
|
||||
(2,1,"GtkListStore",5,14,"id","1"),
|
||||
(2,1,"GtkListStore",5,15,"id","2"),
|
||||
(2,1,"GtkListStore",5,16,"id","3")
|
||||
</object_data_arg>
|
||||
</cambalache-project>
|
@ -1,179 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Cambalache 0.14.0 -->
|
||||
<!--License: GPL-3.0-->
|
||||
<interface domain="https://sharpetronics.com">
|
||||
<!-- interface-name drogon-dashboard.ui -->
|
||||
<!-- interface-description A secure Drogon dashboard for managing content from a Drogon web server.
|
||||
|
||||
The admin dashboard after login user interface. -->
|
||||
<!-- interface-copyright SharpeTronics, Inc. -->
|
||||
<!-- interface-authors SharpeTronics, Inc.
|
||||
oDinZu WenKi -->
|
||||
<requires lib="gtk" version="4.6"/>
|
||||
<requires lib="libadwaita" version="1.0"/>
|
||||
<object class="GtkWindow" id="adminDash">
|
||||
<property name="default-height">700</property>
|
||||
<property name="default-width">500</property>
|
||||
<property name="maximized">True</property>
|
||||
<property name="title">A Drogon Content Manager</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="halign">start</property>
|
||||
<property name="spacing">3</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="halign">start</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="halign">start</property>
|
||||
<property name="label">SharpeTronics</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="margin-top">5</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">1</property>
|
||||
<property name="row">0</property>
|
||||
<property name="row-span">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="halign">start</property>
|
||||
<property name="label">A Drogon Dashboard</property>
|
||||
<property name="margin-bottom">3</property>
|
||||
<property name="margin-start">15</property>
|
||||
<property name="margin-top">5</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
<property name="row-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="halign">start</property>
|
||||
<property name="label">GENERAL</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="margin-top">35</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">8</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="child">
|
||||
<object class="AdwButtonContent">
|
||||
<property name="halign">start</property>
|
||||
<property name="icon-name">text-x-generic</property>
|
||||
<property name="label"> Content Manager</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="margin-start">5</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="halign">start</property>
|
||||
<property name="label">PLUGINS</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="margin-top">35</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="child">
|
||||
<object class="AdwButtonContent">
|
||||
<property name="halign">start</property>
|
||||
<property name="icon-name">image-x-generic</property>
|
||||
<property name="label"> Media Library</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="margin-start">5</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="margin-bottom">15</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="child">
|
||||
<object class="AdwButtonContent">
|
||||
<property name="halign">start</property>
|
||||
<property name="icon-name">application-x-addon-symbolic</property>
|
||||
<property name="label"> Plugins</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="margin-start">5</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">9</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="child">
|
||||
<object class="AdwButtonContent">
|
||||
<property name="halign">start</property>
|
||||
<property name="icon-name">org.gnome.Settings-default-apps-symbolic</property>
|
||||
<property name="label"> Marketplace</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="margin-top">5</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">10</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="child">
|
||||
<object class="AdwButtonContent">
|
||||
<property name="halign">start</property>
|
||||
<property name="icon-name">applications-system-symbolic</property>
|
||||
<property name="label"> Settings</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="margin-start">5</property>
|
||||
<property name="margin-top">5</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">11</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCenterBox"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
@ -1,234 +1,223 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Cambalache 0.14.0 -->
|
||||
<!--License: GPL-3.0-->
|
||||
<interface domain="https://sharpetronics.com">
|
||||
<!-- interface-description A secure Drogon dashboard for managing content from a Drogon web server.
|
||||
|
||||
The admin user registration user interface. -->
|
||||
<!-- interface-copyright SharpeTronics, Inc. -->
|
||||
<!-- interface-authors SharpeTronics, Inc.
|
||||
oDinZu WenKi -->
|
||||
<requires lib="gtk" version="4.6"/>
|
||||
<requires lib="libadwaita" version="1.0"/>
|
||||
<object class="GtkWindow" id="register_window">
|
||||
<property name="default-height">-1</property>
|
||||
<property name="default-width">-1</property>
|
||||
<property name="title">Admin Registration</property>
|
||||
<!-- Created with Cambalache 0.93.0 -->
|
||||
<interface>
|
||||
<!-- interface-name admin-register.ui -->
|
||||
<object class="GtkListStore" id="liststore1">
|
||||
<columns>
|
||||
<column type="gchararray"/>
|
||||
<column type="gchararray"/>
|
||||
<column type="gint"/>
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">John</col>
|
||||
<col id="1" translatable="yes">Doe</col>
|
||||
<col id="2">25</col>
|
||||
<col id="3" translatable="yes">This is the John Doe row</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">Mary</col>
|
||||
<col id="1" translatable="yes">Unknown</col>
|
||||
<col id="2">50</col>
|
||||
<col id="3" translatable="yes">This is the Mary Unknown row</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<menu id="menubar">
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_File</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_New</attribute>
|
||||
<attribute name="action">win.new</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Open</attribute>
|
||||
<attribute name="action">win.open</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Save</attribute>
|
||||
<attribute name="action">win.save</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Save _As</attribute>
|
||||
<attribute name="action">win.save-as</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Quit</attribute>
|
||||
<attribute name="action">win.quit</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Edit</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Copy</attribute>
|
||||
<attribute name="action">win.copy</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Cut</attribute>
|
||||
<attribute name="action">win.cut</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Paste</attribute>
|
||||
<attribute name="action">win.paste</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<attribute name="action">win.help</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About</attribute>
|
||||
<attribute name="action">win.about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
</menu>
|
||||
<object class="GtkAboutDialog" id="aboutdialog1">
|
||||
<property name="program-name" translatable="yes">Builder demo</property>
|
||||
<property name="logo-icon-name" translatable="yes">org.gtk.Demo4</property>
|
||||
<property name="modal">True</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="default-height">250</property>
|
||||
<property name="default-width">440</property>
|
||||
<property name="title" translatable="yes">Builder</property>
|
||||
<child>
|
||||
<object class="GtkCenterBox">
|
||||
<property name="halign">center</property>
|
||||
<property name="width-request">500</property>
|
||||
<child type="center">
|
||||
<object class="GtkGrid">
|
||||
<property name="column-spacing">7</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="row-spacing">5</property>
|
||||
<property name="width-request">450</property>
|
||||
<object class="GtkBox" id="vbox1">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkPopoverMenuBar" id="menubar1">
|
||||
<property name="menu-model">menubar</property>
|
||||
<accessibility>
|
||||
<property name="label">Main Menu</property>
|
||||
</accessibility>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="toolbar1">
|
||||
<property name="accessible-role">toolbar</property>
|
||||
<property name="css-classes">toolbar</property>
|
||||
<accessibility>
|
||||
<property name="label">Toolbar</property>
|
||||
</accessibility>
|
||||
<child>
|
||||
<object class="GtkImage" id="logo">
|
||||
<property name="accessible-role">img</property>
|
||||
<property name="icon-name">audio-x-generic</property>
|
||||
<property name="icon-size">large</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="pixel-size">75</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
<property name="row">0</property>
|
||||
<property name="row-span">1</property>
|
||||
</layout>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">New</property>
|
||||
<property name="tooltip-text" translatable="yes">Create a new file</property>
|
||||
<property name="icon-name">document-new</property>
|
||||
<property name="action-name">win.new</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="title_label">
|
||||
<property name="justify">center</property>
|
||||
<property name="label">Welcome to SharpeTronics</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
<property name="row">1</property>
|
||||
<property name="row-span">1</property>
|
||||
</layout>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Open</property>
|
||||
<property name="tooltip-text" translatable="yes">Open a file</property>
|
||||
<property name="icon-name">document-open</property>
|
||||
<property name="action-name">win.open</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="moto_label">
|
||||
<property name="justify">center</property>
|
||||
<property name="label">A Drogon Dashboard</property>
|
||||
<property name="margin-bottom">15</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Save</property>
|
||||
<property name="tooltip-text" translatable="yes">Save a file</property>
|
||||
<property name="icon-name">document-save</property>
|
||||
<property name="action-name">win.save</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="first_name_label">
|
||||
<property name="accessible-role">label</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">First Name:</property>
|
||||
<property name="margin-bottom">2</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
<object class="GtkSeparator"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Copy</property>
|
||||
<property name="tooltip-text" translatable="yes">Copy selected object into the clipboard</property>
|
||||
<property name="icon-name">edit-copy</property>
|
||||
<property name="action-name">win.copy</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTextView" id="first_name_input">
|
||||
<property name="accepts-tab">False</property>
|
||||
<property name="accessible-role">input</property>
|
||||
<property name="focus-on-click">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="indent">3</property>
|
||||
<property name="input-hints">no-emoji | no-spellcheck | private</property>
|
||||
<property name="input-purpose">name</property>
|
||||
<property name="left-margin">1</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="pixels-above-lines">5</property>
|
||||
<property name="pixels-below-lines">5</property>
|
||||
<property name="tooltip-text">Enter the first name</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">5</property>
|
||||
</layout>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Cut</property>
|
||||
<property name="tooltip-text" translatable="yes">Cut selected object into the clipboard</property>
|
||||
<property name="icon-name">edit-cut</property>
|
||||
<property name="action-name">win.cut</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="last_name_label">
|
||||
<property name="accessible-role">label</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">Last Name:</property>
|
||||
<property name="margin-bottom">2</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Paste</property>
|
||||
<property name="tooltip-text" translatable="yes">Paste object from the clipboard</property>
|
||||
<property name="icon-name">edit-paste</property>
|
||||
<property name="action-name">win.paste</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="has-frame">1</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="last_name_input">
|
||||
<property name="accepts-tab">False</property>
|
||||
<property name="accessible-role">input</property>
|
||||
<property name="focus-on-click">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="indent">3</property>
|
||||
<property name="input-hints">no-emoji | no-spellcheck | private</property>
|
||||
<property name="input-purpose">name</property>
|
||||
<property name="left-margin">1</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="pixels-above-lines">5</property>
|
||||
<property name="pixels-below-lines">5</property>
|
||||
<property name="tooltip-text">Enter the last name</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="register_button">
|
||||
<property name="child">
|
||||
<object class="AdwButtonContent">
|
||||
<property name="icon-name">pan-start-symbolic-rtl</property>
|
||||
<property name="label">Let's Start</property>
|
||||
<object class="GtkTreeView" id="treeview1">
|
||||
<property name="model">liststore1</property>
|
||||
<property name="tooltip-column">3</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="column1">
|
||||
<property name="title">Name</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="renderer1"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="margin-bottom">50</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
<property name="row">12</property>
|
||||
<property name="row-span">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="email_label">
|
||||
<property name="accessible-role">label</property>
|
||||
<property name="label">Email:</property>
|
||||
<property name="margin-bottom">2</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
<property name="row">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTextView" id="email_input">
|
||||
<property name="accepts-tab">False</property>
|
||||
<property name="accessible-role">input</property>
|
||||
<property name="focus-on-click">False</property>
|
||||
<property name="indent">3</property>
|
||||
<property name="input-hints">no-emoji | no-spellcheck</property>
|
||||
<property name="input-purpose">email</property>
|
||||
<property name="left-margin">1</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="pixels-above-lines">5</property>
|
||||
<property name="pixels-below-lines">5</property>
|
||||
<property name="tooltip-text">Enter the user email</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
<property name="row">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="password_label">
|
||||
<property name="label">Password:</property>
|
||||
<property name="margin-bottom">2</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
<property name="row">8</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPasswordEntry" id="password_input">
|
||||
<property name="accessible-role">input</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="show-peek-icon">True</property>
|
||||
<property name="tooltip-text">Enter the user password</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
<property name="row">9</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="password_label_confirm">
|
||||
<property name="label">Confirm Password:</property>
|
||||
<property name="margin-bottom">2</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
<property name="row">10</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPasswordEntry" id="password_input_confirm">
|
||||
<property name="accessible-role">input</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="show-peek-icon">True</property>
|
||||
<property name="tooltip-text">Enter the user password</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">2</property>
|
||||
<property name="row">11</property>
|
||||
</layout>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="column2">
|
||||
<property name="title">Surname</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="renderer2"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="column3">
|
||||
<property name="title">Age</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="renderer3"/>
|
||||
<attributes>
|
||||
<attribute name="text">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="statusbar1">
|
||||
<property name="xalign">0</property>
|
||||
<property name="margin-start">2</property>
|
||||
<property name="margin-end">2</property>
|
||||
<property name="margin-top">2</property>
|
||||
<property name="margin-bottom">2</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -1,11 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Cambalache 0.14.0 -->
|
||||
<!--License: GPL-3.0-->
|
||||
<interface>
|
||||
<!-- interface-description A secure Drogon dashboard for managing content from a Drogon web server.
|
||||
|
||||
The content manager user interface. -->
|
||||
<!-- interface-copyright SharpeTronics, Inc. -->
|
||||
<!-- interface-authors SharpeTronics, Inc.
|
||||
oDinZu WenKi -->
|
||||
</interface>
|
@ -1,368 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
|
||||
<cambalache-project version="0.13.1" target_tk="gtk-4.0">
|
||||
<ui>
|
||||
(1,None,"drogon-dashboard.ui","admin-dashboard.ui","A secure Drogon dashboard for managing content from a Drogon web server.\n\nThe admin dashboard after login user interface.","SharpeTronics, Inc.","SharpeTronics, Inc.\noDinZu WenKi",None,"https://sharpetronics.com","License: GPL-3.0",None),
|
||||
(2,None,None,"login.ui","A secure Drogon dashboard for managing content from a Drogon web server.\n\nThe login user interface.","SharpeTronics, Inc.","SharpeTronics, Inc.\noDinZu WenKi",None,"https://sharpetronics.com","License: GPL-3.0",None),
|
||||
(3,None,None,"admin-register.ui","A secure Drogon dashboard for managing content from a Drogon web server.\n\nThe admin user registration user interface.","SharpeTronics, Inc.","SharpeTronics, Inc.\noDinZu WenKi",None,"https://sharpetronics.com","License: GPL-3.0",None),
|
||||
(4,None,None,"password-recovery.ui","A secure Drogon dashboard for managing content from a Drogon web server.\n\nThe password recovery user interface.","SharpeTronics, Inc.","SharpeTronics, Inc.\noDinZu WenKi",None,None,"License: GPL-3.0",None),
|
||||
(6,None,None,"content-manager.ui","A secure Drogon dashboard for managing content from a Drogon web server.\n\nThe content manager user interface.","SharpeTronics, Inc.","SharpeTronics, Inc.\noDinZu WenKi",None,None,"License: GPL-3.0",None)
|
||||
</ui>
|
||||
<css>
|
||||
(1,"menu-buttons.css",None,1)
|
||||
</css>
|
||||
<object>
|
||||
(1,1,"GtkWindow","adminDash",None,None,None,None,-1,None),
|
||||
(1,4,"GtkBox",None,1,None,None,None,1,None),
|
||||
(1,5,"GtkGrid",None,4,None,None,None,-1,None),
|
||||
(1,8,"GtkLabel",None,5,None,None,None,None,None),
|
||||
(1,9,"GtkLabel",None,5,None,None,None,1,None),
|
||||
(1,10,"GtkSeparator",None,5,None,None,None,6,None),
|
||||
(1,12,"GtkButton",None,5,None,None,None,3,None),
|
||||
(1,13,"AdwButtonContent",None,12,None,None,None,-1,None),
|
||||
(1,14,"GtkLabel",None,5,None,None,None,4,None),
|
||||
(1,15,"GtkLabel",None,5,None,None,None,2,None),
|
||||
(1,16,"GtkButton",None,5,None,None,None,5,None),
|
||||
(1,17,"AdwButtonContent",None,16,None,None,None,None,None),
|
||||
(1,18,"GtkButton",None,5,None,None,None,7,None),
|
||||
(1,19,"AdwButtonContent",None,18,None,None,None,None,None),
|
||||
(1,20,"GtkButton",None,5,None,None,None,8,None),
|
||||
(1,21,"AdwButtonContent",None,20,None,None,None,None,None),
|
||||
(1,22,"GtkButton",None,5,None,None,None,9,None),
|
||||
(1,23,"AdwButtonContent",None,22,None,None,None,None,None),
|
||||
(1,24,"GtkCenterBox",None,4,None,None,None,-1,None),
|
||||
(2,1,"GtkWindow","loginWindow",None,None,None,None,-1,None),
|
||||
(2,2,"GtkCenterBox",None,1,None,None,None,-1,None),
|
||||
(2,3,"GtkGrid",None,2,None,"center",None,-1,None),
|
||||
(2,4,"GtkImage","logo",3,None,None,None,None,None),
|
||||
(2,5,"GtkLabel","titleLabel",3,None,None,None,1,None),
|
||||
(2,6,"GtkLabel","mottoLabel",3,None,None,None,2,None),
|
||||
(2,7,"GtkLabel","emailLabel",3,None,None,None,3,None),
|
||||
(2,8,"GtkLabel","passwordLabel",3,None,None,None,5,None),
|
||||
(2,10,"GtkTextView","emailid",3,None,None,None,4,None),
|
||||
(2,11,"GtkTextView","password",3,None,None,None,6,None),
|
||||
(2,12,"GtkSeparator",None,3,None,None,None,7,None),
|
||||
(2,13,"GtkLabel","forgotPass",3,None,None,None,8,None),
|
||||
(3,1,"GtkWindow","register_window",None,None,None,None,None,None),
|
||||
(3,2,"GtkCenterBox",None,1,None,None,None,None,None),
|
||||
(3,3,"GtkGrid",None,2,None,"center",None,None,None),
|
||||
(3,4,"GtkImage","logo",3,None,None,None,None,None),
|
||||
(3,5,"GtkLabel","title_label",3,None,None,None,1,None),
|
||||
(3,6,"GtkLabel","moto_label",3,None,None,None,2,None),
|
||||
(3,7,"GtkLabel","first_name_label",3,None,None,None,3,None),
|
||||
(3,8,"GtkTextView","first_name_input",3,None,None,None,4,None),
|
||||
(3,9,"GtkLabel","last_name_label",3,None,None,None,5,None),
|
||||
(3,10,"GtkTextView","last_name_input",3,None,None,None,6,None),
|
||||
(3,12,"GtkButton","register_button",3,None,None,None,7,None),
|
||||
(3,13,"GtkLabel","email_label",3,None,None,None,8,None),
|
||||
(3,14,"GtkTextView","email_input",3,None,None,None,9,None),
|
||||
(3,15,"GtkLabel","password_label",3,None,None,None,10,None),
|
||||
(3,17,"GtkLabel","password_label_confirm",3,None,None,None,13,None),
|
||||
(3,20,"AdwButtonContent",None,12,None,None,None,-1,None),
|
||||
(3,21,"GtkPasswordEntry","password_input",3,None,None,None,11,None),
|
||||
(3,22,"GtkPasswordEntry","password_input_confirm",3,None,None,None,14,None),
|
||||
(4,1,"GtkWindow","passwordWindow",None,None,None,None,None,None),
|
||||
(4,2,"GtkCenterBox",None,1,None,None,None,None,None),
|
||||
(4,3,"GtkGrid",None,2,None,"center",None,None,None),
|
||||
(4,4,"GtkImage","logo",3,None,None,None,None,None),
|
||||
(4,5,"GtkLabel","titleLabel",3,None,None,None,1,None),
|
||||
(4,7,"GtkLabel","emailLabel",3,None,None,None,3,None),
|
||||
(4,8,"GtkTextView","emailid",3,None,None,None,3,None),
|
||||
(4,9,"GtkButton","sendEmail",3,None,None,None,4,None)
|
||||
</object>
|
||||
<object_property>
|
||||
(1,1,"GtkWindow","default-height","700",None,None,None,None,None,None,None,None,None),
|
||||
(1,1,"GtkWindow","default-width","500",None,None,None,None,None,None,None,None,None),
|
||||
(1,1,"GtkWindow","maximized","True",None,None,None,None,None,None,None,None,None),
|
||||
(1,1,"GtkWindow","title","A Drogon Content Manager",None,None,None,None,None,None,None,None,None),
|
||||
(1,4,"GtkBox","spacing","3",None,None,None,None,None,None,None,None,None),
|
||||
(1,4,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(1,5,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(1,8,"GtkLabel","label","SharpeTronics",None,None,None,None,None,None,None,None,None),
|
||||
(1,8,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(1,8,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
|
||||
(1,8,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
|
||||
(1,9,"GtkLabel","label","A Drogon Dashboard",None,None,None,None,None,None,None,None,None),
|
||||
(1,9,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(1,9,"GtkWidget","margin-bottom","3",None,None,None,None,None,None,None,None,None),
|
||||
(1,9,"GtkWidget","margin-start","15",None,None,None,None,None,None,None,None,None),
|
||||
(1,9,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
|
||||
(1,10,"GtkWidget","margin-bottom","15",None,None,None,None,None,None,None,None,None),
|
||||
(1,12,"GtkButton","child",None,None,None,None,None,13,None,None,None,None),
|
||||
(1,12,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
|
||||
(1,13,"AdwButtonContent","icon-name","text-x-generic",None,None,None,None,None,None,None,None,None),
|
||||
(1,13,"AdwButtonContent","label"," Content Manager",None,None,None,None,None,None,None,None,None),
|
||||
(1,13,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(1,14,"GtkLabel","label","PLUGINS",None,None,None,None,None,None,None,None,None),
|
||||
(1,14,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(1,14,"GtkWidget","margin-bottom","10",None,None,None,None,None,None,None,None,None),
|
||||
(1,14,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
|
||||
(1,14,"GtkWidget","margin-top","35",None,None,None,None,None,None,None,None,None),
|
||||
(1,15,"GtkLabel","label","GENERAL",None,None,None,None,None,None,None,None,None),
|
||||
(1,15,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(1,15,"GtkWidget","margin-bottom","10",None,None,None,None,None,None,None,None,None),
|
||||
(1,15,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
|
||||
(1,15,"GtkWidget","margin-top","35",None,None,None,None,None,None,None,None,None),
|
||||
(1,16,"GtkButton","child",None,None,None,None,None,17,None,None,None,None),
|
||||
(1,16,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
|
||||
(1,17,"AdwButtonContent","icon-name","image-x-generic",None,None,None,None,None,None,None,None,None),
|
||||
(1,17,"AdwButtonContent","label"," Media Library",None,None,None,None,None,None,None,None,None),
|
||||
(1,17,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(1,18,"GtkButton","child",None,None,None,None,None,19,None,None,None,None),
|
||||
(1,18,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
|
||||
(1,19,"AdwButtonContent","icon-name","application-x-addon-symbolic",None,None,None,None,None,None,None,None,None),
|
||||
(1,19,"AdwButtonContent","label"," Plugins",None,None,None,None,None,None,None,None,None),
|
||||
(1,19,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(1,20,"GtkButton","child",None,None,None,None,None,21,None,None,None,None),
|
||||
(1,20,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
|
||||
(1,20,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
|
||||
(1,21,"AdwButtonContent","icon-name","org.gnome.Settings-default-apps-symbolic",None,None,None,None,None,None,None,None,None),
|
||||
(1,21,"AdwButtonContent","label"," Marketplace",None,None,None,None,None,None,None,None,None),
|
||||
(1,21,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(1,22,"GtkButton","child",None,None,None,None,None,23,None,None,None,None),
|
||||
(1,22,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
|
||||
(1,22,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
|
||||
(1,23,"AdwButtonContent","icon-name","applications-system-symbolic",None,None,None,None,None,None,None,None,None),
|
||||
(1,23,"AdwButtonContent","label"," Settings",None,None,None,None,None,None,None,None,None),
|
||||
(1,23,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(2,1,"GtkWindow","default-height","300",None,None,None,None,None,None,None,None,None),
|
||||
(2,1,"GtkWindow","default-width","300",None,None,None,None,None,None,None,None,None),
|
||||
(2,1,"GtkWindow","title","Login",None,None,None,None,None,None,None,None,None),
|
||||
(2,4,"GtkImage","icon-name","audio-x-generic",None,None,None,None,None,None,None,None,None),
|
||||
(2,4,"GtkImage","icon-size","large",None,None,None,None,None,None,None,None,None),
|
||||
(2,4,"GtkImage","pixel-size","75",None,None,None,None,None,None,None,None,None),
|
||||
(2,4,"GtkWidget","margin-bottom","10",None,None,None,None,None,None,None,None,None),
|
||||
(2,5,"GtkLabel","justify","center",None,None,None,None,None,None,None,None,None),
|
||||
(2,5,"GtkLabel","label","Welcome to SharpeTronics",None,None,None,None,None,None,None,None,None),
|
||||
(2,6,"GtkLabel","justify","center",None,None,None,None,None,None,None,None,None),
|
||||
(2,6,"GtkLabel","label","A Drogon Dashboard",None,None,None,None,None,None,None,None,None),
|
||||
(2,6,"GtkWidget","margin-bottom","15",None,None,None,None,None,None,None,None,None),
|
||||
(2,7,"GtkLabel","label","Email:",None,None,None,None,None,None,None,None,None),
|
||||
(2,7,"GtkLabel","xalign","0.0",None,None,None,None,None,None,None,None,None),
|
||||
(2,7,"GtkWidget","margin-bottom","2",None,None,None,None,None,None,None,None,None),
|
||||
(2,8,"GtkLabel","label","Password:",None,None,None,None,None,None,None,None,None),
|
||||
(2,8,"GtkLabel","xalign","0.0",None,None,None,None,None,None,None,None,None),
|
||||
(2,8,"GtkWidget","margin-bottom","2",None,None,None,None,None,None,None,None,None),
|
||||
(2,10,"GtkAccessible","accessible-role","input",None,None,None,None,None,None,None,None,None),
|
||||
(2,10,"GtkTextView","accepts-tab","False",None,None,None,None,None,None,None,None,None),
|
||||
(2,10,"GtkTextView","indent","3",None,None,None,None,None,None,None,None,None),
|
||||
(2,10,"GtkTextView","input-hints","no-emoji | no-spellcheck",None,None,None,None,None,None,None,None,None),
|
||||
(2,10,"GtkTextView","input-purpose","email",None,None,None,None,None,None,None,None,None),
|
||||
(2,10,"GtkTextView","left-margin","1",None,None,None,None,None,None,None,None,None),
|
||||
(2,10,"GtkTextView","pixels-above-lines","5",None,None,None,None,None,None,None,None,None),
|
||||
(2,10,"GtkTextView","pixels-below-lines","5",None,None,None,None,None,None,None,None,None),
|
||||
(2,10,"GtkWidget","focus-on-click","False",None,None,None,None,None,None,None,None,None),
|
||||
(2,10,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
|
||||
(2,10,"GtkWidget","tooltip-text","Enter the user email",None,None,None,None,None,None,None,None,None),
|
||||
(2,11,"GtkAccessible","accessible-role","input",None,None,None,None,None,None,None,None,None),
|
||||
(2,11,"GtkTextView","accepts-tab","False",None,None,None,None,None,None,None,None,None),
|
||||
(2,11,"GtkTextView","indent","3",None,None,None,None,None,None,None,None,None),
|
||||
(2,11,"GtkTextView","input-hints","no-emoji | no-spellcheck | private",None,None,None,None,None,None,None,None,None),
|
||||
(2,11,"GtkTextView","input-purpose","password",None,None,None,None,None,None,None,None,None),
|
||||
(2,11,"GtkTextView","left-margin","1",None,None,None,None,None,None,None,None,None),
|
||||
(2,11,"GtkTextView","pixels-above-lines","5",None,None,None,None,None,None,None,None,None),
|
||||
(2,11,"GtkTextView","pixels-below-lines","5",None,None,None,None,None,None,None,None,None),
|
||||
(2,11,"GtkWidget","focus-on-click","False",None,None,None,None,None,None,None,None,None),
|
||||
(2,11,"GtkWidget","tooltip-text","Enter the user password",None,None,None,None,None,None,None,None,None),
|
||||
(2,12,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
|
||||
(2,12,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
|
||||
(2,13,"GtkLabel","label","Forgot password",None,None,None,None,None,None,None,None,None),
|
||||
(3,1,"GtkWindow","default-height","-1",None,None,None,None,None,None,None,None,None),
|
||||
(3,1,"GtkWindow","default-width","-1",None,None,None,None,None,None,None,None,None),
|
||||
(3,1,"GtkWindow","title","Admin Registration",None,None,None,None,None,None,None,None,None),
|
||||
(3,2,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||
(3,2,"GtkWidget","width-request","500",None,None,None,None,None,None,None,None,None),
|
||||
(3,3,"GtkGrid","column-spacing","7",None,None,None,None,None,None,None,None,None),
|
||||
(3,3,"GtkGrid","row-spacing","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,3,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
|
||||
(3,3,"GtkWidget","width-request","450",None,None,None,None,None,None,None,None,None),
|
||||
(3,4,"GtkAccessible","accessible-role","img",None,None,None,None,None,None,None,None,None),
|
||||
(3,4,"GtkImage","icon-name","audio-x-generic",None,None,None,None,None,None,None,None,None),
|
||||
(3,4,"GtkImage","icon-size","large",None,None,None,None,None,None,None,None,None),
|
||||
(3,4,"GtkImage","pixel-size","75",None,None,None,None,None,None,None,None,None),
|
||||
(3,4,"GtkWidget","margin-bottom","10",None,None,None,None,None,None,None,None,None),
|
||||
(3,5,"GtkLabel","justify","center",None,None,None,None,None,None,None,None,None),
|
||||
(3,5,"GtkLabel","label","Welcome to SharpeTronics",None,None,None,None,None,None,None,None,None),
|
||||
(3,6,"GtkLabel","justify","center",None,None,None,None,None,None,None,None,None),
|
||||
(3,6,"GtkLabel","label","A Drogon Dashboard",None,None,None,None,None,None,None,None,None),
|
||||
(3,6,"GtkWidget","margin-bottom","15",None,None,None,None,None,None,None,None,None),
|
||||
(3,7,"GtkAccessible","accessible-role","label",None,None,None,None,None,None,None,None,None),
|
||||
(3,7,"GtkLabel","label","First Name:",None,None,None,None,None,None,None,None,None),
|
||||
(3,7,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(3,7,"GtkWidget","margin-bottom","2",None,None,None,None,None,None,None,None,None),
|
||||
(3,8,"GtkAccessible","accessible-role","input",None,None,None,None,None,None,None,None,None),
|
||||
(3,8,"GtkTextView","accepts-tab","False",None,None,None,None,None,None,None,None,None),
|
||||
(3,8,"GtkTextView","indent","3",None,None,None,None,None,None,None,None,None),
|
||||
(3,8,"GtkTextView","input-hints","no-emoji | no-spellcheck | private",None,None,None,None,None,None,None,None,None),
|
||||
(3,8,"GtkTextView","input-purpose","name",None,None,None,None,None,None,None,None,None),
|
||||
(3,8,"GtkTextView","left-margin","1",None,None,None,None,None,None,None,None,None),
|
||||
(3,8,"GtkTextView","pixels-above-lines","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,8,"GtkTextView","pixels-below-lines","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,8,"GtkWidget","focus-on-click","False",None,None,None,None,None,None,None,None,None),
|
||||
(3,8,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||
(3,8,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,8,"GtkWidget","tooltip-text","Enter the first name",None,None,None,None,None,None,None,None,None),
|
||||
(3,9,"GtkAccessible","accessible-role","label",None,None,None,None,None,None,None,None,None),
|
||||
(3,9,"GtkLabel","label","Last Name:",None,None,None,None,None,None,None,None,None),
|
||||
(3,9,"GtkWidget","halign","start",None,None,None,None,None,None,None,None,None),
|
||||
(3,9,"GtkWidget","margin-bottom","2",None,None,None,None,None,None,None,None,None),
|
||||
(3,10,"GtkAccessible","accessible-role","input",None,None,None,None,None,None,None,None,None),
|
||||
(3,10,"GtkTextView","accepts-tab","False",None,None,None,None,None,None,None,None,None),
|
||||
(3,10,"GtkTextView","indent","3",None,None,None,None,None,None,None,None,None),
|
||||
(3,10,"GtkTextView","input-hints","no-emoji | no-spellcheck | private",None,None,None,None,None,None,None,None,None),
|
||||
(3,10,"GtkTextView","input-purpose","name",None,None,None,None,None,None,None,None,None),
|
||||
(3,10,"GtkTextView","left-margin","1",None,None,None,None,None,None,None,None,None),
|
||||
(3,10,"GtkTextView","pixels-above-lines","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,10,"GtkTextView","pixels-below-lines","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,10,"GtkWidget","focus-on-click","False",None,None,None,None,None,None,None,None,None),
|
||||
(3,10,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
|
||||
(3,10,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,10,"GtkWidget","tooltip-text","Enter the last name",None,None,None,None,None,None,None,None,None),
|
||||
(3,12,"GtkButton","child",None,None,None,None,None,20,None,None,None,None),
|
||||
(3,12,"GtkWidget","margin-bottom","50",None,None,None,None,None,None,None,None,None),
|
||||
(3,13,"GtkAccessible","accessible-role","label",None,None,None,None,None,None,None,None,None),
|
||||
(3,13,"GtkLabel","label","Email:",None,None,None,None,None,None,None,None,None),
|
||||
(3,13,"GtkLabel","xalign","0.0",None,None,None,None,None,None,None,None,None),
|
||||
(3,13,"GtkWidget","margin-bottom","2",None,None,None,None,None,None,None,None,None),
|
||||
(3,14,"GtkAccessible","accessible-role","input",None,None,None,None,None,None,None,None,None),
|
||||
(3,14,"GtkTextView","accepts-tab","False",None,None,None,None,None,None,None,None,None),
|
||||
(3,14,"GtkTextView","indent","3",None,None,None,None,None,None,None,None,None),
|
||||
(3,14,"GtkTextView","input-hints","no-emoji | no-spellcheck",None,None,None,None,None,None,None,None,None),
|
||||
(3,14,"GtkTextView","input-purpose","email",None,None,None,None,None,None,None,None,None),
|
||||
(3,14,"GtkTextView","left-margin","1",None,None,None,None,None,None,None,None,None),
|
||||
(3,14,"GtkTextView","pixels-above-lines","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,14,"GtkTextView","pixels-below-lines","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,14,"GtkWidget","focus-on-click","False",None,None,None,None,None,None,None,None,None),
|
||||
(3,14,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,14,"GtkWidget","tooltip-text","Enter the user email",None,None,None,None,None,None,None,None,None),
|
||||
(3,15,"GtkLabel","label","Password:",None,None,None,None,None,None,None,None,None),
|
||||
(3,15,"GtkLabel","xalign","0.0",None,None,None,None,None,None,None,None,None),
|
||||
(3,15,"GtkWidget","margin-bottom","2",None,None,None,None,None,None,None,None,None),
|
||||
(3,17,"GtkLabel","label","Confirm Password:",None,None,None,None,None,None,None,None,None),
|
||||
(3,17,"GtkLabel","xalign","0.0",None,None,None,None,None,None,None,None,None),
|
||||
(3,17,"GtkWidget","margin-bottom","2",None,None,None,None,None,None,None,None,None),
|
||||
(3,20,"AdwButtonContent","icon-name","pan-start-symbolic-rtl",None,None,None,None,None,None,None,None,None),
|
||||
(3,20,"AdwButtonContent","label","Let's Start",None,None,None,None,None,None,None,None,None),
|
||||
(3,21,"GtkAccessible","accessible-role","input",None,None,None,None,None,None,None,None,None),
|
||||
(3,21,"GtkPasswordEntry","show-peek-icon","True",None,None,None,None,None,None,None,None,None),
|
||||
(3,21,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,21,"GtkWidget","tooltip-text","Enter the user password",None,None,None,None,None,None,None,None,None),
|
||||
(3,22,"GtkAccessible","accessible-role","input",None,None,None,None,None,None,None,None,None),
|
||||
(3,22,"GtkPasswordEntry","show-peek-icon","True",None,None,None,None,None,None,None,None,None),
|
||||
(3,22,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
|
||||
(3,22,"GtkWidget","tooltip-text","Enter the user password",None,None,None,None,None,None,None,None,None),
|
||||
(4,1,"GtkWindow","default-height","300",None,None,None,None,None,None,None,None,None),
|
||||
(4,1,"GtkWindow","default-width","300",None,None,None,None,None,None,None,None,None),
|
||||
(4,1,"GtkWindow","title","Login",None,None,None,None,None,None,None,None,None),
|
||||
(4,4,"GtkImage","icon-name","audio-x-generic",None,None,None,None,None,None,None,None,None),
|
||||
(4,4,"GtkImage","icon-size","large",None,None,None,None,None,None,None,None,None),
|
||||
(4,4,"GtkImage","pixel-size","75",None,None,None,None,None,None,None,None,None),
|
||||
(4,4,"GtkWidget","margin-bottom","10",None,None,None,None,None,None,None,None,None),
|
||||
(4,5,"GtkAccessible","accessible-role","label",None,None,None,None,None,None,None,None,None),
|
||||
(4,5,"GtkLabel","justify","center",None,None,None,None,None,None,None,None,None),
|
||||
(4,5,"GtkLabel","label","Password Recovery",None,None,None,None,None,None,None,None,None),
|
||||
(4,5,"GtkWidget","margin-bottom","15",None,None,None,None,None,None,None,None,None),
|
||||
(4,7,"GtkLabel","label","Email:",None,None,None,None,None,None,None,None,None),
|
||||
(4,7,"GtkLabel","xalign","0.0",None,None,None,None,None,None,None,None,None),
|
||||
(4,7,"GtkWidget","margin-bottom","2",None,None,None,None,None,None,None,None,None),
|
||||
(4,8,"GtkAccessible","accessible-role","input",None,None,None,None,None,None,None,None,None),
|
||||
(4,8,"GtkTextView","accepts-tab","False",None,None,None,None,None,None,None,None,None),
|
||||
(4,8,"GtkTextView","indent","3",None,None,None,None,None,None,None,None,None),
|
||||
(4,8,"GtkTextView","input-hints","no-emoji | no-spellcheck",None,None,None,None,None,None,None,None,None),
|
||||
(4,8,"GtkTextView","input-purpose","email",None,None,None,None,None,None,None,None,None),
|
||||
(4,8,"GtkTextView","left-margin","1",None,None,None,None,None,None,None,None,None),
|
||||
(4,8,"GtkTextView","pixels-above-lines","5",None,None,None,None,None,None,None,None,None),
|
||||
(4,8,"GtkTextView","pixels-below-lines","5",None,None,None,None,None,None,None,None,None),
|
||||
(4,8,"GtkWidget","focus-on-click","False",None,None,None,None,None,None,None,None,None),
|
||||
(4,8,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
|
||||
(4,8,"GtkWidget","tooltip-text","Enter the user email",None,None,None,None,None,None,None,None,None),
|
||||
(4,8,"GtkWidget","width-request","275",None,None,None,None,None,None,None,None,None),
|
||||
(4,9,"GtkButton","label","Send",None,None,None,None,None,None,None,None,None)
|
||||
</object_property>
|
||||
<object_layout_property>
|
||||
(1,5,8,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(1,5,8,"GtkGridLayoutChild","column-span","1",None,None,None,None),
|
||||
(1,5,8,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||
(1,5,9,"GtkGridLayoutChild","row","1",None,None,None,None),
|
||||
(1,5,9,"GtkGridLayoutChild","row-span","2",None,None,None,None),
|
||||
(1,5,10,"GtkGridLayoutChild","row","3",None,None,None,None),
|
||||
(1,5,12,"GtkGridLayoutChild","row","5",None,None,None,None),
|
||||
(1,5,14,"GtkGridLayoutChild","row","6",None,None,None,None),
|
||||
(1,5,15,"GtkGridLayoutChild","row","8",None,None,None,None),
|
||||
(1,5,16,"GtkGridLayoutChild","row","7",None,None,None,None),
|
||||
(1,5,18,"GtkGridLayoutChild","row","9",None,None,None,None),
|
||||
(1,5,20,"GtkGridLayoutChild","row","10",None,None,None,None),
|
||||
(1,5,22,"GtkGridLayoutChild","row","11",None,None,None,None),
|
||||
(2,3,4,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(2,3,4,"GtkGridLayoutChild","column-span","1",None,None,None,None),
|
||||
(2,3,4,"GtkGridLayoutChild","row","0",None,None,None,None),
|
||||
(2,3,4,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||
(2,3,5,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(2,3,5,"GtkGridLayoutChild","column-span","1",None,None,None,None),
|
||||
(2,3,5,"GtkGridLayoutChild","row","1",None,None,None,None),
|
||||
(2,3,5,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||
(2,3,6,"GtkGridLayoutChild","row","2",None,None,None,None),
|
||||
(2,3,7,"GtkGridLayoutChild","row","4",None,None,None,None),
|
||||
(2,3,8,"GtkGridLayoutChild","row","7",None,None,None,None),
|
||||
(2,3,10,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(2,3,10,"GtkGridLayoutChild","row","5",None,None,None,None),
|
||||
(2,3,11,"GtkGridLayoutChild","row","8",None,None,None,None),
|
||||
(2,3,12,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(2,3,12,"GtkGridLayoutChild","column-span","1",None,None,None,None),
|
||||
(2,3,12,"GtkGridLayoutChild","row","9",None,None,None,None),
|
||||
(2,3,12,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||
(2,3,13,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(2,3,13,"GtkGridLayoutChild","column-span","1",None,None,None,None),
|
||||
(2,3,13,"GtkGridLayoutChild","row","10",None,None,None,None),
|
||||
(2,3,13,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||
(3,3,4,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(3,3,4,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||
(3,3,4,"GtkGridLayoutChild","row","0",None,None,None,None),
|
||||
(3,3,4,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||
(3,3,5,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(3,3,5,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||
(3,3,5,"GtkGridLayoutChild","row","1",None,None,None,None),
|
||||
(3,3,5,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||
(3,3,6,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(3,3,6,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||
(3,3,6,"GtkGridLayoutChild","row","2",None,None,None,None),
|
||||
(3,3,7,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(3,3,7,"GtkGridLayoutChild","row","4",None,None,None,None),
|
||||
(3,3,8,"GtkGridLayoutChild","row","5",None,None,None,None),
|
||||
(3,3,9,"GtkGridLayoutChild","column","1",None,None,None,None),
|
||||
(3,3,9,"GtkGridLayoutChild","row","4",None,None,None,None),
|
||||
(3,3,10,"GtkGridLayoutChild","column","1",None,None,None,None),
|
||||
(3,3,10,"GtkGridLayoutChild","row","5",None,None,None,None),
|
||||
(3,3,12,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(3,3,12,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||
(3,3,12,"GtkGridLayoutChild","row","12",None,None,None,None),
|
||||
(3,3,12,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||
(3,3,13,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||
(3,3,13,"GtkGridLayoutChild","row","6",None,None,None,None),
|
||||
(3,3,14,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||
(3,3,14,"GtkGridLayoutChild","row","7",None,None,None,None),
|
||||
(3,3,15,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||
(3,3,15,"GtkGridLayoutChild","row","8",None,None,None,None),
|
||||
(3,3,17,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||
(3,3,17,"GtkGridLayoutChild","row","10",None,None,None,None),
|
||||
(3,3,21,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||
(3,3,21,"GtkGridLayoutChild","row","9",None,None,None,None),
|
||||
(3,3,22,"GtkGridLayoutChild","column-span","2",None,None,None,None),
|
||||
(3,3,22,"GtkGridLayoutChild","row","11",None,None,None,None),
|
||||
(4,3,4,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(4,3,4,"GtkGridLayoutChild","column-span","1",None,None,None,None),
|
||||
(4,3,4,"GtkGridLayoutChild","row","0",None,None,None,None),
|
||||
(4,3,4,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||
(4,3,5,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(4,3,5,"GtkGridLayoutChild","column-span","1",None,None,None,None),
|
||||
(4,3,5,"GtkGridLayoutChild","row","1",None,None,None,None),
|
||||
(4,3,5,"GtkGridLayoutChild","row-span","1",None,None,None,None),
|
||||
(4,3,7,"GtkGridLayoutChild","column","0",None,None,None,None),
|
||||
(4,3,7,"GtkGridLayoutChild","row","2",None,None,None,None),
|
||||
(4,3,8,"GtkGridLayoutChild","row","3",None,None,None,None),
|
||||
(4,3,9,"GtkGridLayoutChild","row","4",None,None,None,None)
|
||||
</object_layout_property>
|
||||
<object_data>
|
||||
(2,5,"GtkLabel",2,2,None,1,None,None,None,None)
|
||||
</object_data>
|
||||
</cambalache-project>
|
Binary file not shown.
144
src/ui/login.ui
144
src/ui/login.ui
@ -1,144 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Cambalache 0.14.0 -->
|
||||
<!--License: GPL-3.0-->
|
||||
<interface domain="https://sharpetronics.com">
|
||||
<!-- interface-description A secure Drogon dashboard for managing content from a Drogon web server.
|
||||
|
||||
The login user interface. -->
|
||||
<!-- interface-copyright SharpeTronics, Inc. -->
|
||||
<!-- interface-authors SharpeTronics, Inc.
|
||||
oDinZu WenKi -->
|
||||
<requires lib="gtk" version="4.6"/>
|
||||
<object class="GtkWindow" id="loginWindow">
|
||||
<property name="default-height">300</property>
|
||||
<property name="default-width">300</property>
|
||||
<property name="title">Login</property>
|
||||
<child>
|
||||
<object class="GtkCenterBox">
|
||||
<child type="center">
|
||||
<object class="GtkGrid">
|
||||
<child>
|
||||
<object class="GtkImage" id="logo">
|
||||
<property name="icon-name">audio-x-generic</property>
|
||||
<property name="icon-size">large</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="pixel-size">75</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">1</property>
|
||||
<property name="row">0</property>
|
||||
<property name="row-span">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="titleLabel">
|
||||
<property name="justify">center</property>
|
||||
<property name="label">Welcome to SharpeTronics</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">1</property>
|
||||
<property name="row">1</property>
|
||||
<property name="row-span">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="mottoLabel">
|
||||
<property name="justify">center</property>
|
||||
<property name="label">A Drogon Dashboard</property>
|
||||
<property name="margin-bottom">15</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="emailLabel">
|
||||
<property name="label">Email:</property>
|
||||
<property name="margin-bottom">2</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTextView" id="emailid">
|
||||
<property name="accepts-tab">False</property>
|
||||
<property name="accessible-role">input</property>
|
||||
<property name="focus-on-click">False</property>
|
||||
<property name="indent">3</property>
|
||||
<property name="input-hints">no-emoji | no-spellcheck</property>
|
||||
<property name="input-purpose">email</property>
|
||||
<property name="left-margin">1</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="pixels-above-lines">5</property>
|
||||
<property name="pixels-below-lines">5</property>
|
||||
<property name="tooltip-text">Enter the user email</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="passwordLabel">
|
||||
<property name="label">Password:</property>
|
||||
<property name="margin-bottom">2</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTextView" id="password">
|
||||
<property name="accepts-tab">False</property>
|
||||
<property name="accessible-role">input</property>
|
||||
<property name="focus-on-click">False</property>
|
||||
<property name="indent">3</property>
|
||||
<property name="input-hints">no-emoji | no-spellcheck | private</property>
|
||||
<property name="input-purpose">password</property>
|
||||
<property name="left-margin">1</property>
|
||||
<property name="pixels-above-lines">5</property>
|
||||
<property name="pixels-below-lines">5</property>
|
||||
<property name="tooltip-text">Enter the user password</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">8</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="margin-top">5</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">1</property>
|
||||
<property name="row">9</property>
|
||||
<property name="row-span">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="forgotPass">
|
||||
<property name="label">Forgot password</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">1</property>
|
||||
<property name="row">10</property>
|
||||
<property name="row-span">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
@ -1,93 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Created with Cambalache 0.14.0 -->
|
||||
<!--License: GPL-3.0-->
|
||||
<interface>
|
||||
<!-- interface-description A secure Drogon dashboard for managing content from a Drogon web server.
|
||||
|
||||
The password recovery user interface. -->
|
||||
<!-- interface-copyright SharpeTronics, Inc. -->
|
||||
<!-- interface-authors SharpeTronics, Inc.
|
||||
oDinZu WenKi -->
|
||||
<requires lib="gtk" version="4.6"/>
|
||||
<object class="GtkWindow" id="passwordWindow">
|
||||
<property name="default-height">300</property>
|
||||
<property name="default-width">300</property>
|
||||
<property name="title">Login</property>
|
||||
<child>
|
||||
<object class="GtkCenterBox">
|
||||
<child type="center">
|
||||
<object class="GtkGrid">
|
||||
<child>
|
||||
<object class="GtkImage" id="logo">
|
||||
<property name="icon-name">audio-x-generic</property>
|
||||
<property name="icon-size">large</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="pixel-size">75</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">1</property>
|
||||
<property name="row">0</property>
|
||||
<property name="row-span">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="titleLabel">
|
||||
<property name="accessible-role">label</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="label">Password Recovery</property>
|
||||
<property name="margin-bottom">15</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="column-span">1</property>
|
||||
<property name="row">1</property>
|
||||
<property name="row-span">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="emailLabel">
|
||||
<property name="label">Email:</property>
|
||||
<property name="margin-bottom">2</property>
|
||||
<property name="xalign">0.0</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTextView" id="emailid">
|
||||
<property name="accepts-tab">False</property>
|
||||
<property name="accessible-role">input</property>
|
||||
<property name="focus-on-click">False</property>
|
||||
<property name="indent">3</property>
|
||||
<property name="input-hints">no-emoji | no-spellcheck</property>
|
||||
<property name="input-purpose">email</property>
|
||||
<property name="left-margin">1</property>
|
||||
<property name="margin-bottom">5</property>
|
||||
<property name="pixels-above-lines">5</property>
|
||||
<property name="pixels-below-lines">5</property>
|
||||
<property name="tooltip-text">Enter the user email</property>
|
||||
<property name="width-request">275</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="sendEmail">
|
||||
<property name="label">Send</property>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
561
vendors/api-server/.gitignore
vendored
Normal file
561
vendors/api-server/.gitignore
vendored
Normal file
@ -0,0 +1,561 @@
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/intellij+all,visualstudio,visualstudiocode,cmake,c,c++
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=intellij+all,visualstudio,visualstudiocode,cmake,c,c++
|
||||
|
||||
### C ###
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
### C++ ###
|
||||
# Prerequisites
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
|
||||
# Precompiled Headers
|
||||
|
||||
# Linker files
|
||||
|
||||
# Debugger Files
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
|
||||
# Executables
|
||||
|
||||
### CMake ###
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
CMakeUserPresets.json
|
||||
|
||||
### CMake Patch ###
|
||||
# External projects
|
||||
*-prefix/
|
||||
|
||||
### Intellij+all ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### Intellij+all Patch ###
|
||||
# Ignores the whole .idea folder and all .iml files
|
||||
# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
|
||||
|
||||
.idea/
|
||||
|
||||
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
|
||||
|
||||
*.iml
|
||||
modules.xml
|
||||
.idea/misc.xml
|
||||
*.ipr
|
||||
|
||||
# Sonarlint plugin
|
||||
.idea/sonarlint
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode/*
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
*.code-workspace
|
||||
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
.history
|
||||
.ionide
|
||||
|
||||
### VisualStudio ###
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.meta
|
||||
*.iobj
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*[.json, .xml, .info]
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
### VisualStudio Patch ###
|
||||
# Additional files built by Visual Studio
|
||||
*.tlog
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/intellij+all,visualstudio,visualstudiocode,cmake,c,c++
|
77
vendors/api-server/CMakeLists.txt
vendored
Normal file
77
vendors/api-server/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
# Note: drogon_ctl was implemented to create the local template architecture
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(DrogonCMS_API_Server CXX)
|
||||
|
||||
include(CheckIncludeFileCXX)
|
||||
|
||||
check_include_file_cxx(any HAS_ANY)
|
||||
check_include_file_cxx(string_view HAS_STRING_VIEW)
|
||||
check_include_file_cxx(coroutine HAS_COROUTINE)
|
||||
if (NOT "${CMAKE_CXX_STANDARD}" STREQUAL "")
|
||||
# Do nothing
|
||||
elseif (HAS_ANY AND HAS_STRING_VIEW AND HAS_COROUTINE)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
elseif (HAS_ANY AND HAS_STRING_VIEW)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
else ()
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
endif ()
|
||||
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
add_executable(${PROJECT_NAME} main.cc)
|
||||
|
||||
# ##############################################################################
|
||||
# If you include the drogon source code locally in your project, use this method
|
||||
# to add drogon
|
||||
# add_subdirectory(drogon)
|
||||
# target_link_libraries(${PROJECT_NAME} PRIVATE drogon)
|
||||
#
|
||||
# and comment out the following lines
|
||||
find_package(Drogon CONFIG REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Drogon::Drogon)
|
||||
|
||||
# ##############################################################################
|
||||
|
||||
if (CMAKE_CXX_STANDARD LESS 17)
|
||||
message(FATAL_ERROR "c++17 or higher is required")
|
||||
elseif (CMAKE_CXX_STANDARD LESS 20)
|
||||
message(STATUS "use c++17")
|
||||
else ()
|
||||
message(STATUS "use c++20")
|
||||
endif ()
|
||||
|
||||
aux_source_directory(controllers CTL_SRC)
|
||||
aux_source_directory(filters FILTER_SRC)
|
||||
aux_source_directory(plugins PLUGIN_SRC)
|
||||
aux_source_directory(models MODEL_SRC)
|
||||
|
||||
drogon_create_views(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/views
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
# use the following line to create views with namespaces.
|
||||
# drogon_create_views(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/views
|
||||
# ${CMAKE_CURRENT_BINARY_DIR} TRUE)
|
||||
# use the following line to create views with namespace CHANGE_ME prefixed
|
||||
# and path namespaces.
|
||||
# drogon_create_views(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/views
|
||||
# ${CMAKE_CURRENT_BINARY_DIR} TRUE CHANGE_ME)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/models)
|
||||
target_sources(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
${SRC_DIR}
|
||||
${CTL_SRC}
|
||||
${FILTER_SRC}
|
||||
${PLUGIN_SRC}
|
||||
${MODEL_SRC})
|
||||
# ##############################################################################
|
||||
# uncomment the following line for dynamically loading views
|
||||
# set_property(TARGET ${PROJECT_NAME} PROPERTY ENABLE_EXPORTS ON)
|
||||
|
||||
# ##############################################################################
|
||||
|
||||
add_subdirectory(test)
|
223
vendors/api-server/README.md
vendored
Normal file
223
vendors/api-server/README.md
vendored
Normal file
@ -0,0 +1,223 @@
|
||||
*Note: drogon_ctl was implemented to create the local template architecture*
|
||||

|
||||
|
||||
[](https://github.com/drogonframework/drogon/actions)
|
||||
[](https://gitter.im/drogon-web/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://t.me/joinchat/_mMNGv0748ZkMDAx)
|
||||
[](https://discord.gg/3DvHY6Ewuj)
|
||||
[](https://cloud.docker.com/u/drogonframework/repository/docker/drogonframework/drogon)
|
||||
|
||||
English | [简体中文](./README.zh-CN.md) | [繁體中文](./README.zh-TW.md)
|
||||
### Overview
|
||||
**Drogon** is a C++17/20 based HTTP application framework. Drogon can be used to easily build various types of web application server programs using C++. **Drogon** is the name of a dragon in the American TV series "Game of Thrones" that I really like.
|
||||
|
||||
Drogon is a cross-platform framework, It supports Linux, macOS, FreeBSD, OpenBSD, HaikuOS, and Windows. Its main features are as follows:
|
||||
|
||||
* Use a non-blocking I/O network lib based on epoll (kqueue under macOS/FreeBSD) to provide high-concurrency, high-performance network IO, please visit the [TFB Tests Results](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=composite) for more details;
|
||||
* Provide a completely asynchronous programming mode;
|
||||
* Support Http1.0/1.1 (server side and client side);
|
||||
* Based on template, a simple reflection mechanism is implemented to completely decouple the main program framework, controllers and views.
|
||||
* Support cookies and built-in sessions;
|
||||
* Support back-end rendering, the controller generates the data to the view to generate the Html page. Views are described by CSP template files, C++ codes are embedded into Html pages through CSP tags. And the drogon command-line tool automatically generates the C++ code files for compilation;
|
||||
* Support view page dynamic loading (dynamic compilation and loading at runtime);
|
||||
* Provide a convenient and flexible routing solution from the path to the controller handler;
|
||||
* Support filter chains to facilitate the execution of unified logic (such as login verification, Http Method constraint verification, etc.) before handling HTTP requests;
|
||||
* Support https (based on OpenSSL);
|
||||
* Support WebSocket (server side and client side);
|
||||
* Support JSON format request and response, very friendly to the Restful API application development;
|
||||
* Support file download and upload;
|
||||
* Support gzip, brotli compression transmission;
|
||||
* Support pipelining;
|
||||
* Provide a lightweight command line tool, drogon_ctl, to simplify the creation of various classes in Drogon and the generation of view code;
|
||||
* Support non-blocking I/O based asynchronously reading and writing database (PostgreSQL and MySQL(MariaDB) database);
|
||||
* Support asynchronously reading and writing sqlite3 database based on thread pool;
|
||||
* Support Redis with asynchronous reading and writing;
|
||||
* Support ARM Architecture;
|
||||
* Provide a convenient lightweight ORM implementation that supports for regular object-to-database bidirectional mapping;
|
||||
* Support plugins which can be installed by the configuration file at load time;
|
||||
* Support AOP with built-in joinpoints.
|
||||
* Support C++ coroutines
|
||||
|
||||
## A very simple example
|
||||
|
||||
Unlike most C++ frameworks, the main program of the drogon application can be kept clean and simple. Drogon uses a few tricks to decouple controllers from the main program. The routing settings of controllers can be done through macros or configuration file.
|
||||
|
||||
Below is the main program of a typical drogon application:
|
||||
|
||||
```c++
|
||||
#include <drogon/drogon.h>
|
||||
using namespace drogon;
|
||||
int main()
|
||||
{
|
||||
app().setLogPath("./")
|
||||
.setLogLevel(trantor::Logger::kWarn)
|
||||
.addListener("0.0.0.0", 80)
|
||||
.setThreadNum(16)
|
||||
.enableRunAsDaemon()
|
||||
.run();
|
||||
}
|
||||
```
|
||||
|
||||
It can be further simplified by using configuration file as follows:
|
||||
|
||||
```c++
|
||||
#include <drogon/drogon.h>
|
||||
using namespace drogon;
|
||||
int main()
|
||||
{
|
||||
app().loadConfigFile("./config.json").run();
|
||||
}
|
||||
```
|
||||
|
||||
Drogon provides some interfaces for adding controller logic directly in the main() function, for example, user can register a handler like this in Drogon:
|
||||
|
||||
```c++
|
||||
app().registerHandler("/test?username={name}",
|
||||
[](const HttpRequestPtr& req,
|
||||
std::function<void (const HttpResponsePtr &)> &&callback,
|
||||
const std::string &name)
|
||||
{
|
||||
Json::Value json;
|
||||
json["result"]="ok";
|
||||
json["message"]=std::string("hello,")+name;
|
||||
auto resp=HttpResponse::newHttpJsonResponse(json);
|
||||
callback(resp);
|
||||
},
|
||||
{Get,"LoginFilter"});
|
||||
```
|
||||
|
||||
While such interfaces look intuitive, they are not suitable for complex business logic scenarios. Assuming there are tens or even hundreds of handlers that need to be registered in the framework, isn't it a better practice to implement them separately in their respective classes? So unless your logic is very simple, we don't recommend using above interfaces. Instead, we can create an HttpSimpleController as follows:
|
||||
|
||||
```c++
|
||||
/// The TestCtrl.h file
|
||||
#pragma once
|
||||
#include <drogon/HttpSimpleController.h>
|
||||
using namespace drogon;
|
||||
class TestCtrl:public drogon::HttpSimpleController<TestCtrl>
|
||||
{
|
||||
public:
|
||||
void asyncHandleHttpRequest(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback) override;
|
||||
PATH_LIST_BEGIN
|
||||
PATH_ADD("/test",Get);
|
||||
PATH_LIST_END
|
||||
};
|
||||
|
||||
/// The TestCtrl.cc file
|
||||
#include "TestCtrl.h"
|
||||
void TestCtrl::asyncHandleHttpRequest(const HttpRequestPtr& req,
|
||||
std::function<void (const HttpResponsePtr &)> &&callback)
|
||||
{
|
||||
//write your application logic here
|
||||
auto resp = HttpResponse::newHttpResponse();
|
||||
resp->setBody("<p>Hello, world!</p>");
|
||||
resp->setExpiredTime(0);
|
||||
callback(resp);
|
||||
}
|
||||
```
|
||||
|
||||
**Most of the above programs can be automatically generated by the command line tool `drogon_ctl` provided by drogon** (The command is `drogon_ctl create controller TestCtrl`). All the user needs to do is add their own business logic. In the example, the controller returns a `Hello, world!` string when the client accesses the `http://ip/test` URL.
|
||||
|
||||
For JSON format response, we create the controller as follows:
|
||||
|
||||
```c++
|
||||
/// The header file
|
||||
#pragma once
|
||||
#include <drogon/HttpSimpleController.h>
|
||||
using namespace drogon;
|
||||
class JsonCtrl : public drogon::HttpSimpleController<JsonCtrl>
|
||||
{
|
||||
public:
|
||||
void asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback) override;
|
||||
PATH_LIST_BEGIN
|
||||
//list path definitions here;
|
||||
PATH_ADD("/json", Get);
|
||||
PATH_LIST_END
|
||||
};
|
||||
|
||||
/// The source file
|
||||
#include "JsonCtrl.h"
|
||||
void JsonCtrl::asyncHandleHttpRequest(const HttpRequestPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback)
|
||||
{
|
||||
Json::Value ret;
|
||||
ret["message"] = "Hello, World!";
|
||||
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
||||
callback(resp);
|
||||
}
|
||||
```
|
||||
|
||||
Let's go a step further and create a demo RESTful API with the HttpController class, as shown below (Omit the source file):
|
||||
|
||||
```c++
|
||||
/// The header file
|
||||
#pragma once
|
||||
#include <drogon/HttpController.h>
|
||||
using namespace drogon;
|
||||
namespace api
|
||||
{
|
||||
namespace v1
|
||||
{
|
||||
class User : public drogon::HttpController<User>
|
||||
{
|
||||
public:
|
||||
METHOD_LIST_BEGIN
|
||||
//use METHOD_ADD to add your custom processing function here;
|
||||
METHOD_ADD(User::getInfo, "/{id}", Get); //path is /api/v1/User/{arg1}
|
||||
METHOD_ADD(User::getDetailInfo, "/{id}/detailinfo", Get); //path is /api/v1/User/{arg1}/detailinfo
|
||||
METHOD_ADD(User::newUser, "/{name}", Post); //path is /api/v1/User/{arg1}
|
||||
METHOD_LIST_END
|
||||
//your declaration of processing function maybe like this:
|
||||
void getInfo(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, int userId) const;
|
||||
void getDetailInfo(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, int userId) const;
|
||||
void newUser(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, std::string &&userName);
|
||||
public:
|
||||
User()
|
||||
{
|
||||
LOG_DEBUG << "User constructor!";
|
||||
}
|
||||
};
|
||||
} // namespace v1
|
||||
} // namespace api
|
||||
```
|
||||
|
||||
As you can see, users can use the `HttpController` to map paths and parameters at the same time. This is a very convenient way to create a RESTful API application.
|
||||
|
||||
In addition, you can also find that all handler interfaces are in asynchronous mode, where the response is returned by a callback object. This design is for performance reasons because in asynchronous mode the drogon application can handle a large number of concurrent requests with a small number of threads.
|
||||
|
||||
After compiling all of the above source files, we get a very simple web application. This is a good start. **For more information, please visit the [wiki](https://github.com/an-tao/drogon/wiki/ENG-01-Overview)**
|
||||
|
||||
## Cross-compilation
|
||||
|
||||
Drogon supports cross-compilation, you should define the `CMAKE_SYSTEM_NAME` in toolchain file, for example:
|
||||
|
||||
```cmake
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
```
|
||||
|
||||
You can disable building options for examples and drogon_ctl by settings `BUILD_EXAMPLES` and `BUILD_CTL` to `OFF` in the toolchain file.
|
||||
|
||||
## Building options
|
||||
|
||||
Drogon provides some building options, you can enable or disable them by setting the corresponding variables to `ON` or `OFF` in the cmake command line, cmake file etc...
|
||||
|
||||
| Option name | Description | Default value |
|
||||
| :--- | :--- | :--- |
|
||||
| BUILD_CTL | Build drogon_ctl | ON |
|
||||
| BUILD_EXAMPLES | Build examples | ON |
|
||||
| BUILD_ORM | Build orm | ON |
|
||||
| COZ_PROFILING | Use coz for profiling | OFF |
|
||||
| BUILD_SHARED_LIBS | Build drogon as a shared lib | OFF |
|
||||
| BUILD_DOC | Build Doxygen documentation | OFF |
|
||||
| BUILD_BROTLI | Build Brotli | ON |
|
||||
| BUILD_YAML_CONFIG | Build yaml config | ON |
|
||||
| USE_SUBMODULE | Use trantor as a submodule | ON |
|
||||
|
||||
|
||||
## Contributions
|
||||
|
||||
This project exists thanks to all the people who contribute code.
|
||||
|
||||
<a href="https://github.com/drogonframework/drogon/graphs/contributors"><img src="https://contributors-svg.opencollective.com/drogon/contributors.svg?width=890&button=false" alt="Code contributors" /></a>
|
||||
|
||||
Every contribution is welcome. Please refer to the [contribution guidelines](CONTRIBUTING.md) for more information.
|
297
vendors/api-server/config.yaml
vendored
Normal file
297
vendors/api-server/config.yaml
vendored
Normal file
@ -0,0 +1,297 @@
|
||||
# This is a YAML format configuration file
|
||||
|
||||
# ssl:The global SSL settings. "key" and "cert" are the path to the SSL key and certificate. While
|
||||
# "conf" is an array of 1 or 2-element tuples that supplies file style options for `SSL_CONF_cmd`.
|
||||
# ssl:
|
||||
# cert: ../../trantor/trantor/tests/server.pem
|
||||
# key: ../../trantor/trantor/tests/server.pem
|
||||
# conf: [
|
||||
# # [Options, -SessionTicket],
|
||||
# # [Options, Compression]
|
||||
# ]
|
||||
# listeners:
|
||||
# # address: Ip address,0.0.0.0 by default
|
||||
# - address: 0.0.0.0
|
||||
# # port: Port number
|
||||
# port: 80
|
||||
# # https: If true, use https for security,false by default
|
||||
# https: false
|
||||
# - address: 0.0.0.0
|
||||
# port: 443
|
||||
# https: true
|
||||
# # cert,key: Cert file path and key file path, empty by default,
|
||||
# # if empty, use the global setting
|
||||
# cert: ''
|
||||
# key: ''
|
||||
# # use_old_tls: enable the TLS1.0/1.1, false by default
|
||||
# use_old_tls: false
|
||||
# ssl_conf: [
|
||||
# # [MinProtocol, TLSv1.3]
|
||||
# ]
|
||||
# db_clients:
|
||||
# # name: Name of the client,'default' by default
|
||||
# - name: ''
|
||||
# # rdbms: Server type, postgresql,mysql or sqlite3, "postgresql" by default
|
||||
# rdbms: postgresql
|
||||
# # filename: Sqlite3 db file name
|
||||
# # filename: '',
|
||||
# # host: Server address,localhost by default
|
||||
# host: 127.0.0.1
|
||||
# # port: Server port, 5432 by default
|
||||
# port: 5432
|
||||
# # dbname: Database name
|
||||
# dbname: test
|
||||
# # user: 'postgres' by default
|
||||
# user: ''
|
||||
# # passwd: '' by default
|
||||
# passwd: ''
|
||||
# # is_fast: false by default, if it is true, the client is faster but user can't call
|
||||
# # any synchronous interface of it.
|
||||
# is_fast: false
|
||||
# # client_encoding: The character set used by the client. it is empty string by default which
|
||||
# # means use the default character set.
|
||||
# # client_encoding: '',
|
||||
# # number_of_connections: 1 by default, if the 'is_fast' is true, the number is the number of
|
||||
# # connections per IO thread, otherwise it is the total number of all connections.
|
||||
# number_of_connections: 1
|
||||
# # timeout: -1 by default, in seconds, the timeout for executing a SQL query.
|
||||
# # zero or negative value means no timeout.
|
||||
# timeout: -1
|
||||
# # "auto_batch": this feature is only available for the PostgreSQL driver(version >= 14.0), see
|
||||
# # the wiki for more details.
|
||||
# auto_batch: false
|
||||
# redis_clients:
|
||||
# # name: Name of the client,'default' by default
|
||||
# - name: ''
|
||||
# # host: Server IP, 127.0.0.1 by default
|
||||
# host: 127.0.0.1
|
||||
# # port: Server port, 6379 by default
|
||||
# port: 6379
|
||||
# # username: '' by default which means 'default' in redis ACL
|
||||
# username: ''
|
||||
# # passwd: '' by default
|
||||
# passwd: ''
|
||||
# # db index: 0 by default
|
||||
# db: 0
|
||||
# # is_fast: false by default, if it is true, the client is faster but user can't call
|
||||
# # any synchronous interface of it.
|
||||
# is_fast: false
|
||||
# # number_of_connections: 1 by default, if the 'is_fast' is true, the number is the number of
|
||||
# # connections per IO thread, otherwise it is the total number of all connections.
|
||||
# number_of_connections: 1
|
||||
# # timeout: -1.0 by default, in seconds, the timeout for executing a command.
|
||||
# # zero or negative value means no timeout.
|
||||
# timeout: -1
|
||||
app:
|
||||
# number_of_threads: The number of IO threads, 1 by default, if the value is set to 0, the number of threads
|
||||
# is the number of CPU cores
|
||||
number_of_threads: 1
|
||||
# enable_session: False by default
|
||||
enable_session: true
|
||||
session_timeout: 0
|
||||
# string value of SameSite attribute of the Set-Cookie HTTP respone header
|
||||
# valid value is either 'Null' (default), 'Lax', 'Strict' or 'None'
|
||||
session_same_site: 'Null'
|
||||
# session_cookie_key: The cookie key of the session, "JSESSIONID" by default
|
||||
session_cookie_key: 'JSESSIONID'
|
||||
# session_max_age: The max age of the session cookie, -1 by default
|
||||
session_max_age: -1
|
||||
# document_root: Root path of HTTP document, defaut path is ./
|
||||
document_root: ./
|
||||
# home_page: Set the HTML file of the home page, the default value is "index.html"
|
||||
# If there isn't any handler registered to the path "/", the home page file in the "document_root" is send to clients as a response
|
||||
# to the request for "/".
|
||||
home_page: index.html
|
||||
# use_implicit_page: enable implicit pages if true, true by default
|
||||
use_implicit_page: true
|
||||
# implicit_page: Set the file which would the server access in a directory that a user accessed.
|
||||
# For example, by default, http://localhost/a-directory resolves to http://localhost/a-directory/index.html.
|
||||
implicit_page: index.html
|
||||
# static_file_headers: Headers for static files
|
||||
# static_file_headers:
|
||||
# - name: field-name
|
||||
# value: field-value
|
||||
# upload_path: The path to save the uploaded file. "uploads" by default.
|
||||
# If the path isn't prefixed with /, ./ or ../,
|
||||
# it is relative path of document_root path
|
||||
upload_path: uploads
|
||||
# file_types:
|
||||
# HTTP download file types,The file types supported by drogon
|
||||
# by default are "html", "js", "css", "xml", "xsl", "txt", "svg",
|
||||
# "ttf", "otf", "woff2", "woff" , "eot", "png", "jpg", "jpeg",
|
||||
# "gif", "bmp", "ico", "icns", etc.
|
||||
file_types:
|
||||
- gif
|
||||
- png
|
||||
- jpg
|
||||
- js
|
||||
- css
|
||||
- html
|
||||
- ico
|
||||
- swf
|
||||
- xap
|
||||
- apk
|
||||
- cur
|
||||
- xml
|
||||
- webp
|
||||
# mime: A dictionary that extends the internal MIME type support. Maps extensions into new MIME types
|
||||
# note: This option only adds MIME to the sever. `file_types` above have to be set for the server to serve them.
|
||||
mime: {
|
||||
# text/markdown: md,
|
||||
# text/gemini: [gmi, gemini]
|
||||
}
|
||||
# locations: An array of locations of static files for GET requests.
|
||||
locations:
|
||||
# uri_prefix: The URI prefix of the location prefixed with "/", the default value is "" that disables the location.
|
||||
- uri_prefix: '' # /.well-known/acme-challenge/
|
||||
# default_content_type: The default content type of the static files without
|
||||
# an extension. empty string by default.
|
||||
default_content_type: text/plain
|
||||
# alias: The location in file system, if it is prefixed with "/", it
|
||||
# presents an absolute path, otherwise it presents a relative path to
|
||||
# the document_root path.
|
||||
# The default value is "" which means use the document root path as the location base path.
|
||||
alias: ''
|
||||
# is_case_sensitive: indicates whether the URI prefix is case sensitive.
|
||||
is_case_sensitive: false
|
||||
# allow_all: true by default. If it is set to false, only static files with a valid extension can be accessed.
|
||||
allow_all: true
|
||||
# is_recursive: true by default. If it is set to false, files in sub directories can't be accessed.
|
||||
is_recursive: true
|
||||
# filters: string array, the filters applied to the location.
|
||||
filters: []
|
||||
# max_connections: maximum number of connections, 100000 by default
|
||||
max_connections: 100000
|
||||
# max_connections_per_ip: maximum number of connections per clinet, 0 by default which means no limit
|
||||
max_connections_per_ip: 0
|
||||
# Load_dynamic_views: False by default, when set to true, drogon
|
||||
# compiles and loads dynamically "CSP View Files" in directories defined
|
||||
# by "dynamic_views_path"
|
||||
load_dynamic_views: false
|
||||
# dynamic_views_path: If the path isn't prefixed with /, ./ or ../,
|
||||
# it is relative path of document_root path
|
||||
dynamic_views_path:
|
||||
- ./views
|
||||
# dynamic_views_output_path: Default by an empty string which means the output path of source
|
||||
# files is the path where the csp files locate. If the path isn't prefixed with /, it is relative
|
||||
# path of the current working directory.
|
||||
dynamic_views_output_path: ''
|
||||
# json_parser_stack_limit: 1000 by default, the maximum number of stack depth when reading a json string by the jsoncpp library.
|
||||
json_parser_stack_limit: 1000
|
||||
# enable_unicode_escaping_in_json: true by default, enable unicode escaping in json.
|
||||
enable_unicode_escaping_in_json: true
|
||||
# float_precision_in_json: set precision of float number in json.
|
||||
float_precision_in_json:
|
||||
# precision: 0 by default, 0 means use the default precision of the jsoncpp lib.
|
||||
precision: 0
|
||||
# precision_type: must be "significant" or "decimal", defaults to "significant" that means
|
||||
# setting max number of significant digits in string, "decimal" means setting max number of
|
||||
# digits after "." in string
|
||||
precision_type: significant
|
||||
# log: Set log output, drogon output logs to stdout by default
|
||||
log:
|
||||
# use_spdlog: Use spdlog library to log
|
||||
use_spdlog: false,
|
||||
# log_path: Log file path,empty by default,in which case,logs are output to the stdout
|
||||
# log_path: ./
|
||||
# logfile_base_name: Log file base name,empty by default which means drogon names logfile as
|
||||
# drogon.log ...
|
||||
logfile_base_name: ''
|
||||
# log_size_limit: 100000000 bytes by default,
|
||||
# When the log file size reaches "log_size_limit", the log file is switched.
|
||||
log_size_limit: 100000000
|
||||
# log_level: "DEBUG" by default,options:"TRACE","DEBUG","INFO","WARN"
|
||||
# The TRACE level is only valid when built in DEBUG mode.
|
||||
log_level: DEBUG
|
||||
# display_local_time: false by default, if true, the log time is displayed in local time
|
||||
display_local_time: false
|
||||
# run_as_daemon: False by default
|
||||
run_as_daemon: false
|
||||
# handle_sig_term: True by default
|
||||
handle_sig_term: true
|
||||
# relaunch_on_error: False by default, if true, the program will be restart by the parent after exiting;
|
||||
relaunch_on_error: false
|
||||
# use_sendfile: True by default, if true, the program
|
||||
# uses sendfile() system-call to send static files to clients;
|
||||
use_sendfile: true
|
||||
# use_gzip: True by default, use gzip to compress the response body's content;
|
||||
use_gzip: true
|
||||
# use_brotli: False by default, use brotli to compress the response body's content;
|
||||
use_brotli: false
|
||||
# static_files_cache_time: 5 (seconds) by default, the time in which the static file response is cached,
|
||||
# 0 means cache forever, the negative value means no cache
|
||||
static_files_cache_time: 5
|
||||
# simple_controllers_map: Used to configure mapping from path to simple controller
|
||||
simple_controllers_map:
|
||||
- path: /path/name
|
||||
controller: controllerClassName
|
||||
http_methods:
|
||||
- get
|
||||
- post
|
||||
filters:
|
||||
- FilterClassName
|
||||
# idle_connection_timeout: Defaults to 60 seconds, the lifetime
|
||||
# of the connection without read or write
|
||||
idle_connection_timeout: 60
|
||||
# server_header_field: Set the 'Server' header field in each response sent by drogon,
|
||||
# empty string by default with which the 'Server' header field is set to "Server: drogon/version string\r\n"
|
||||
server_header_field: ''
|
||||
# enable_server_header: Set true to force drogon to add a 'Server' header to each HTTP response. The default
|
||||
# value is true.
|
||||
enable_server_header: true
|
||||
# enable_date_header: Set true to force drogon to add a 'Date' header to each HTTP response. The default
|
||||
# value is true.
|
||||
enable_date_header: true
|
||||
# keepalive_requests: Set the maximum number of requests that can be served through one keep-alive connection.
|
||||
# After the maximum number of requests are made, the connection is closed.
|
||||
# The default value of 0 means no limit.
|
||||
keepalive_requests: 0
|
||||
# pipelining_requests: Set the maximum number of unhandled requests that can be cached in pipelining buffer.
|
||||
# After the maximum number of requests are made, the connection is closed.
|
||||
# The default value of 0 means no limit.
|
||||
pipelining_requests: 0
|
||||
# gzip_static: If it is set to true, when the client requests a static file, drogon first finds the compressed
|
||||
# file with the extension ".gz" in the same path and send the compressed file to the client.
|
||||
# The default value of gzip_static is true.
|
||||
gzip_static: true
|
||||
# br_static: If it is set to true, when the client requests a static file, drogon first finds the compressed
|
||||
# file with the extension ".br" in the same path and send the compressed file to the client.
|
||||
# The default value of br_static is true.
|
||||
br_static: true
|
||||
# client_max_body_size: Set the maximum body size of HTTP requests received by drogon. The default value is "1M".
|
||||
# One can set it to "1024", "1k", "10M", "1G", etc. Setting it to "" means no limit.
|
||||
client_max_body_size: 1M
|
||||
# max_memory_body_size: Set the maximum body size in memory of HTTP requests received by drogon. The default value is "64K" bytes.
|
||||
# If the body size of a HTTP request exceeds this limit, the body is stored to a temporary file for processing.
|
||||
# Setting it to "" means no limit.
|
||||
client_max_memory_body_size: 64K
|
||||
# client_max_websocket_message_size: Set the maximum size of messages sent by WebSocket client. The default value is "128K".
|
||||
# One can set it to "1024", "1k", "10M", "1G", etc. Setting it to "" means no limit.
|
||||
client_max_websocket_message_size: 128K
|
||||
# reuse_port: Defaults to false, users can run multiple processes listening on the same port at the same time.
|
||||
reuse_port: false
|
||||
# enabled_compresed_request: Defaults to false. If true the server will automatically decompress compressed request bodies.
|
||||
# Currently only gzip and br are supported. Note: max_memory_body_size and max_body_size applies twice for compressed requests.
|
||||
# Once when receiving and once when decompressing. i.e. if the decompressed body is larger than max_body_size, the request
|
||||
# will be rejected.
|
||||
enabled_compresed_request: false
|
||||
# plugins: Define all plugins running in the application
|
||||
plugins:
|
||||
# name: The class name of the plugin
|
||||
- name: '' # drogon::plugin::SecureSSLRedirector
|
||||
# dependencies: Plugins that the plugin depends on. It can be commented out
|
||||
dependencies: []
|
||||
# config: The configuration of the plugin. This json object is the parameter to initialize the plugin.
|
||||
# It can be commented out
|
||||
config:
|
||||
ssl_redirect_exempt:
|
||||
- .*\.jpg
|
||||
secure_ssl_host: 'localhost:8849'
|
||||
# custom_config: custom configuration for users. This object can be get by the app().getCustomConfig() method.
|
||||
custom_config:
|
||||
realm: drogonRealm
|
||||
opaque: drogonOpaque
|
||||
credentials:
|
||||
- user: drogon
|
||||
password: dr0g0n
|
||||
|
4
vendors/api-server/controllers/README.md
vendored
Normal file
4
vendors/api-server/controllers/README.md
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
## A README.md placehodler
|
||||
|
||||
### License
|
||||
* GPL-3.0
|
345
vendors/api-server/example-config.json
vendored
Normal file
345
vendors/api-server/example-config.json
vendored
Normal file
@ -0,0 +1,345 @@
|
||||
/* This is a JSON format configuration file
|
||||
*/
|
||||
{
|
||||
/*
|
||||
//ssl:The global SSL settings. "key" and "cert" are the path to the SSL key and certificate. While
|
||||
// "conf" is an array of 1 or 2-element tuples that supplies file style options for `SSL_CONF_cmd`.
|
||||
"ssl": {
|
||||
"cert": "../../trantor/trantor/tests/server.crt",
|
||||
"key": "../../trantor/trantor/tests/server.key",
|
||||
"conf": [
|
||||
//["Options", "-SessionTicket"],
|
||||
//["Options", "Compression"]
|
||||
]
|
||||
},
|
||||
"listeners": [
|
||||
{
|
||||
//address: Ip address,0.0.0.0 by default
|
||||
"address": "0.0.0.0",
|
||||
//port: Port number
|
||||
"port": 80,
|
||||
//https: If true, use https for security,false by default
|
||||
"https": false
|
||||
},
|
||||
{
|
||||
"address": "0.0.0.0",
|
||||
"port": 443,
|
||||
"https": true,
|
||||
//cert,key: Cert file path and key file path, empty by default,
|
||||
//if empty, use the global setting
|
||||
"cert": "",
|
||||
"key": "",
|
||||
//use_old_tls: enable the TLS1.0/1.1, false by default
|
||||
"use_old_tls": false,
|
||||
"ssl_conf": [
|
||||
//["MinProtocol", "TLSv1.3"]
|
||||
]
|
||||
}
|
||||
],
|
||||
"db_clients": [
|
||||
{
|
||||
//name: Name of the client,'default' by default
|
||||
//"name":"",
|
||||
//rdbms: Server type, postgresql,mysql or sqlite3, "postgresql" by default
|
||||
"rdbms": "postgresql",
|
||||
//filename: Sqlite3 db file name
|
||||
//"filename":"",
|
||||
//host: Server address,localhost by default
|
||||
"host": "127.0.0.1",
|
||||
//port: Server port, 5432 by default
|
||||
"port": 5432,
|
||||
//dbname: Database name
|
||||
"dbname": "test",
|
||||
//user: 'postgres' by default
|
||||
"user": "",
|
||||
//passwd: '' by default
|
||||
"passwd": "",
|
||||
//is_fast: false by default, if it is true, the client is faster but user can't call
|
||||
//any synchronous interface of it.
|
||||
"is_fast": false,
|
||||
//client_encoding: The character set used by the client. it is empty string by default which
|
||||
//means use the default character set.
|
||||
//"client_encoding": "",
|
||||
//number_of_connections: 1 by default, if the 'is_fast' is true, the number is the number of
|
||||
//connections per IO thread, otherwise it is the total number of all connections.
|
||||
"number_of_connections": 1,
|
||||
//timeout: -1.0 by default, in seconds, the timeout for executing a SQL query.
|
||||
//zero or negative value means no timeout.
|
||||
"timeout": -1.0,
|
||||
//"auto_batch": this feature is only available for the PostgreSQL driver(version >= 14.0), see
|
||||
// the wiki for more details.
|
||||
"auto_batch": false
|
||||
}
|
||||
],
|
||||
"redis_clients": [
|
||||
{
|
||||
//name: Name of the client,'default' by default
|
||||
//"name":"",
|
||||
//host: Server IP, 127.0.0.1 by default
|
||||
"host": "127.0.0.1",
|
||||
//port: Server port, 6379 by default
|
||||
"port": 6379,
|
||||
//username: '' by default which means 'default' in redis ACL
|
||||
"username": "",
|
||||
//passwd: '' by default
|
||||
"passwd": "",
|
||||
//db index: 0 by default
|
||||
"db": 0,
|
||||
//is_fast: false by default, if it is true, the client is faster but user can't call
|
||||
//any synchronous interface of it.
|
||||
"is_fast": false,
|
||||
//number_of_connections: 1 by default, if the 'is_fast' is true, the number is the number of
|
||||
//connections per IO thread, otherwise it is the total number of all connections.
|
||||
"number_of_connections": 1,
|
||||
//timeout: -1.0 by default, in seconds, the timeout for executing a command.
|
||||
//zero or negative value means no timeout.
|
||||
"timeout": -1.0
|
||||
}
|
||||
],*/
|
||||
"app": {
|
||||
//number_of_threads: The number of IO threads, 1 by default, if the value is set to 0, the number of threads
|
||||
//is the number of CPU cores
|
||||
"number_of_threads": 1,
|
||||
//enable_session: False by default
|
||||
"enable_session": false,
|
||||
"session_timeout": 0,
|
||||
//string value of SameSite attribute of the Set-Cookie HTTP respone header
|
||||
//valid value is either 'Null' (default), 'Lax', 'Strict' or 'None'
|
||||
"session_same_site" : "Null",
|
||||
//session_cookie_key: The cookie key of the session, "JSESSIONID" by default
|
||||
"session_cookie_key": "JSESSIONID",
|
||||
//session_max_age: The max age of the session cookie, -1 by default
|
||||
"session_max_age": -1,
|
||||
//document_root: Root path of HTTP document, defaut path is ./
|
||||
"document_root": "./",
|
||||
//home_page: Set the HTML file of the home page, the default value is "index.html"
|
||||
//If there isn't any handler registered to the path "/", the home page file in the "document_root" is send to clients as a response
|
||||
//to the request for "/".
|
||||
"home_page": "index.html",
|
||||
//use_implicit_page: enable implicit pages if true, true by default
|
||||
"use_implicit_page": true,
|
||||
//implicit_page: Set the file which would the server access in a directory that a user accessed.
|
||||
//For example, by default, http://localhost/a-directory resolves to http://localhost/a-directory/index.html.
|
||||
"implicit_page": "index.html",
|
||||
//static_file_headers: Headers for static files
|
||||
/*"static_file_headers": [
|
||||
{
|
||||
"name": "field-name",
|
||||
"value": "field-value"
|
||||
}
|
||||
],*/
|
||||
//upload_path: The path to save the uploaded file. "uploads" by default.
|
||||
//If the path isn't prefixed with /, ./ or ../,
|
||||
//it is relative path of document_root path
|
||||
"upload_path": "uploads",
|
||||
/* file_types:
|
||||
* HTTP download file types,The file types supported by drogon
|
||||
* by default are "html", "js", "css", "xml", "xsl", "txt", "svg",
|
||||
* "ttf", "otf", "woff2", "woff" , "eot", "png", "jpg", "jpeg",
|
||||
* "gif", "bmp", "ico", "icns", etc. */
|
||||
"file_types": [
|
||||
"gif",
|
||||
"png",
|
||||
"jpg",
|
||||
"js",
|
||||
"css",
|
||||
"html",
|
||||
"ico",
|
||||
"swf",
|
||||
"xap",
|
||||
"apk",
|
||||
"cur",
|
||||
"xml",
|
||||
"webp",
|
||||
"svg"
|
||||
],
|
||||
// mime: A dictionary that extends the internal MIME type support. Maps extensions into new MIME types
|
||||
// note: This option only adds MIME to the sever. `file_types` above have to be set for the server to serve them.
|
||||
"mime": {
|
||||
// "text/markdown": "md",
|
||||
// "text/gemini": ["gmi", "gemini"]
|
||||
},
|
||||
//locations: An array of locations of static files for GET requests.
|
||||
"locations": [
|
||||
{
|
||||
//uri_prefix: The URI prefix of the location prefixed with "/", the default value is "" that disables the location.
|
||||
//"uri_prefix": "/.well-known/acme-challenge/",
|
||||
//default_content_type: The default content type of the static files without
|
||||
//an extension. empty string by default.
|
||||
"default_content_type": "text/plain",
|
||||
//alias: The location in file system, if it is prefixed with "/", it
|
||||
//presents an absolute path, otherwise it presents a relative path to
|
||||
//the document_root path.
|
||||
//The default value is "" which means use the document root path as the location base path.
|
||||
"alias": "",
|
||||
//is_case_sensitive: indicates whether the URI prefix is case sensitive.
|
||||
"is_case_sensitive": false,
|
||||
//allow_all: true by default. If it is set to false, only static files with a valid extension can be accessed.
|
||||
"allow_all": true,
|
||||
//is_recursive: true by default. If it is set to false, files in sub directories can't be accessed.
|
||||
"is_recursive": true,
|
||||
//filters: string array, the filters applied to the location.
|
||||
"filters": []
|
||||
}
|
||||
],
|
||||
//max_connections: maximum number of connections, 100000 by default
|
||||
"max_connections": 100000,
|
||||
//max_connections_per_ip: maximum number of connections per clinet, 0 by default which means no limit
|
||||
"max_connections_per_ip": 0,
|
||||
//Load_dynamic_views: False by default, when set to true, drogon
|
||||
//compiles and loads dynamically "CSP View Files" in directories defined
|
||||
//by "dynamic_views_path"
|
||||
"load_dynamic_views": false,
|
||||
//dynamic_views_path: If the path isn't prefixed with /, ./ or ../,
|
||||
//it is relative path of document_root path
|
||||
"dynamic_views_path": [
|
||||
"./views"
|
||||
],
|
||||
//dynamic_views_output_path: Default by an empty string which means the output path of source
|
||||
//files is the path where the csp files locate. If the path isn't prefixed with /, it is relative
|
||||
//path of the current working directory.
|
||||
"dynamic_views_output_path": "",
|
||||
//json_parser_stack_limit: 1000 by default, the maximum number of stack depth when reading a json string by the jsoncpp library.
|
||||
"json_parser_stack_limit": 1000,
|
||||
//enable_unicode_escaping_in_json: true by default, enable unicode escaping in json.
|
||||
"enable_unicode_escaping_in_json": true,
|
||||
//float_precision_in_json: set precision of float number in json.
|
||||
"float_precision_in_json": {
|
||||
//precision: 0 by default, 0 means use the default precision of the jsoncpp lib.
|
||||
"precision": 0,
|
||||
//precision_type: must be "significant" or "decimal", defaults to "significant" that means
|
||||
//setting max number of significant digits in string, "decimal" means setting max number of
|
||||
//digits after "." in string
|
||||
"precision_type": "significant"
|
||||
},
|
||||
//log: Set log output, drogon output logs to stdout by default
|
||||
"log": {
|
||||
//use_spdlog: Use spdlog library to log
|
||||
//"use_spdlog": false
|
||||
"use_spdlog": false,
|
||||
//log_path: Log file path,empty by default,in which case,logs are output to the stdout
|
||||
//"log_path": "./",
|
||||
//logfile_base_name: Log file base name,empty by default which means drogon names logfile as
|
||||
//drogon.log ...
|
||||
"logfile_base_name": "",
|
||||
//log_size_limit: 100000000 bytes by default,
|
||||
//When the log file size reaches "log_size_limit", the log file is switched.
|
||||
"log_size_limit": 100000000,
|
||||
//max_files: 0 by default,
|
||||
//When the number of old log files exceeds "max_files", the oldest file will be deleted. 0 means never delete.
|
||||
"max_files": 0,
|
||||
//log_level: "DEBUG" by default,options:"TRACE","DEBUG","INFO","WARN"
|
||||
//The TRACE level is only valid when built in DEBUG mode.
|
||||
"log_level": "DEBUG",
|
||||
//display_local_time: false by default, if true, the log time is displayed in local time
|
||||
"display_local_time": false
|
||||
},
|
||||
//run_as_daemon: False by default
|
||||
"run_as_daemon": false,
|
||||
//handle_sig_term: True by default
|
||||
"handle_sig_term": true,
|
||||
//relaunch_on_error: False by default, if true, the program will be restart by the parent after exiting;
|
||||
"relaunch_on_error": false,
|
||||
//use_sendfile: True by default, if true, the program
|
||||
//uses sendfile() system-call to send static files to clients;
|
||||
"use_sendfile": true,
|
||||
//use_gzip: True by default, use gzip to compress the response body's content;
|
||||
"use_gzip": true,
|
||||
//use_brotli: False by default, use brotli to compress the response body's content;
|
||||
"use_brotli": false,
|
||||
//static_files_cache_time: 5 (seconds) by default, the time in which the static file response is cached,
|
||||
//0 means cache forever, the negative value means no cache
|
||||
"static_files_cache_time": 5,
|
||||
//simple_controllers_map: Used to configure mapping from path to simple controller
|
||||
//"simple_controllers_map": [
|
||||
// {
|
||||
// "path": "/path/name",
|
||||
// "controller": "controllerClassName",
|
||||
// "http_methods": [
|
||||
// "get",
|
||||
// "post"
|
||||
// ],
|
||||
// "filters": [
|
||||
// "FilterClassName"
|
||||
// ]
|
||||
// }
|
||||
//],
|
||||
//idle_connection_timeout: Defaults to 60 seconds, the lifetime
|
||||
//of the connection without read or write
|
||||
"idle_connection_timeout": 60,
|
||||
//server_header_field: Set the 'Server' header field in each response sent by drogon,
|
||||
//empty string by default with which the 'Server' header field is set to "Server: drogon/version string\r\n"
|
||||
"server_header_field": "",
|
||||
//enable_server_header: Set true to force drogon to add a 'Server' header to each HTTP response. The default
|
||||
//value is true.
|
||||
"enable_server_header": true,
|
||||
//enable_date_header: Set true to force drogon to add a 'Date' header to each HTTP response. The default
|
||||
//value is true.
|
||||
"enable_date_header": true,
|
||||
//keepalive_requests: Set the maximum number of requests that can be served through one keep-alive connection.
|
||||
//After the maximum number of requests are made, the connection is closed.
|
||||
//The default value of 0 means no limit.
|
||||
"keepalive_requests": 0,
|
||||
//pipelining_requests: Set the maximum number of unhandled requests that can be cached in pipelining buffer.
|
||||
//After the maximum number of requests are made, the connection is closed.
|
||||
//The default value of 0 means no limit.
|
||||
"pipelining_requests": 0,
|
||||
//gzip_static: If it is set to true, when the client requests a static file, drogon first finds the compressed
|
||||
//file with the extension ".gz" in the same path and send the compressed file to the client.
|
||||
//The default value of gzip_static is true.
|
||||
"gzip_static": true,
|
||||
//br_static: If it is set to true, when the client requests a static file, drogon first finds the compressed
|
||||
//file with the extension ".br" in the same path and send the compressed file to the client.
|
||||
//The default value of br_static is true.
|
||||
"br_static": true,
|
||||
//client_max_body_size: Set the maximum body size of HTTP requests received by drogon. The default value is "1M".
|
||||
//One can set it to "1024", "1k", "10M", "1G", etc. Setting it to "" means no limit.
|
||||
"client_max_body_size": "1M",
|
||||
//max_memory_body_size: Set the maximum body size in memory of HTTP requests received by drogon. The default value is "64K" bytes.
|
||||
//If the body size of a HTTP request exceeds this limit, the body is stored to a temporary file for processing.
|
||||
//Setting it to "" means no limit.
|
||||
"client_max_memory_body_size": "64K",
|
||||
//client_max_websocket_message_size: Set the maximum size of messages sent by WebSocket client. The default value is "128K".
|
||||
//One can set it to "1024", "1k", "10M", "1G", etc. Setting it to "" means no limit.
|
||||
"client_max_websocket_message_size": "128K",
|
||||
//reuse_port: Defaults to false, users can run multiple processes listening on the same port at the same time.
|
||||
"reuse_port": false,
|
||||
// enabled_compressed_request: Defaults to false. If true the server will automatically decompress compressed request bodies.
|
||||
// Currently only gzip and br are supported. Note: max_memory_body_size and max_body_size applies twice for compressed requests.
|
||||
// Once when receiving and once when decompressing. i.e. if the decompressed body is larger than max_body_size, the request
|
||||
// will be rejected.
|
||||
"enabled_compressed_request": false
|
||||
},
|
||||
//plugins: Define all plugins running in the application
|
||||
"plugins": [
|
||||
{
|
||||
//name: The class name of the plugin
|
||||
"name": "drogon::plugin::PromExporter",
|
||||
//dependencies: Plugins that the plugin depends on. It can be commented out
|
||||
"dependencies": [],
|
||||
//config: The configuration of the plugin. This json object is the parameter to initialize the plugin.
|
||||
//It can be commented out
|
||||
"config": {
|
||||
"path": "/metrics"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "drogon::plugin::AccessLogger",
|
||||
"dependencies": [],
|
||||
"config": {
|
||||
"use_spdlog": false,
|
||||
"log_path": "",
|
||||
"log_format": "",
|
||||
"log_file": "access.log",
|
||||
"log_size_limit": 0,
|
||||
"use_local_time": true,
|
||||
"log_index": 0,
|
||||
// "show_microseconds": true,
|
||||
// "custom_time_format": "",
|
||||
// "use_real_ip": false
|
||||
}
|
||||
}
|
||||
],
|
||||
//custom_config: custom configuration for users. This object can be get by the app().getCustomConfig() method.
|
||||
"custom_config": {}
|
||||
}
|
4
vendors/api-server/filters/README.md
vendored
Normal file
4
vendors/api-server/filters/README.md
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
## A README.md placehodler
|
||||
|
||||
### License
|
||||
* GPL-3.0
|
1
vendors/api-server/index.html
vendored
Normal file
1
vendors/api-server/index.html
vendored
Normal file
@ -0,0 +1 @@
|
||||
<h1>Howdy Do World!</h1>
|
215
vendors/api-server/main.cc
vendored
Normal file
215
vendors/api-server/main.cc
vendored
Normal file
@ -0,0 +1,215 @@
|
||||
// https://github.com/drogonframework/drogon/blob/master/examples/jsonstore/README.md
|
||||
#include <drogon/drogon.h>
|
||||
|
||||
using namespace drogon;
|
||||
|
||||
HttpResponsePtr makeFailedResponse()
|
||||
{
|
||||
Json::Value json;
|
||||
json["ok"] = false;
|
||||
auto resp = HttpResponse::newHttpJsonResponse(json);
|
||||
resp->setStatusCode(k500InternalServerError);
|
||||
return resp;
|
||||
}
|
||||
|
||||
HttpResponsePtr makeSuccessResponse()
|
||||
{
|
||||
Json::Value json;
|
||||
json["ok"] = true;
|
||||
auto resp = HttpResponse::newHttpJsonResponse(json);
|
||||
return resp;
|
||||
}
|
||||
|
||||
std::string getRandomString(size_t n)
|
||||
{
|
||||
std::vector<unsigned char> random(n);
|
||||
utils::secureRandomBytes(random.data(), random.size());
|
||||
|
||||
// This is cryptographically safe as 256 mod 16 == 0
|
||||
static const std::string alphabets = "0123456789abcdef";
|
||||
assert(256 % alphabets.size() == 0);
|
||||
std::string randomString(n, '\0');
|
||||
for (size_t i = 0; i < n; i++)
|
||||
randomString[i] = alphabets[random[i] % alphabets.size()];
|
||||
return randomString;
|
||||
}
|
||||
|
||||
struct DataItem
|
||||
{
|
||||
Json::Value item;
|
||||
std::mutex mtx;
|
||||
};
|
||||
|
||||
class JsonStore : public HttpController<JsonStore>
|
||||
{
|
||||
public:
|
||||
METHOD_LIST_BEGIN
|
||||
ADD_METHOD_TO(JsonStore::getToken, "/get-token", Get);
|
||||
ADD_METHOD_VIA_REGEX(JsonStore::getItem, "/([a-f0-9]{64})/(.*)", Get);
|
||||
ADD_METHOD_VIA_REGEX(JsonStore::createItem, "/([a-f0-9]{64})", Post);
|
||||
ADD_METHOD_VIA_REGEX(JsonStore::deleteItem, "/([a-f0-9]{64})", Delete);
|
||||
ADD_METHOD_VIA_REGEX(JsonStore::updateItem, "/([a-f0-9]{64})/(.*)", Put);
|
||||
METHOD_LIST_END
|
||||
|
||||
void getToken(const HttpRequestPtr &,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback)
|
||||
{
|
||||
std::string randomString = getRandomString(64);
|
||||
Json::Value res;
|
||||
res["token"] = randomString;
|
||||
|
||||
callback(HttpResponse::newHttpJsonResponse(std::move(res)));
|
||||
}
|
||||
|
||||
void getItem(const HttpRequestPtr &,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||
const std::string &token,
|
||||
const std::string &path)
|
||||
{
|
||||
auto itemPtr = [this, &token]() -> std::shared_ptr<DataItem> {
|
||||
// It is possible that the item is being removed while another
|
||||
// thread tries to look it up. The mutex here prevents that from
|
||||
// happening.
|
||||
std::lock_guard<std::mutex> lock(storageMtx_);
|
||||
auto it = dataStore_.find(token);
|
||||
if (it == dataStore_.end())
|
||||
return nullptr;
|
||||
return it->second;
|
||||
}();
|
||||
if (itemPtr == nullptr)
|
||||
{
|
||||
callback(makeFailedResponse());
|
||||
return;
|
||||
}
|
||||
|
||||
auto &item = *itemPtr;
|
||||
// Prevents another thread from writing to the same item while this
|
||||
// thread reads. Could cause blockage if multiple clients are asking to
|
||||
// read the same object. But that should be rare.
|
||||
std::lock_guard<std::mutex> lock(item.mtx);
|
||||
Json::Value *valuePtr = walkJson(item.item, path);
|
||||
|
||||
if (valuePtr == nullptr)
|
||||
{
|
||||
callback(makeFailedResponse());
|
||||
return;
|
||||
}
|
||||
|
||||
auto resp = HttpResponse::newHttpJsonResponse(*valuePtr);
|
||||
callback(resp);
|
||||
}
|
||||
|
||||
void updateItem(const HttpRequestPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||
const std::string &token,
|
||||
const std::string &path)
|
||||
{
|
||||
auto jsonPtr = req->jsonObject();
|
||||
auto itemPtr = [this, &token]() -> std::shared_ptr<DataItem> {
|
||||
// It is possible that the item is being removed while another
|
||||
// thread tries to look it up. The mutex here prevents that from
|
||||
// happening.
|
||||
std::lock_guard<std::mutex> lock(storageMtx_);
|
||||
auto it = dataStore_.find(token);
|
||||
if (it == dataStore_.end())
|
||||
return nullptr;
|
||||
return it->second;
|
||||
}();
|
||||
|
||||
if (itemPtr == nullptr || jsonPtr == nullptr)
|
||||
{
|
||||
callback(makeFailedResponse());
|
||||
return;
|
||||
}
|
||||
|
||||
auto &item = *itemPtr;
|
||||
std::lock_guard<std::mutex> lock(item.mtx);
|
||||
Json::Value *valuePtr = walkJson(item.item, path, 1);
|
||||
|
||||
if (valuePtr == nullptr)
|
||||
{
|
||||
callback(makeFailedResponse());
|
||||
return;
|
||||
}
|
||||
|
||||
std::string key = utils::splitString(path, "/").back();
|
||||
(*valuePtr)[key] = *jsonPtr;
|
||||
|
||||
callback(makeSuccessResponse());
|
||||
}
|
||||
|
||||
void createItem(const HttpRequestPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||
const std::string &token)
|
||||
{
|
||||
auto jsonPtr = req->jsonObject();
|
||||
if (jsonPtr == nullptr)
|
||||
{
|
||||
callback(makeFailedResponse());
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(storageMtx_);
|
||||
if (dataStore_.find(token) == dataStore_.end())
|
||||
{
|
||||
auto item = std::make_shared<DataItem>();
|
||||
item->item = std::move(*jsonPtr);
|
||||
dataStore_.insert({token, std::move(item)});
|
||||
|
||||
callback(makeSuccessResponse());
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(makeFailedResponse());
|
||||
}
|
||||
}
|
||||
|
||||
void deleteItem(const HttpRequestPtr &,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||
const std::string &token)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(storageMtx_);
|
||||
dataStore_.erase(token);
|
||||
|
||||
callback(makeSuccessResponse());
|
||||
}
|
||||
|
||||
protected:
|
||||
static Json::Value *walkJson(Json::Value &json,
|
||||
const std::string &path,
|
||||
size_t ignore_back = 0)
|
||||
{
|
||||
auto pathElem = utils::splitString(path, "/", false);
|
||||
if (pathElem.size() >= ignore_back)
|
||||
pathElem.resize(pathElem.size() - ignore_back);
|
||||
Json::Value *valuePtr = &json;
|
||||
for (const auto &elem : pathElem)
|
||||
{
|
||||
if (valuePtr->isArray())
|
||||
{
|
||||
Json::Value &value = (*valuePtr)[std::stoi(elem)];
|
||||
if (value.isNull())
|
||||
return nullptr;
|
||||
|
||||
valuePtr = &value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Json::Value &value = (*valuePtr)[elem];
|
||||
if (value.isNull())
|
||||
return nullptr;
|
||||
|
||||
valuePtr = &value;
|
||||
}
|
||||
}
|
||||
return valuePtr;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<DataItem>> dataStore_;
|
||||
std::mutex storageMtx_;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
app().addListener("127.0.0.1", 8848).run();
|
||||
}
|
104
vendors/api-server/models/model.json
vendored
Normal file
104
vendors/api-server/models/model.json
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
{
|
||||
//rdbms: server type, postgresql,mysql or sqlite3
|
||||
"rdbms": "postgresql",
|
||||
//filename: sqlite3 db file name
|
||||
//"filename":"",
|
||||
//host: server address,localhost by default;
|
||||
"host": "127.0.0.1",
|
||||
//port: server port, 5432 by default;
|
||||
"port": 5432,
|
||||
//dbname: Database name;
|
||||
"dbname": "drogoncmsdb",
|
||||
//schema: valid for postgreSQL, "public" by default;
|
||||
"schema": "public",
|
||||
//user: User name
|
||||
"user": "",
|
||||
//password or passwd: Password
|
||||
"password": "",
|
||||
//client_encoding: The character set used by drogon_ctl. it is empty string by default which
|
||||
//means use the default character set.
|
||||
//"client_encoding": "",
|
||||
//table: An array of tables to be modelized. if the array is empty, all revealed tables are modelized.
|
||||
"tables": [],
|
||||
//convert: the value can be changed by a function call before it is stored into database or
|
||||
//after it is read from database
|
||||
"convert": {
|
||||
"enabled": false,
|
||||
"items":[{
|
||||
"table": "user",
|
||||
"column": "password",
|
||||
"method": {
|
||||
//after_db_read: name of the method which is called after reading from database, signature: void([const] std::shared_ptr [&])
|
||||
"after_db_read": "decrypt_password",
|
||||
//before_db_write: name of the method which is called before writing to database, signature: void([const] std::shared_ptr [&])
|
||||
"before_db_write": "encrypt_password"
|
||||
},
|
||||
"includes": [
|
||||
"\"file_local_search_path.h\"","<file_in_global_search_path.h>"
|
||||
]
|
||||
}]
|
||||
},
|
||||
"relationships": {
|
||||
"enabled": false,
|
||||
"items": [{
|
||||
"type": "has one",
|
||||
"original_table_name": "products",
|
||||
"original_table_alias": "product",
|
||||
"original_key": "id",
|
||||
"target_table_name": "skus",
|
||||
"target_table_alias": "SKU",
|
||||
"target_key": "product_id",
|
||||
"enable_reverse": true
|
||||
},
|
||||
{
|
||||
"type": "has many",
|
||||
"original_table_name": "products",
|
||||
"original_table_alias": "product",
|
||||
"original_key": "id",
|
||||
"target_table_name": "reviews",
|
||||
"target_table_alias": "",
|
||||
"target_key": "product_id",
|
||||
"enable_reverse": true
|
||||
},
|
||||
{
|
||||
"type": "many to many",
|
||||
"original_table_name": "products",
|
||||
"original_table_alias": "",
|
||||
"original_key": "id",
|
||||
"pivot_table": {
|
||||
"table_name": "carts_products",
|
||||
"original_key": "product_id",
|
||||
"target_key": "cart_id"
|
||||
},
|
||||
"target_table_name": "carts",
|
||||
"target_table_alias": "",
|
||||
"target_key": "id",
|
||||
"enable_reverse": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"restful_api_controllers": {
|
||||
"enabled": false,
|
||||
// resource_uri: The URI to access the resource, the default value
|
||||
// is '/*' in which the asterisk represents the table name.
|
||||
// If this option is set to a empty string, the URI is composed of the namespaces and the class name.
|
||||
"resource_uri": "/*",
|
||||
// class_name: "Restful*Ctrl" by default, the asterisk represents the table name.
|
||||
// This option can contain namespaces.
|
||||
"class_name": "Restful*Ctrl",
|
||||
// filters: an array of filter names.
|
||||
"filters": [],
|
||||
// db_client: the database client used by the controller. this option must be consistent with
|
||||
// the configuration of the application.
|
||||
"db_client": {
|
||||
//name: Name of the client,'default' by default
|
||||
"name": "default",
|
||||
//is_fast:
|
||||
"is_fast": false
|
||||
},
|
||||
// directory: The directory where the controller source files are stored.
|
||||
"directory": "controllers",
|
||||
// generate_base_only: false by default. Set to true to avoid overwriting custom subclasses.
|
||||
"generate_base_only": false
|
||||
}
|
||||
}
|
4
vendors/api-server/plugins/README.md
vendored
Normal file
4
vendors/api-server/plugins/README.md
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
## A README.md placehodler
|
||||
|
||||
### License
|
||||
* GPL-3.0
|
14
vendors/api-server/test/CMakeLists.txt
vendored
Normal file
14
vendors/api-server/test/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(local-server_test CXX)
|
||||
|
||||
add_executable(${PROJECT_NAME} test_main.cc)
|
||||
|
||||
# ##############################################################################
|
||||
# If you include the drogon source code locally in your project, use this method
|
||||
# to add drogon
|
||||
# target_link_libraries(${PROJECT_NAME} PRIVATE drogon)
|
||||
#
|
||||
# and comment out the following lines
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Drogon::Drogon)
|
||||
|
||||
ParseAndAddDrogonTests(${PROJECT_NAME})
|
32
vendors/api-server/test/test_main.cc
vendored
Normal file
32
vendors/api-server/test/test_main.cc
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
#define DROGON_TEST_MAIN
|
||||
#include <drogon/drogon_test.h>
|
||||
#include <drogon/drogon.h>
|
||||
|
||||
DROGON_TEST(BasicTest)
|
||||
{
|
||||
// Add your tests here
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
using namespace drogon;
|
||||
|
||||
std::promise<void> p1;
|
||||
std::future<void> f1 = p1.get_future();
|
||||
|
||||
// Start the main loop on another thread
|
||||
std::thread thr([&]() {
|
||||
// Queues the promise to be fulfilled after starting the loop
|
||||
app().getLoop()->queueInLoop([&p1]() { p1.set_value(); });
|
||||
app().run();
|
||||
});
|
||||
|
||||
// The future is only satisfied after the event loop started
|
||||
f1.get();
|
||||
int status = test::run(argc, argv);
|
||||
|
||||
// Ask the event loop to shutdown and wait
|
||||
app().getLoop()->queueInLoop([]() { app().quit(); });
|
||||
thr.join();
|
||||
return status;
|
||||
}
|
4
vendors/api-server/views/README.md
vendored
Normal file
4
vendors/api-server/views/README.md
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
## A README.md placehodler
|
||||
|
||||
### License
|
||||
* GPL-3.0
|
1161
vendors/cmake/CPM_0.38.7.cmake
vendored
Normal file
1161
vendors/cmake/CPM_0.38.7.cmake
vendored
Normal file
File diff suppressed because it is too large
Load Diff
24
vendors/cmake/cpm/get_cpm.cmake
vendored
Normal file
24
vendors/cmake/cpm/get_cpm.cmake
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors
|
||||
|
||||
set(CPM_DOWNLOAD_VERSION 0.38.7)
|
||||
set(CPM_HASH_SUM "83e5eb71b2bbb8b1f2ad38f1950287a057624e385c238f6087f94cdfc44af9c5")
|
||||
|
||||
if(CPM_SOURCE_CACHE)
|
||||
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
|
||||
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
|
||||
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
|
||||
else()
|
||||
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
|
||||
endif()
|
||||
|
||||
# Expand relative path. This is important if the provided path contains a tilde (~)
|
||||
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
|
||||
|
||||
file(DOWNLOAD
|
||||
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
|
||||
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
|
||||
)
|
||||
|
||||
include(${CPM_DOWNLOAD_LOCATION})
|
36
vendors/simple-reverse-proxy/.gitignore
vendored
Normal file
36
vendors/simple-reverse-proxy/.gitignore
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
build
|
||||
cmake-build-debug
|
||||
.idea
|
56
vendors/simple-reverse-proxy/CMakeLists.txt
vendored
Normal file
56
vendors/simple-reverse-proxy/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
cmake_minimum_required (VERSION 3.5)
|
||||
project(DrogonCMS_Reverse_Proxy CXX)
|
||||
|
||||
include(CheckIncludeFileCXX)
|
||||
|
||||
check_include_file_cxx(any HAS_ANY)
|
||||
check_include_file_cxx(string_view HAS_STRING_VIEW)
|
||||
if(HAS_ANY AND HAS_STRING_VIEW)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
else()
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
add_executable(DrogonCMS_Reverse_Proxy main.cc)
|
||||
|
||||
##########
|
||||
# If you include the drogon source code locally in your project, use this method to add drogon
|
||||
# add_subdirectory(drogon)
|
||||
# target_link_libraries(simple_reverse_proxy PRIVATE drogon)
|
||||
##########
|
||||
|
||||
find_package(Drogon CONFIG REQUIRED)
|
||||
target_link_libraries(DrogonCMS_Reverse_Proxy PRIVATE Drogon::Drogon)
|
||||
|
||||
if(CMAKE_CXX_STANDARD LESS 17)
|
||||
#With C++14, use boost to support any and string_view
|
||||
message(STATUS "use c++14")
|
||||
find_package(Boost 1.61.0 REQUIRED)
|
||||
target_include_directories(DrogonCMS_Reverse_Proxy PRIVATE ${Boost_INCLUDE_DIRS})
|
||||
else()
|
||||
message(STATUS "use c++17")
|
||||
endif()
|
||||
|
||||
aux_source_directory(controllers CTL_SRC)
|
||||
aux_source_directory(filters FILTER_SRC)
|
||||
aux_source_directory(plugins PLUGIN_SRC)
|
||||
aux_source_directory(models MODEL_SRC)
|
||||
|
||||
file(GLOB SCP_LIST ${CMAKE_CURRENT_SOURCE_DIR}/views/*.csp)
|
||||
foreach(cspFile ${SCP_LIST})
|
||||
message(STATUS "cspFile:" ${cspFile})
|
||||
EXEC_PROGRAM(basename ARGS "${cspFile} .csp" OUTPUT_VARIABLE classname)
|
||||
message(STATUS "view classname:" ${classname})
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${classname}.h ${classname}.cc
|
||||
COMMAND drogon_ctl
|
||||
ARGS create view ${cspFile}
|
||||
DEPENDS ${cspFile}
|
||||
VERBATIM )
|
||||
set(VIEWSRC ${VIEWSRC} ${classname}.cc)
|
||||
endforeach()
|
||||
|
||||
target_include_directories(DrogonCMS_Reverse_Proxy PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/models)
|
||||
target_sources(DrogonCMS_Reverse_Proxy PRIVATE ${SRC_DIR} ${CTL_SRC} ${FILTER_SRC} ${VIEWSRC} ${PLUGIN_SRC} ${MODEL_SRC})
|
3
vendors/simple-reverse-proxy/README.md
vendored
Normal file
3
vendors/simple-reverse-proxy/README.md
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
### An example that shows how to use drogon as an http reverse proxy with a simple round robin.
|
||||
|
||||
This project is created with the drogon_ctl command, please compile it after installing drogon.
|
160
vendors/simple-reverse-proxy/config.json
vendored
Normal file
160
vendors/simple-reverse-proxy/config.json
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
/* This is a JSON format configuration file
|
||||
*/
|
||||
{
|
||||
/*
|
||||
//ssl: The global ssl files setting
|
||||
"ssl": {
|
||||
"cert": "../../trantor/trantor/tests/server.crt",
|
||||
"key": "../../trantor/trantor/tests/server.key"
|
||||
},*/
|
||||
"listeners": [{
|
||||
//address: Ip address,0.0.0.0 by default
|
||||
"address": "0.0.0.0",
|
||||
//port: Port number
|
||||
"port": 8088,
|
||||
//https: If true, use https for security, false by default
|
||||
"https": false
|
||||
}],
|
||||
"app": {
|
||||
//threads_num: The number of IO threads, 1 by default, if the value is set to 0, the number of threads
|
||||
//is the number of CPU cores
|
||||
"threads_num": 4,
|
||||
//enable_session: False by default
|
||||
"enable_session": false,
|
||||
"session_timeout": 0,
|
||||
//session_cookie_key: The cookie key of the session, "JSESSIONID" by default
|
||||
"session_cookie_key": "JSESSIONID",
|
||||
//session_max_age: The max age of the session cookie, -1 by default
|
||||
"session_max_age": -1,
|
||||
//document_root: Root path of HTTP document, default path is ./
|
||||
"document_root": "./",
|
||||
//home_page: Set the HTML file of the home page, the default value is "index.html"
|
||||
//If there isn't any handler registered to the path "/", the home page file in the "document_root" is send to clients as a response
|
||||
//to the request for "/".
|
||||
"home_page": "index.html",
|
||||
//static_file_headers: Headers for static files
|
||||
/*"static_file_headers": [
|
||||
{
|
||||
"name": "field-name",
|
||||
"value": "field-value"
|
||||
}
|
||||
],*/
|
||||
//upload_path: The path to save the uploaded file. "uploads" by default.
|
||||
//If the path isn't prefixed with /, ./ or ../,
|
||||
//it is relative path of document_root path
|
||||
"upload_path": "uploads",
|
||||
/* file_types:
|
||||
* HTTP download file types, the file types supported by drogon
|
||||
* by default are "html", "js", "css", "xml", "xsl", "txt", "svg",
|
||||
* "ttf", "otf", "woff2", "woff" , "eot", "png", "jpg", "jpeg",
|
||||
* "gif", "bmp", "ico", "icns", etc. */
|
||||
"file_types": [
|
||||
"gif",
|
||||
"png",
|
||||
"jpg",
|
||||
"js",
|
||||
"css",
|
||||
"html",
|
||||
"ico",
|
||||
"swf",
|
||||
"xap",
|
||||
"apk",
|
||||
"cur",
|
||||
"xml"
|
||||
],
|
||||
//max_connections: maximum connections number, 100000 by default
|
||||
"max_connections": 100000,
|
||||
//max_connections_per_ip: maximum connections number per client,0 by default which means no limit
|
||||
"max_connections_per_ip": 0,
|
||||
//Load_dynamic_views: False by default, when set to true, drogon
|
||||
//compiles and loads dynamically "CSP View Files" in directories defined
|
||||
//by "dynamic_views_path"
|
||||
"load_dynamic_views": false,
|
||||
//dynamic_views_path: If the path isn't prefixed with /, ./ or ../,
|
||||
//it is relative path of document_root path
|
||||
"dynamic_views_path": [
|
||||
"./views"
|
||||
],
|
||||
//log: Set log output, drogon output logs to stdout by default
|
||||
"log": {
|
||||
//log_path: Log file path,empty by default,in which case,logs are output to the stdout
|
||||
//"log_path": "./",
|
||||
//logfile_base_name: Log file base name,empty by default which means drogon names logfile as
|
||||
//drogon.log ...
|
||||
"logfile_base_name": "",
|
||||
//log_size_limit: 100000000 bytes by default,
|
||||
//When the log file size reaches "log_size_limit", the log file is switched.
|
||||
"log_size_limit": 100000000,
|
||||
//log_level: "DEBUG" by default,options:"TRACE","DEBUG","INFO","WARN"
|
||||
//The TRACE level is only valid when built in DEBUG mode.
|
||||
"log_level": "DEBUG"
|
||||
},
|
||||
//run_as_daemon: False by default
|
||||
"run_as_daemon": false,
|
||||
//handle_sig_term: True by default
|
||||
"handle_sig_term": true,
|
||||
//relaunch_on_error: False by default, if true, the program will be restart by the parent after exiting;
|
||||
"relaunch_on_error": false,
|
||||
//use_sendfile: True by default, if true, the program
|
||||
//uses sendfile() system-call to send static files to clients;
|
||||
"use_sendfile": true,
|
||||
//use_gzip: True by default, use gzip to compress the response body's content;
|
||||
"use_gzip": true,
|
||||
//static_files_cache_time: 5 (seconds) by default, the time in which the static file response is cached,
|
||||
//0 means cache forever, the negative value means no cache
|
||||
"static_files_cache_time": 5,
|
||||
//idle_connection_timeout: Defaults to 60 seconds, the lifetime
|
||||
//of the connection without read or write
|
||||
"idle_connection_timeout": 60,
|
||||
//server_header_field: Set the 'Server' header field in each response sent by drogon,
|
||||
//empty string by default with which the 'Server' header field is set to "Server: drogon/version string\r\n"
|
||||
"server_header_field": "",
|
||||
//enable_server_header: Set true to force drogon to add a 'Server' header to each HTTP response. The default
|
||||
//value is true.
|
||||
"enable_server_header": false,
|
||||
//enable_date_header: Set true to force drogon to add a 'Date' header to each HTTP response. The default
|
||||
//value is true.
|
||||
"enable_date_header": false,
|
||||
//keepalive_requests: Set the maximum number of requests that can be served through one keep-alive connection.
|
||||
//After the maximum number of requests are made, the connection is closed.
|
||||
//The default value of 0 means no limit.
|
||||
"keepalive_requests": 0,
|
||||
//pipelining_requests: Set the maximum number of unhandled requests that can be cached in pipelining buffer.
|
||||
//After the maximum number of requests are made, the connection is closed.
|
||||
//The default value of 0 means no limit.
|
||||
"pipelining_requests": 0,
|
||||
//gzip_static: If it is set to true, when the client requests a static file, drogon first finds the compressed
|
||||
//file with the extension ".gz" in the same path and send the compressed file to the client.
|
||||
//The default value of gzip_static is true.
|
||||
"gzip_static": true,
|
||||
//client_max_body_size: Set the maximum body size of HTTP requests received by drogon. The default value is "1M".
|
||||
//One can set it to "1024", "1k", "10M", "1G", etc. Setting it to "" means no limit.
|
||||
"client_max_body_size": "1M",
|
||||
//max_memory_body_size: Set the maximum body size in memory of HTTP requests received by drogon. The default value is "64K" bytes.
|
||||
//If the body size of a HTTP request exceeds this limit, the body is stored to a temporary file for processing.
|
||||
//Setting it to "" means no limit.
|
||||
"client_max_memory_body_size": "64K",
|
||||
//client_max_websocket_message_size: Set the maximum size of messages sent by WebSocket client. The default value is "128K".
|
||||
//One can set it to "1024", "1k", "10M", "1G", etc. Setting it to "" means no limit.
|
||||
"client_max_websocket_message_size": "128K"
|
||||
},
|
||||
//plugins: Define all plugins running in the application
|
||||
"plugins": [{
|
||||
//name: The class name of the plugin
|
||||
"name": "my_plugin::SimpleReverseProxy",
|
||||
//dependencies: Plugins that the plugin depends on. It can be commented out
|
||||
"dependencies": [],
|
||||
//config: The configuration of the plugin. This json object is the parameter to initialize the plugin.
|
||||
//It can be commented out
|
||||
"config": {
|
||||
// The pipelining depth of HTTP clients.
|
||||
"pipelining": 32,
|
||||
"backends": ["http://127.0.0.1:8848"],
|
||||
"same_client_to_same_backend": false,
|
||||
//The number of connections created by proxy for each backend in every event loop (IO thread).
|
||||
"connection_factor": 1
|
||||
}
|
||||
}],
|
||||
//custom_config: custom configuration for users. This object can be get by the app().getCustomConfig() method.
|
||||
"custom_config": {}
|
||||
}
|
10
vendors/simple-reverse-proxy/main.cc
vendored
Normal file
10
vendors/simple-reverse-proxy/main.cc
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
#include <drogon/drogon.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Set HTTP listener address and port
|
||||
drogon::app().loadConfigFile("config.json");
|
||||
// Run HTTP framework, the method will block in the internal event loop
|
||||
drogon::app().run();
|
||||
return 0;
|
||||
}
|
100
vendors/simple-reverse-proxy/plugins/SimpleReverseProxy.cc
vendored
Normal file
100
vendors/simple-reverse-proxy/plugins/SimpleReverseProxy.cc
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
*
|
||||
* @file SimpleReverseProxy.cc
|
||||
*
|
||||
*/
|
||||
|
||||
#include "SimpleReverseProxy.h"
|
||||
|
||||
using namespace drogon;
|
||||
using namespace my_plugin;
|
||||
|
||||
void SimpleReverseProxy::initAndStart(const Json::Value &config)
|
||||
{
|
||||
/// Initialize and start the plugin
|
||||
if (config.isMember("backends") && config["backends"].isArray())
|
||||
{
|
||||
for (auto &backend : config["backends"])
|
||||
{
|
||||
backendAddrs_.emplace_back(backend.asString());
|
||||
}
|
||||
if (backendAddrs_.empty())
|
||||
{
|
||||
LOG_ERROR << "You must set at least one backend";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR << "Error in configuration";
|
||||
abort();
|
||||
}
|
||||
pipeliningDepth_ = config.get("pipelining", 0).asInt();
|
||||
sameClientToSameBackend_ =
|
||||
config.get("same_client_to_same_backend", false).asBool();
|
||||
connectionFactor_ = config.get("connection_factor", 1).asInt();
|
||||
if (connectionFactor_ == 0 || connectionFactor_ > 100)
|
||||
{
|
||||
LOG_ERROR << "invalid number of connection factor";
|
||||
abort();
|
||||
}
|
||||
clients_.init(
|
||||
[this](std::vector<HttpClientPtr> &clients, size_t ioLoopIndex) {
|
||||
clients.resize(backendAddrs_.size() * connectionFactor_);
|
||||
});
|
||||
clientIndex_.init(
|
||||
[this](size_t &index, size_t ioLoopIndex) { index = ioLoopIndex; });
|
||||
drogon::app().registerPreRoutingAdvice([this](const HttpRequestPtr &req,
|
||||
AdviceCallback &&callback,
|
||||
AdviceChainCallback &&pass) {
|
||||
preRouting(req, std::move(callback), std::move(pass));
|
||||
});
|
||||
}
|
||||
|
||||
void SimpleReverseProxy::shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
void SimpleReverseProxy::preRouting(const HttpRequestPtr &req,
|
||||
AdviceCallback &&callback,
|
||||
AdviceChainCallback &&)
|
||||
{
|
||||
size_t index;
|
||||
auto &clientsVector = *clients_;
|
||||
if (sameClientToSameBackend_)
|
||||
{
|
||||
index = std::hash<uint32_t>{}(req->getPeerAddr().ipNetEndian()) %
|
||||
clientsVector.size();
|
||||
index = (index + (++(*clientIndex_)) * backendAddrs_.size()) %
|
||||
clientsVector.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
index = ++(*clientIndex_) % clientsVector.size();
|
||||
}
|
||||
auto &clientPtr = clientsVector[index];
|
||||
if (!clientPtr)
|
||||
{
|
||||
auto &addr = backendAddrs_[index % backendAddrs_.size()];
|
||||
clientPtr = HttpClient::newHttpClient(
|
||||
addr, trantor::EventLoop::getEventLoopOfCurrentThread());
|
||||
clientPtr->setPipeliningDepth(pipeliningDepth_);
|
||||
}
|
||||
req->setPassThrough(true);
|
||||
clientPtr->sendRequest(
|
||||
req,
|
||||
[callback = std::move(callback)](ReqResult result,
|
||||
const HttpResponsePtr &resp) {
|
||||
if (result == ReqResult::Ok)
|
||||
{
|
||||
resp->setPassThrough(true);
|
||||
callback(resp);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto errResp = HttpResponse::newHttpResponse();
|
||||
errResp->setStatusCode(k500InternalServerError);
|
||||
callback(errResp);
|
||||
}
|
||||
});
|
||||
}
|
44
vendors/simple-reverse-proxy/plugins/SimpleReverseProxy.h
vendored
Normal file
44
vendors/simple-reverse-proxy/plugins/SimpleReverseProxy.h
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
*
|
||||
* @file SimpleReverseProxy.h
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/plugins/Plugin.h>
|
||||
#include <drogon/drogon.h>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace my_plugin
|
||||
{
|
||||
class SimpleReverseProxy : public drogon::Plugin<SimpleReverseProxy>
|
||||
{
|
||||
public:
|
||||
SimpleReverseProxy()
|
||||
{
|
||||
}
|
||||
|
||||
/// This method must be called by drogon to initialize and start the plugin.
|
||||
/// It must be implemented by the user.
|
||||
void initAndStart(const Json::Value &config) override;
|
||||
|
||||
/// This method must be called by drogon to shutdown the plugin.
|
||||
/// It must be implemented by the user.
|
||||
void shutdown() override;
|
||||
|
||||
private:
|
||||
// Create 'connectionFactor_' HTTP clients for every backend in every IO
|
||||
// event loop.
|
||||
drogon::IOThreadStorage<std::vector<drogon::HttpClientPtr>> clients_;
|
||||
drogon::IOThreadStorage<size_t> clientIndex_{0};
|
||||
std::vector<std::string> backendAddrs_;
|
||||
bool sameClientToSameBackend_{false};
|
||||
size_t pipeliningDepth_{0};
|
||||
void preRouting(const drogon::HttpRequestPtr &,
|
||||
drogon::AdviceCallback &&,
|
||||
drogon::AdviceChainCallback &&);
|
||||
size_t connectionFactor_{1};
|
||||
};
|
||||
} // namespace my_plugin
|
Loading…
x
Reference in New Issue
Block a user