From a73ff4e05cc59f89ead9da3b13cd1cf15d71902c Mon Sep 17 00:00:00 2001 From: Relintai Date: Sat, 1 May 2021 14:08:48 +0200 Subject: [PATCH] Initial commit. --- .clang-format | 128 +++++++++++ .gitignore | 31 +++ HEADS | 1 + LICENSE | 1 + Readme.md | 9 + SConstruct | 492 ++++++++++++++++++++++++++++++++++++++++ app/paged_list.cpp | 45 ++++ app/paged_list.h | 26 +++ app/rdn_application.cpp | 264 +++++++++++++++++++++ app/rdn_application.h | 60 +++++ build.config.example | 44 ++++ main.cpp | 97 ++++++++ 12 files changed, 1198 insertions(+) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 HEADS create mode 100644 LICENSE create mode 100644 Readme.md create mode 100644 SConstruct create mode 100644 app/paged_list.cpp create mode 100644 app/paged_list.h create mode 100644 app/rdn_application.cpp create mode 100644 app/rdn_application.h create mode 100644 build.config.example create mode 100644 main.cpp diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..cb67d39 --- /dev/null +++ b/.clang-format @@ -0,0 +1,128 @@ +# Commented out parameters are those with the same value as base LLVM style +# We can uncomment them if we want to change their value, or enforce the +# chosen value in case the base style changes (last sync: Clang 6.0.1). +--- +### General config, applies to all languages ### +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +# AlignConsecutiveAssignments: false +# AlignConsecutiveDeclarations: false +# AlignEscapedNewlines: Right +# AlignOperands: true +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: false +# AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: true +# AllowShortLoopsOnASingleLine: false +# AlwaysBreakAfterDefinitionReturnType: None +# AlwaysBreakAfterReturnType: None +# AlwaysBreakBeforeMultilineStrings: false +# AlwaysBreakTemplateDeclarations: false +# BinPackArguments: true +# BinPackParameters: true +# BraceWrapping: +# AfterClass: false +# AfterControlStatement: false +# AfterEnum: false +# AfterFunction: false +# AfterNamespace: false +# AfterObjCDeclaration: false +# AfterStruct: false +# AfterUnion: false +# AfterExternBlock: false +# BeforeCatch: false +# BeforeElse: false +# IndentBraces: false +# SplitEmptyFunction: true +# SplitEmptyRecord: true +# SplitEmptyNamespace: true +# BreakBeforeBinaryOperators: None +# BreakBeforeBraces: Attach +# BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: false +# BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: AfterColon +# BreakStringLiterals: true +ColumnLimit: 0 +# CommentPragmas: '^ IWYU pragma:' +# CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 8 +Cpp11BracedListStyle: false +# DerivePointerAlignment: false +# DisableFormat: false +# ExperimentalAutoDetectBinPacking: false +# FixNamespaceComments: true +# ForEachMacros: +# - foreach +# - Q_FOREACH +# - BOOST_FOREACH +# IncludeBlocks: Preserve +IncludeCategories: + - Regex: '".*"' + Priority: 1 + - Regex: '^<.*\.h>' + Priority: 2 + - Regex: '^<.*' + Priority: 3 +# IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: true +# IndentPPDirectives: None +IndentWidth: 4 +# IndentWrappedFunctionNames: false +# JavaScriptQuotes: Leave +# JavaScriptWrapImports: true +# KeepEmptyLinesAtTheStartOfBlocks: true +# MacroBlockBegin: '' +# MacroBlockEnd: '' +# MaxEmptyLinesToKeep: 1 +# NamespaceIndentation: None +# PenaltyBreakAssignment: 2 +# PenaltyBreakBeforeFirstCallParameter: 19 +# PenaltyBreakComment: 300 +# PenaltyBreakFirstLessLess: 120 +# PenaltyBreakString: 1000 +# PenaltyExcessCharacter: 1000000 +# PenaltyReturnTypeOnItsOwnLine: 60 +# PointerAlignment: Right +# RawStringFormats: +# - Delimiter: pb +# Language: TextProto +# BasedOnStyle: google +# ReflowComments: true +# SortIncludes: true +# SortUsingDeclarations: true +# SpaceAfterCStyleCast: false +# SpaceAfterTemplateKeyword: true +# SpaceBeforeAssignmentOperators: true +# SpaceBeforeParens: ControlStatements +# SpaceInEmptyParentheses: false +# SpacesBeforeTrailingComments: 1 +# SpacesInAngles: false +# SpacesInContainerLiterals: true +# SpacesInCStyleCastParentheses: false +# SpacesInParentheses: false +# SpacesInSquareBrackets: false +TabWidth: 4 +UseTab: Always +--- +### C++ specific config ### +Language: Cpp +Standard: Cpp03 +--- +### ObjC specific config ### +Language: ObjC +Standard: Cpp03 +ObjCBlockIndentWidth: 4 +# ObjCSpaceAfterProperty: false +# ObjCSpaceBeforeProtocolList: true +--- +### Java specific config ### +Language: Java +# BreakAfterJavaFieldAnnotations: false +JavaImportGroups: ['org.godotengine', 'android', 'androidx', 'com.android', 'com.google', 'java', 'javax'] +... diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..028c273 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +engine +modules/* +logs/* + +*.d +*.o +*.meta +game/.import/** +game/.prop_tool_temp/** +.sconsign.dblite +.DS_Store + +export/** +release/** + +.vs/* +.kdev4/* +.vscode/* + +TestRWTextures + +_build/* +_binaries/* +game/android/build/* + +*.blend1 +.dir-locals.el + +build.config + +content/* \ No newline at end of file diff --git a/HEADS b/HEADS new file mode 100644 index 0000000..fbb8516 --- /dev/null +++ b/HEADS @@ -0,0 +1 @@ +{"engine": {"master": "8c483b4f8ee02bebb9db275a262208254f0d34fc"}} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e3c3eba --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +Copyright (c) 2020 Péter Magyar diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..b7f2f57 --- /dev/null +++ b/Readme.md @@ -0,0 +1,9 @@ +# rcpp_cms_project + +Sample project for rcpp cms. + + +clone this repo, then call `scons`, it will clone rcpp cms into a new engine directory, then you can build using build words, like: `scons bl`. + + +Proper explanation for the time being: https://github.com/Relintai/broken_seals (Compiling section). (I'm using the same script.) diff --git a/SConstruct b/SConstruct new file mode 100644 index 0000000..f31f11b --- /dev/null +++ b/SConstruct @@ -0,0 +1,492 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright (c) 2019-2020 Péter Magyar +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +EnsureSConsVersion(0, 98, 1) + +import sys +import os +import subprocess +import json +import shutil +import traceback + + +folders = [ + 'app', +] + +main_file = 'main.cpp' + +repository_index = 0 +module_clone_path = '/modules/' +clone_command = 'git clone {0} {1}' + +visual_studio_call_vcvarsall = False +visual_studio_vcvarsall_path = 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat' +visual_studio_arch = 'amd64' + +exports = { + 'global': [], + 'linux': [], + 'windows': [], + 'android': [], + 'javascript': [], +} + +engine_repository = [ ['https://github.com/Relintai/rcpp_cms.git', 'git@github.com:Relintai/rcpp_cms.git'], 'engine', '' ] + +module_repositories = [ +] + +addon_repositories = [ +] + +third_party_addon_repositories = [ +] + +target_commits = {} + +engine_branch = 'master' + +def onerror(func, path, exc_info): + """ + https://stackoverflow.com/questions/2656322/shutil-rmtree-fails-on-windows-with-access-is-denied + + Because Windows. + + Error handler for ``shutil.rmtree``. + + If the error is due to an access error (read only file) + it attempts to add write permission and then retries. + + If the error is for another reason it re-raises the error. + + Usage : ``shutil.rmtree(path, onerror=onerror)`` + """ + import stat + if not os.access(path, os.W_OK): + # Is the error an access error ? + os.chmod(path, stat.S_IWUSR) + func(path) + else: + raise + +def load_target_commits_array(): + global target_commits + + if os.path.isfile('./HEADS'): + with open('./HEADS', 'r') as infile: + target_commits = json.load(infile) + else: + target_commits = {} + +def save_target_commits_array(): + with open('./HEADS', 'w') as outfile: + json.dump(target_commits, outfile) + +def update_repository(data, clone_path, branch = 'master'): + cwd = os.getcwd() + + full_path = cwd + clone_path + data[1] + '/' + + if not os.path.isdir(full_path): + os.chdir(cwd + clone_path) + + subprocess.call(clone_command.format(data[0][repository_index], data[1]), shell=True) + + os.chdir(full_path) + + subprocess.call('git reset', shell=True) + subprocess.call('git reset --hard', shell=True) + subprocess.call('git clean -f -d', shell=True) + subprocess.call('git checkout -B ' + branch + ' origin/' + branch, shell=True) + subprocess.call('git reset', shell=True) + subprocess.call('git reset --hard', shell=True) + subprocess.call('git clean -f -d', shell=True) + subprocess.call('git pull origin ' + branch, shell=True) + + process = subprocess.Popen('git rev-parse HEAD', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + output = process.communicate()[0].decode().strip() + + if data[1] not in target_commits: + target_commits[data[1]] = {} + + target_commits[data[1]][branch] = output + + os.chdir(cwd) + +def setup_repository(data, clone_path, branch = 'master'): + cwd = os.getcwd() + + full_path = cwd + clone_path + data[1] + '/' + + if not os.path.isdir(full_path): + os.chdir(cwd + clone_path) + + subprocess.call(clone_command.format(data[0][repository_index], data[1]), shell=True) + + os.chdir(full_path) + + subprocess.call('git reset', shell=True) + subprocess.call('git reset --hard', shell=True) + subprocess.call('git clean -f -d', shell=True) + subprocess.call('git checkout -B ' + branch + ' origin/' + branch, shell=True) + subprocess.call('git pull origin ' + branch, shell=True) + subprocess.call('git reset', shell=True) + subprocess.call('git reset --hard', shell=True) + + if data[1] in target_commits: + target = target_commits[data[1]][branch] + + subprocess.call('git checkout -B ' + branch + ' ' + target, shell=True) + subprocess.call('git clean -f -d', shell=True) + subprocess.call('git reset', shell=True) + subprocess.call('git reset --hard', shell=True) + + os.chdir(cwd) + +def copy_repository(data, target_folder, clone_path): + copytree(os.path.abspath(clone_path + data[1] + '/' + data[2]), os.path.abspath(target_folder + data[1])) + +def copytree(src, dst): + for item in os.listdir(src): + sp = os.path.join(src, item) + dp = os.path.join(dst, item) + + if os.path.isdir(sp): + if os.path.isdir(dp): + shutil.rmtree(dp, onerror=onerror) + + shutil.copytree(sp, dp) + else: + if not os.path.isdir(dst): + os.makedirs(dst) + + shutil.copy2(sp, dp) + +def update_engine(): + update_repository(engine_repository, '/', engine_branch) + +def update_modules(): + for rep in module_repositories: + update_repository(rep, module_clone_path) + copy_repository(rep, './engine/modules/', '.' + module_clone_path) + +def update_addons(): + for rep in addon_repositories: + update_repository(rep, module_clone_path) + copy_repository(rep, './game/addons/', '.' + module_clone_path) + +def update_addons_third_party_addons(): + for rep in third_party_addon_repositories: + update_repository(rep, module_clone_path) + copy_repository(rep, './game/addons/', '.' + module_clone_path) + +def update_all(): + update_engine() + update_modules() + update_addons() + update_addons_third_party_addons() + + save_target_commits_array() + + +def setup_engine(): + setup_repository(engine_repository, '/', engine_branch) + +def setup_modules(): + for rep in module_repositories: + setup_repository(rep, module_clone_path) + copy_repository(rep, './engine/modules/', '.' + module_clone_path) + +def setup_addons(): + for rep in addon_repositories: + setup_repository(rep, module_clone_path) + copy_repository(rep, './game/addons/', '.' + module_clone_path) + +def setup_addons_third_party_addons(): + for rep in third_party_addon_repositories: + setup_repository(rep, module_clone_path) + copy_repository(rep, './game/addons/', '.' + module_clone_path) + +def setup_all(): + setup_engine() + setup_modules() + setup_addons() + setup_addons_third_party_addons() + +def format_path(path): + if 'win' in sys.platform: + path = path.replace('/', '\\') + path = path.replace('~', '%userprofile%') + + return path + +def get_exports_for(platform): + export_command = 'export ' + command_separator = ';' + + if 'win' in sys.platform: + command_separator = '&' + export_command = 'set ' + + command = '' + + for p in exports[platform]: + command += export_command + p + command_separator + + return command + + +def parse_config(): + global visual_studio_vcvarsall_path + global visual_studio_arch + global visual_studio_call_vcvarsall + global exports + + if not os.path.isfile('build.config'): + return + + with open('build.config', 'r') as f: + + for line in f: + ls = line.strip() + if ls == '' or ls.startswith('#'): + continue + + words = line.split() + + if (len(words) < 2): + print('This build.config line is malformed, and got ignored: ' + ls) + continue + + if words[0] == 'visual_studio_vcvarsall_path': + visual_studio_vcvarsall_path = format_path(ls[29:]) + elif words[0] == 'visual_studio_arch': + visual_studio_arch = format_path(ls[19:]) + elif words[0] == 'visual_studio_call_vcvarsall': + visual_studio_call_vcvarsall = words[1].lower() in [ 'true', '1', 't', 'y', 'yes' ] + elif words[0] == 'export': + if (len(words) < 3) or not words[1] in exports: + print('This build.config line is malformed, and got ignored: ' + ls) + continue + + export_path = format_path(ls[8 + len(words[1]):]) + + exports[words[1]].append(export_path) + +parse_config() + +env = Environment() + +if len(sys.argv) > 1: + + arg = sys.argv[1] + + arg_split = arg.split('_') + arg = arg_split[0] + arg_split = arg_split[1:] + + if arg[0] == 'b': + build_string = get_exports_for('global') + 'scons ' + + build_string += 'target=' + if 'r' in arg: + build_string += 'release' + elif 'd' in arg: + build_string += 'debug' + else: + build_string += 'release_debug' + build_string += ' ' + + if 'm' in arg: + build_string += 'use_mingw=yes' + else: + if 'win' in sys.platform and visual_studio_call_vcvarsall: + build_string = 'call "{0}" {1}&'.format(visual_studio_vcvarsall_path, visual_studio_arch) + build_string + + if 'o' in arg: + build_string += 'use_llvm=yes' + + if 'v' in arg: + build_string += 'vsproj=yes' + + build_string += 'folders="' + + for f in folders: + build_string += '../' + f + build_string += ';' + + build_string += '" ' + + build_string += 'main_file="../' + main_file + '" ' + + for i in range(2, len(sys.argv)): + build_string += ' ' + sys.argv[i] + ' ' + + cwd = os.getcwd() + full_path = cwd + '/engine/' + + if not os.path.isdir(full_path): + print('engine directory doesnt exists.') + exit() + + os.chdir(full_path) + + if 'l' in arg: + build_string += 'platform=x11' + + build_string = get_exports_for('linux') + build_string + + print('Running command: ' + build_string) + + subprocess.call(build_string, shell=True) + elif 'w' in arg: + build_string += 'platform=windows' + + build_string = get_exports_for('windows') + build_string + + print('Running command: ' + build_string) + + subprocess.call(build_string, shell=True) + elif 'a' in arg: + build_string += 'platform=android' + + build_string = get_exports_for('android') + build_string + + print('Running command: ' + build_string + ' android_arch=armv7') + subprocess.call(build_string + ' android_arch=armv7', shell=True) + print('Running command: ' + build_string + ' android_arch=arm64v8') + subprocess.call(build_string + ' android_arch=arm64v8', shell=True) + print('Running command: ' + build_string + ' android_arch=x86') + subprocess.call(build_string + ' android_arch=x86', shell=True) + + os.chdir(full_path + 'platform/android/java/') + + print('Running command: ' + get_exports_for('global') + get_exports_for('android') + './gradlew generateGodotTemplates') + subprocess.call(get_exports_for('global') + get_exports_for('android') + './gradlew generateGodotTemplates', shell=True) + elif 'j' in arg: + build_string += 'platform=javascript' + + build_string = get_exports_for('javascript') + build_string + + print('Running command: ' + build_string) + subprocess.call(build_string, shell=True) + + else: + print('No platform specified') + exit() + + exit() + elif arg[0] == 'p': + if arg == 'p': + #print("Applies a patch. Append c for the compilation database patch. For example: pc") + print("Applies a patch. No Patches right now.") + exit() + + cwd = os.getcwd() + full_path = cwd + '/engine/' + + if not os.path.isdir(full_path): + print('engine directory doesnt exists.') + exit() + + os.chdir(full_path) + + #apply the patch to just the working directory, without creating a commit + + #if 'c' in arg: + # subprocess.call('git apply --index ../patches/compilation_db.patch', shell=True) + + #unstage all files + subprocess.call('git reset', shell=True) + + exit() + +opts = Variables(args=ARGUMENTS) + +opts.Add('a', 'What to do', '') +opts.Add(EnumVariable('action', 'What to do', 'setup', ('setup', 'update'))) +opts.Add('t', 'Action target', '') +opts.Add(EnumVariable('target', 'Action target', 'all', ('all', 'engine', 'modules', 'all_addons', 'addons', 'third_party_addons'))) +opts.Add(EnumVariable('repository_type', 'Type of repositories to clone from first', 'http', ('http', 'ssh'))) + +opts.Update(env) +Help(opts.GenerateHelpText(env)) + +load_target_commits_array() + +rt = env['repository_type'] + +if rt == 'ssh': + repository_index = 1 + +action = env['action'] +target = env['target'] + +if env['a']: + action = env['a'] + +if env['t']: + target = env['t'] + +if not os.path.isdir('./modules'): + os.mkdir('./modules') + +if 'm' in action: + godot_branch = 'master' + +if 'setup' in action or action[0] == 's': + if target == 'all': + setup_all() + elif target == 'engine': + setup_engine() + elif target == 'modules': + setup_modules() + elif target == 'all_addons': + setup_addons() + setup_addons_third_party_addons() + elif target == 'addons': + setup_addons() + elif target == 'third_party_addons': + setup_addons_third_party_addons() +elif 'update' in action or action[0] == 'u': + if target == 'all': + update_all() + elif target == 'engine': + update_engine() + save_target_commits_array() + elif target == 'modules': + update_modules() + save_target_commits_array() + elif target == 'all_addons': + update_addons() + update_addons_third_party_addons() + save_target_commits_array() + elif target == 'addons': + update_addons() + save_target_commits_array() + elif target == 'third_party_addons': + update_addons_third_party_addons() + save_target_commits_array() + diff --git a/app/paged_list.cpp b/app/paged_list.cpp new file mode 100644 index 0000000..ea581c0 --- /dev/null +++ b/app/paged_list.cpp @@ -0,0 +1,45 @@ +#include "paged_list.h" + +#include "core/request.h" + +#include + +#include "core/file_cache.h" + +#include "core/handler_instance.h" + +#include "core/database_manager.h" + +#include "core/html_builder.h" + +void PagedList::index(Request *request) { + const std::string path = request->get_current_path_segment(); + + if (request->get_remaining_segment_count() == 0) { + main_page->index(request); + return; + } + + articles->index(request); +} + +void PagedList::load() { + main_page->folder = folder; + main_page->load(); + + articles->base_path = base_path; + articles->folder = folder; + articles->load(); +} + +PagedList::PagedList() : + Object() { + + main_page = new ListPage(); + articles = new PagedArticle(); +} + +PagedList::~PagedList() { + delete main_page; + delete articles; +} diff --git a/app/paged_list.h b/app/paged_list.h new file mode 100644 index 0000000..481f54a --- /dev/null +++ b/app/paged_list.h @@ -0,0 +1,26 @@ +#ifndef PAGED_LIST_H +#define PAGED_LIST_H + +#include "core/object.h" + +#include + +#include "modules/list_page/list_page.h" +#include "modules/paged_article/paged_article.h" + +class PagedList : public Object { +public: + void index(Request *request); + + void load(); + + PagedList(); + ~PagedList(); + + ListPage *main_page; + PagedArticle *articles; + std::string folder; + std::string base_path; +}; + +#endif \ No newline at end of file diff --git a/app/rdn_application.cpp b/app/rdn_application.cpp new file mode 100644 index 0000000..c9bb65c --- /dev/null +++ b/app/rdn_application.cpp @@ -0,0 +1,264 @@ +#include "rdn_application.h" + +#include "core/request.h" + +#include + +#include "core/file_cache.h" + +#include "core/handler_instance.h" + +#include "core/database_manager.h" + +#include "core/html_builder.h" + +void RDNApplication::index(Object *instance, Request *request) { + add_menu(request, MENUENTRY_HOME); + + dynamic_cast(instance)->index(request); +} + +void RDNApplication::session_middleware_func(Object *instance, Request *request) { + std::cout << "test: session_middleware_func called" << std::endl; + + //if fail + //request->send(); in middleware + + request->next_stage(); +} + +void RDNApplication::add_menu(Request *request, const Menuentries index) { + request->head += menu_head; + request->body += menu_strings[index]; + request->footer = footer; +} + +void RDNApplication::projects_page_func(Object *instance, Request *request) { + add_menu(request, MENUENTRY_PROJECTS); + + dynamic_cast(instance)->index(request); +} + +void RDNApplication::classes_page_func(Object *instance, Request *request) { + add_menu(request, MENUENTRY_CLASSES); + + dynamic_cast(instance)->index(request); +} + +void RDNApplication::videos_page_func(Object *instance, Request *request) { + add_menu(request, MENUENTRY_VIDEOS); + + dynamic_cast(instance)->index(request); +} + +void RDNApplication::papers_page_func(Object *instance, Request *request) { + add_menu(request, MENUENTRY_PAPERS); + + dynamic_cast(instance)->index(request); +} + +void RDNApplication::research_page_func(Object *instance, Request *request) { + add_menu(request, MENUENTRY_RESEARCH); + + dynamic_cast(instance)->index(request); +} + +void RDNApplication::setup_routes() { + Application::setup_routes(); + + index_func = HandlerInstance(index, index_page); + main_route_map["projects"] = HandlerInstance(projects_page_func, projects_page); + main_route_map["classes"] = HandlerInstance(classes_page_func, classes_page); + //main_route_map["videos"] = HandlerInstance(videos_page_func, videos_page); + main_route_map["papers"] = HandlerInstance(papers_page_func, papers_page); + //main_route_map["research"] = HandlerInstance(research_page_func, research_page); +} + +void RDNApplication::setup_middleware() { + Application::setup_middleware(); + + //middlewares.push_back(RDNApplication::session_middleware_func); +} + +void RDNApplication::migrate() { +} + +void RDNApplication::compile_menu() { + + for (int i = 0; i < MENUENTRY_MAX; ++i) { + HTMLBuilder b; + + HTMLTag *t; + + b.div()->cls("content"); + + b.header(); + b.w("<relintai::net>"); + b.span()->cls("header_link"); + b.w(" [ "); + b.a()->href("https://github.com/Relintai"); + b.w("Github"); + b.ca(); + b.w(" ]"); + b.ca(); + + b.cheader(); + + b.ul()->cls("menu"); + + //b.li(); + //b.w("::Relintai.net::"); + //b.cli(); + + b.li(); + t = b.a()->href("/"); + + if (i == MENUENTRY_HOME) { + t->cls("menu_active"); + } + + b.w("Home"); + b.ca(); + b.cli(); + + b.li(); + t = b.a()->href("/projects"); + + if (i == MENUENTRY_PROJECTS) { + t->cls("menu_active"); + } + + b.w("Projects"); + b.ca(); + b.cli(); + + /* + b.li(); + t = b.a()->href("/videos"); + + if (i == MENUENTRY_VIDEOS) { + t->cls("menu_active"); + } + + b.w("Videos"); + b.ca(); + b.cli(); +*/ + + b.li(); + t = b.a()->href("/classes"); + + if (i == MENUENTRY_CLASSES) { + t->cls("menu_active"); + } + + b.w("Classes"); + b.ca(); + b.cli(); + + b.li(); + t = b.a()->href("/papers"); + + if (i == MENUENTRY_PAPERS) { + t->cls("menu_active"); + } + + b.w("Papers"); + b.ca(); + b.cli(); + + /* + b.li(); + t = b.a()->href("/research"); + + if (i == MENUENTRY_RESEARCH) { + t->cls("menu_active"); + } + + b.w("Research"); + b.ca(); + b.cli(); +*/ + + b.cul(); + + //b.div()->cls("content"); + //b.write_tag(); + + b.div()->cls("inner_content"); + b.write_tag(); + + menu_strings.push_back(b.result); + } + + HTMLBuilder bh; + + bh.meta()->charset_utf_8(); + + bh.link()->rel_stylesheet()->href("/css/main.css"); + bh.write_tag(); + + menu_head = bh.result; + + HTMLBuilder bf; + + bf.cdiv(); + bf.footer(); + bf.w("Powered by "); + bf.a()->href("https://github.com/Relintai/rcpp_cms"); + bf.w("rcpp cms"); + bf.ca(); + bf.w("."); + bf.cfooter(); + + bf.cdiv(); + + footer = bf.result; +} + +RDNApplication::RDNApplication() : + Application() { + + index_page = new ListPage(); + index_page->folder = "./content/home/"; + index_page->load(); + + projects_page = new ListPage(); + projects_page->folder = "./content/projects/"; + projects_page->load(); + + classes_page = new PagedList(); + classes_page->base_path = "/classes"; + classes_page->folder = "./content/classes/"; + classes_page->load(); + + videos_page = new ListPage(); + videos_page->folder = "./content/videos/"; + videos_page->load(); + + papers_page = new ListPage(); + papers_page->folder = "./content/papers/"; + papers_page->load(); + + research_page = nullptr; + + //research_page = new PagedList(); + //research_page->base_path = "/research"; + //research_page->folder = "./content/research/"; + //research_page->load(); + + compile_menu(); +} + +RDNApplication::~RDNApplication() { + delete index_page; + delete projects_page; + delete classes_page; + delete videos_page; + delete papers_page; +// delete research_page; +} + +std::vector RDNApplication::menu_strings; +std::string RDNApplication::menu_head = ""; +std::string RDNApplication::footer = ""; diff --git a/app/rdn_application.h b/app/rdn_application.h new file mode 100644 index 0000000..64aafcf --- /dev/null +++ b/app/rdn_application.h @@ -0,0 +1,60 @@ +#ifndef RDN_APPLICATION_H +#define RDN_APPLICATION_H + +#include "core/application.h" +#include "core/object.h" + +#include "modules/message_page/message_page.h" +#include "modules/list_page/list_page.h" +#include "modules/paged_article/paged_article.h" +#include "paged_list.h" + +class RDNApplication : public Application { +public: + enum Menuentries { + MENUENTRY_HOME = 0, + MENUENTRY_PROJECTS, + MENUENTRY_VIDEOS, + MENUENTRY_CLASSES, + MENUENTRY_PAPERS, + MENUENTRY_RESEARCH, + + MENUENTRY_MAX, + }; + +public: + static void index(Object *instance, Request *request); + + static void session_middleware_func(Object* instance, Request *request); + + static void add_menu(Request *request, const Menuentries index); + + static void projects_page_func(Object *instance, Request *request); + static void classes_page_func(Object *instance, Request *request); + static void videos_page_func(Object *instance, Request *request); + static void papers_page_func(Object *instance, Request *request); + static void research_page_func(Object *instance, Request *request); + + virtual void setup_routes(); + virtual void setup_middleware(); + + virtual void migrate(); + + void compile_menu(); + + RDNApplication(); + ~RDNApplication(); + + ListPage *index_page; + ListPage *projects_page; + PagedList *classes_page; + ListPage *videos_page; + ListPage *papers_page; + PagedList *research_page; + + static std::vector menu_strings; + static std::string menu_head; + static std::string footer; +}; + +#endif \ No newline at end of file diff --git a/build.config.example b/build.config.example new file mode 100644 index 0000000..317567f --- /dev/null +++ b/build.config.example @@ -0,0 +1,44 @@ +# Copyright (c) 2019-2020 Péter Magyar +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Rename this file to build.config to use it + +# Lines starting with # are comments. (Only works at the start of the line!) + +# Note: +# ~ will be converted to %userprofile% on windows +# / will be converted to \ on windows +# so you don't have to worry about it + +# Visual studio related setup: +visual_studio_call_vcvarsall True +visual_studio_vcvarsall_path C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build/vcvarsall.bat +visual_studio_arch amd64 + +# export related setup +# available export targets: global, linux, windows, android, javascript + +export global SCONS_CACHE=~/.scons_cache +export global SCONS_CACHE_LIMIT=5000 + +export android ANDROID_NDK_ROOT=~/SDKs/Android/NDK/android-ndk-r20b +export android ANDROID_NDK_HOME=~/SDKs/Android/NDK/android-ndk-r20b +export android ANDROID_HOME=~/SDKs/Android/SDK + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..3f2597f --- /dev/null +++ b/main.cpp @@ -0,0 +1,97 @@ +#include +#include +#include + +#include "core/application.h" +#include "core/file_cache.h" +#include "core/http_server.h" + +#include "app/rdn_application.h" + +#include "core/database_manager.h" + +#include "database/db_init.h" + +#include "core/settings.h" + +#define MAIN_CLASS RDNApplication + +void create_databases() { + + Settings *settings = Settings::get_singleton(); + + if (!settings) { + printf("create_databases: Settings singleton is null!"); + return; + } + +/* + rapidjson::Value dbs = settings->settings["databases"]; + + if (!dbs.IsArray()) { + printf("create_databases: dbs !dbs.IsArray()!"); + return; + } +*/ + + //DatabaseManager *dbm = DatabaseManager::get_singleton(); + + //uint32_t index = dbm->create_database("mysql"); + //Database *db = dbm->databases[0]; + //db->_builder_creation_func = MysqlQueryBuilder::create; + //db->connect(""); +} + +int main(int argc, char **argv) { + bool migrate = false; + + for (int i = 1; i < argc; ++i) { + const char *a = argv[i]; + + if (a[0] == 'm') { + migrate = true; + } + } + + initialize_database_backends(); + + Settings *settings = new Settings(true); + + settings->parse_file("settings.json"); + + FileCache *file_cache = new FileCache(true); + file_cache->wwwroot = "./content/www"; + file_cache->wwwroot_refresh_cache(); + + DatabaseManager *dbm = new DatabaseManager(); + + create_databases(); + + Application *app = new MAIN_CLASS(); + + app->load_settings(); + app->setup_routes(); + app->setup_middleware(); + + HTTPServer *server = new HTTPServer(); + server->application = app; + + server->port = 8080; + server->initialize(); + + if (!migrate) { + printf("Initialized!\n"); + server->main_loop(); + } else { + printf("Running migrations.\n"); + app->migrate(); + } + + delete server; + delete app; + delete dbm; + delete file_cache; + delete settings; + + return 0; +} \ No newline at end of file