"404 Not Found" exceptions now contains the requested URL (as in the log)

This commit is contained in:
Daniele Teti 2020-04-07 10:37:33 +02:00
parent 36ca9d43dc
commit 4a1ef47bd3
36 changed files with 196 additions and 3110 deletions

View File

@ -1,65 +0,0 @@
Installing Apache HTTP Server 2.x with
DomainName = example.com
ServerName = www.example.com
ServerAdmin = admin@example.com
ServerPort = 80
ServerSslPort = 443
ServerRoot = c:/Apache24
Rewrote docs/conf/extra/httpd-autoindex.conf.in
to c:/Apache24/conf/original/extra/httpd-autoindex.conf
Rewrote docs/conf/extra/httpd-default.conf.in
to c:/Apache24/conf/original/extra/httpd-default.conf
Rewrote docs/conf/extra/httpd-ssl.conf.in
to c:/Apache24/conf/original/extra/httpd-ssl.conf
Rewrote docs/conf/extra/httpd-multilang-errordoc.conf.in
to c:/Apache24/conf/original/extra/httpd-multilang-errordoc.conf
Rewrote docs/conf/extra/httpd-info.conf.in
to c:/Apache24/conf/original/extra/httpd-info.conf
Rewrote docs/conf/extra/httpd-userdir.conf.in
to c:/Apache24/conf/original/extra/httpd-userdir.conf
Rewrote docs/conf/extra/httpd-mpm.conf.in
to c:/Apache24/conf/original/extra/httpd-mpm.conf
Rewrote docs/conf/httpd.conf.in
to c:/Apache24/conf/original/httpd.conf
Rewrote docs/conf/extra/proxy-html.conf.in
to c:/Apache24/conf/original/extra/proxy-html.conf
Rewrote docs/conf/extra/httpd-vhosts.conf.in
to c:/Apache24/conf/original/extra/httpd-vhosts.conf
Rewrote docs/conf/extra/httpd-dav.conf.in
to c:/Apache24/conf/original/extra/httpd-dav.conf
Rewrote docs/conf/extra/httpd-languages.conf.in
to c:/Apache24/conf/original/extra/httpd-languages.conf
Rewrote docs/conf/extra/httpd-manual.conf.in
to c:/Apache24/conf/original/extra/httpd-manual.conf
Duplicated c:/Apache24/conf/original/extra/httpd-autoindex.conf
to c:/Apache24/conf/extra/httpd-autoindex.conf
Duplicated c:/Apache24/conf/original/extra/httpd-default.conf
to c:/Apache24/conf/extra/httpd-default.conf
Duplicated c:/Apache24/conf/original/extra/httpd-ssl.conf
to c:/Apache24/conf/extra/httpd-ssl.conf
Duplicated c:/Apache24/conf/original/extra/httpd-multilang-errordoc.conf
to c:/Apache24/conf/extra/httpd-multilang-errordoc.conf
Duplicated c:/Apache24/conf/original/extra/httpd-info.conf
to c:/Apache24/conf/extra/httpd-info.conf
Duplicated c:/Apache24/conf/original/extra/httpd-userdir.conf
to c:/Apache24/conf/extra/httpd-userdir.conf
Duplicated c:/Apache24/conf/original/extra/httpd-mpm.conf
to c:/Apache24/conf/extra/httpd-mpm.conf
Duplicated c:/Apache24/conf/original/httpd.conf
to c:/Apache24/conf/httpd.conf
Duplicated c:/Apache24/conf/original/magic
to c:/Apache24/conf/magic
Duplicated c:/Apache24/conf/original/charset.conv
to c:/Apache24/conf/charset.conv
Duplicated c:/Apache24/conf/original/extra/proxy-html.conf
to c:/Apache24/conf/extra/proxy-html.conf
Duplicated c:/Apache24/conf/original/extra/httpd-vhosts.conf
to c:/Apache24/conf/extra/httpd-vhosts.conf
Duplicated c:/Apache24/conf/original/extra/httpd-dav.conf
to c:/Apache24/conf/extra/httpd-dav.conf
Duplicated c:/Apache24/conf/original/mime.types
to c:/Apache24/conf/mime.types
Duplicated c:/Apache24/conf/original/extra/httpd-languages.conf
to c:/Apache24/conf/extra/httpd-languages.conf
Duplicated c:/Apache24/conf/original/extra/httpd-manual.conf
to c:/Apache24/conf/extra/httpd-manual.conf

Binary file not shown.

View File

@ -67,7 +67,7 @@ begin
Article := Context.Request.BodyAs<TArticle>; Article := Context.Request.BodyAs<TArticle>;
try try
GetArticlesService.Add(Article); GetArticlesService.Add(Article);
ResponseCreated('/articles/' + Article.ID.ToString, 'Article Created'); Render201Created('/articles/' + Article.ID.ToString, 'Article Created');
finally finally
Article.Free; Article.Free;
end; end;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2198,7 +2198,12 @@ begin
LContext.Response.StatusCode := HTTP_STATUS.NotFound; LContext.Response.StatusCode := HTTP_STATUS.NotFound;
LContext.Response.ReasonString := 'Not Found'; LContext.Response.ReasonString := 'Not Found';
fOnRouterLog(LRouter, rlsRouteNotFound, LContext); fOnRouterLog(LRouter, rlsRouteNotFound, LContext);
raise EMVCException.Create(LContext.Response.StatusCode, LContext.Response.ReasonString); raise EMVCException.Create(
LContext.Response.ReasonString,
LContext.Request.HTTPMethodAsString + ' ' + LContext.Request.PathInfo,
0,
HTTP_STATUS.NotFound
);
end; end;
end end
else else

View File

@ -1,2 +1,2 @@
const const
DMVCFRAMEWORK_VERSION = '3.2.0 (boron) RC6'; DMVCFRAMEWORK_VERSION = '3.2.0 (boron) RC7';

301
tasks.py
View File

@ -1,4 +1,4 @@
from invoke import task, context from invoke import task, context, Exit
import os import os
import subprocess import subprocess
from colorama import * from colorama import *
@ -17,25 +17,32 @@ DEFAULT_DELPHI_VERSION = "10.3"
g_releases_path = "releases" g_releases_path = "releases"
g_output = "bin" g_output = "bin"
g_output_folder = "" # defined at runtime g_output_folder = "" # defined at runtime
g_version = 'DEV' g_version = "DEV"
def get_delphi_projects_to_build(which='', delphi_version=DEFAULT_DELPHI_VERSION): def get_delphi_projects_to_build(which="", delphi_version=DEFAULT_DELPHI_VERSION):
projects = [] projects = []
dversion = 'd' + delphi_version.replace('.', '') dversion = "d" + delphi_version.replace(".", "")
if not which or which == 'core': if not which or which == "core":
projects += glob.glob(r"packages\{dversion}\*.groupproj".format(dversion=dversion)) projects += glob.glob(
r"packages\{dversion}\*.groupproj".format(dversion=dversion)
)
projects += glob.glob(r"tools\entitygenerator\MVCAREntitiesGenerator.dproj") projects += glob.glob(r"tools\entitygenerator\MVCAREntitiesGenerator.dproj")
if not which or which == 'tests': if not which or which == "tests":
projects += glob.glob(r"unittests\**\*.dproj") projects += glob.glob(r"unittests\**\*.dproj")
if not which or which == 'samples': if not which or which == "samples":
projects += glob.glob(r"samples\**\*.dproj") projects += glob.glob(r"samples\**\*.dproj")
projects += glob.glob(r"samples\**\**\*.dproj") projects += glob.glob(r"samples\**\**\*.dproj")
projects += glob.glob(r"samples\**\**\**\*.dproj") projects += glob.glob(r"samples\**\**\**\*.dproj")
return sorted(projects) return sorted(projects)
def build_delphi_project(ctx: context.Context, project_filename, config='DEBUG', delphi_version=DEFAULT_DELPHI_VERSION): def build_delphi_project(
ctx: context.Context,
project_filename,
config="DEBUG",
delphi_version=DEFAULT_DELPHI_VERSION,
):
delphi_versions = { delphi_versions = {
"XE7": {"path": "15.0", "desc": "Delphi XE7"}, "XE7": {"path": "15.0", "desc": "Delphi XE7"},
"XE8": {"path": "16.0", "desc": "Delphi XE8"}, "XE8": {"path": "16.0", "desc": "Delphi XE8"},
@ -45,22 +52,39 @@ def build_delphi_project(ctx: context.Context, project_filename, config='DEBUG',
"10.3": {"path": "20.0", "desc": "Delphi 10.3 Rio"}, "10.3": {"path": "20.0", "desc": "Delphi 10.3 Rio"},
} }
assert delphi_version in delphi_versions, "Invalid Delphi version: " + delphi_version assert delphi_version in delphi_versions, (
"Invalid Delphi version: " + delphi_version
)
print("[" + delphi_versions[delphi_version]["desc"] + "] ", end="") print("[" + delphi_versions[delphi_version]["desc"] + "] ", end="")
version_path = delphi_versions[delphi_version]["path"] version_path = delphi_versions[delphi_version]["path"]
rsvars_path = f'C:\\Program Files (x86)\\Embarcadero\\Studio\\{version_path}\\bin\\rsvars.bat' rsvars_path = (
f"C:\\Program Files (x86)\\Embarcadero\\Studio\\{version_path}\\bin\\rsvars.bat"
)
if not os.path.isfile(rsvars_path): if not os.path.isfile(rsvars_path):
rsvars_path = f'D:\\Program Files (x86)\\Embarcadero\\Studio\\{version_path}\\bin\\rsvars.bat' rsvars_path = f"D:\\Program Files (x86)\\Embarcadero\\Studio\\{version_path}\\bin\\rsvars.bat"
if not os.path.isfile(rsvars_path): if not os.path.isfile(rsvars_path):
raise Exception("Cannot find rsvars.bat") raise Exception("Cannot find rsvars.bat")
cmdline = '"' + rsvars_path + '"' + " & msbuild /t:Build /p:Config=" + config + " /p:Platform=Win32 \"" + project_filename + "\"" cmdline = (
'"'
+ rsvars_path
+ '"'
+ " & msbuild /t:Build /p:Config="
+ config
+ ' /p:Platform=Win32 "'
+ project_filename
+ '"'
)
return ctx.run(cmdline, hide=True, warn=True) return ctx.run(cmdline, hide=True, warn=True)
def zip_samples(version): def zip_samples(version):
global g_output_folder global g_output_folder
cmdline = "7z a " + g_output_folder + f"\\..\\{version}_samples.zip -r -i@7ziplistfile.txt" cmdline = (
"7z a "
+ g_output_folder
+ f"\\..\\{version}_samples.zip -r -i@7ziplistfile.txt"
)
return subprocess.call(cmdline, shell=True) == 0 return subprocess.call(cmdline, shell=True) == 0
@ -91,15 +115,17 @@ def copy_sources():
# copying tools # copying tools
print("Copying tools...") print("Copying tools...")
copytree('tools\\entitygenerator', g_output_folder + "\\tools\\entitygenerator") copytree("tools\\entitygenerator", g_output_folder + "\\tools\\entitygenerator")
#copytree('tools\\rql2sql', g_output_folder + "\\tools\\rql2sql") # copytree('tools\\rql2sql', g_output_folder + "\\tools\\rql2sql")
# copying ideexperts # copying ideexperts
print("Copying DMVCFramework IDEExpert...") print("Copying DMVCFramework IDEExpert...")
src = glob.glob("ideexpert\\*.pas") + \ src = (
glob.glob("ideexpert\\*.dfm") + \ glob.glob("ideexpert\\*.pas")
glob.glob("ideexpert\\*.ico") + \ + glob.glob("ideexpert\\*.dfm")
glob.glob("ideexpert\\*.bmp") + glob.glob("ideexpert\\*.ico")
+ glob.glob("ideexpert\\*.bmp")
)
for file in src: for file in src:
print("Copying " + file + " to " + g_output_folder + "\\ideexpert") print("Copying " + file + " to " + g_output_folder + "\\ideexpert")
@ -111,27 +137,23 @@ def copy_sources():
"dmvcframeworkRT.dproj", "dmvcframeworkRT.dproj",
"dmvcframeworkRT.dpk", "dmvcframeworkRT.dpk",
"dmvcframeworkDT.dproj", "dmvcframeworkDT.dproj",
"dmvcframeworkDT.dpk" "dmvcframeworkDT.dpk",
] ]
folders = [ folders = ["d100", "d101", "d102", "d103"]
"d100",
"d101",
"d102",
"d103"
]
for folder in folders: for folder in folders:
print(f"Copying DMVCFramework Delphi {folder} packages...") print(f"Copying DMVCFramework Delphi {folder} packages...")
for file in files: for file in files:
os.makedirs(g_output_folder + f"\\packages\\{folder}", exist_ok=True) os.makedirs(g_output_folder + f"\\packages\\{folder}", exist_ok=True)
copy2(rf"packages\{folder}\{file}", g_output_folder + rf"\packages\{folder}") copy2(
rf"packages\{folder}\{file}", g_output_folder + rf"\packages\{folder}"
)
def copy_libs(ctx): def copy_libs(ctx):
global g_output_folder global g_output_folder
# swagdoc # swagdoc
print("Copying libraries: SwagDoc...") print("Copying libraries: SwagDoc...")
curr_folder = g_output_folder + "\\lib\\swagdoc" curr_folder = g_output_folder + "\\lib\\swagdoc"
@ -179,7 +201,7 @@ def copy_libs(ctx):
def printkv(key, value): def printkv(key, value):
print(Fore.RESET + key + ': ' + Fore.GREEN + value.rjust(60) + Fore.RESET) print(Fore.RESET + key + ": " + Fore.GREEN + value.rjust(60) + Fore.RESET)
def init_build(version): def init_build(version):
@ -208,17 +230,19 @@ def init_build(version):
copy2("License.txt", g_output_folder) copy2("License.txt", g_output_folder)
def build_delphi_project_list(ctx, projects, config="DEBUG", filter='', delphi_version=DEFAULT_DELPHI_VERSION): def build_delphi_project_list(
ctx, projects, config="DEBUG", filter="", delphi_version=DEFAULT_DELPHI_VERSION
):
ret = True ret = True
for delphi_project in projects: for delphi_project in projects:
if filter and (not filter in delphi_project): if filter and (not filter in delphi_project):
print(f"Skipped {os.path.basename(delphi_project)}") print(f"Skipped {os.path.basename(delphi_project)}")
continue continue
msg = f"Building: {os.path.basename(delphi_project)} ({config})" msg = f"Building: {os.path.basename(delphi_project)} ({config})"
print(Fore.RESET + msg.ljust(90, '.'), end="") print(Fore.RESET + msg.ljust(90, "."), end="")
res = build_delphi_project(ctx, delphi_project, 'DEBUG', delphi_version) res = build_delphi_project(ctx, delphi_project, "DEBUG", delphi_version)
if res.ok: if res.ok:
print(Fore.GREEN + 'OK' + Fore.RESET) print(Fore.GREEN + "OK" + Fore.RESET)
else: else:
ret = False ret = False
print(Fore.RED + "\n\nBUILD ERROR") print(Fore.RED + "\n\nBUILD ERROR")
@ -232,75 +256,84 @@ def build_delphi_project_list(ctx, projects, config="DEBUG", filter='', delphi_v
def tests(ctx, delphi_version=DEFAULT_DELPHI_VERSION): def tests(ctx, delphi_version=DEFAULT_DELPHI_VERSION):
"""Builds and execute the unit tests""" """Builds and execute the unit tests"""
import os import os
apppath = os.path.dirname(os.path.realpath(__file__)) apppath = os.path.dirname(os.path.realpath(__file__))
res = True res = True
tests = [ testclient = r"unittests\general\Several\DMVCFrameworkTests.dproj"
r"unittests\serializer\jsondataobjects\TestSerializerJsonDataObjects.dproj" testserver = r"unittests\general\TestServer\TestServer.dproj"
]
testsexe = [ build_delphi_project(ctx, testclient, config="CI", delphi_version=delphi_version)
r"unittests\serializer\jsondataobjects\Win32\CI\TestSerializerJsonDataObjects.exe" build_delphi_project(ctx, testserver, config="CI", delphi_version=delphi_version)
]
i = 0 # import subprocess
for test_project in tests: # subprocess.run([r"unittests\general\TestServer\Win32\Debug\TestServer.exe"])
res = build_delphi_project(ctx, test_project, 'CI', delphi_version) and res # os.spawnl(os.P_NOWAIT, r"unittests\general\TestServer\Win32\Debug\TestServer.exe")
if res: import subprocess
exename = apppath + "\\" + testsexe[i]
printkv("Running", exename) subprocess.Popen([r"unittests\general\TestServer\Win32\Debug\TestServer.exe"])
res = ctx.run(exename, hide=False) r = subprocess.run([r"unittests\general\Several\bin\DMVCFrameworkTests.exe"])
if not res: subprocess.run(["taskkill", "/f", "/im", "TestServer.exe"])
print("UnitTest execution failed!") if r.returncode > 0:
return False print(r)
i = i + 1 return Exit("Unit tests failed")
return res
@task @task
def clean(ctx): def clean(ctx, folder=None):
global g_output_folder global g_output_folder
import os import os
import glob import glob
print(f"Cleaning from {g_output_folder}...")
output = pathlib.Path(g_output_folder)
rmtree(g_output_folder + r"\lib\loggerpro\Win32", True)
rmtree(g_output_folder + r"\lib\loggerpro\packages\d101\__history", True)
rmtree(g_output_folder + r"\lib\loggerpro\packages\d101\Win32\Debug", True)
rmtree(g_output_folder + r"\lib\loggerpro\packages\d102\__history", True)
rmtree(g_output_folder + r"\lib\loggerpro\packages\d102\Win32\Debug", True)
rmtree(g_output_folder + r"\lib\loggerpro\packages\d103\__history", True)
rmtree(g_output_folder + r"\lib\loggerpro\packages\d103\Win32\Debug", True)
rmtree(g_output_folder + r"\lib\dmustache\.git", True)
rmtree(g_output_folder + r"\lib\swagdoc\lib", True)
rmtree(g_output_folder + r"\lib\swagdoc\deploy", True)
rmtree(g_output_folder + r"\lib\swagdoc\demos", True)
if folder is None:
folder = g_output_folder
print(f"Cleaning folder {folder}")
output = pathlib.Path(folder)
to_delete = [] to_delete = []
to_delete += glob.glob(g_output_folder + r"\**\*.exe", recursive=True) to_delete += glob.glob(folder + r"\**\*.exe", recursive=True)
to_delete += glob.glob(g_output_folder + r"\**\*.dcu", recursive=True) to_delete += glob.glob(folder + r"\**\*.dcu", recursive=True)
to_delete += glob.glob(g_output_folder + r"\**\*.stat", recursive=True) to_delete += glob.glob(folder + r"\**\*.stat", recursive=True)
to_delete += glob.glob(g_output_folder + r"\**\*.res", recursive=True) to_delete += glob.glob(folder + r"\**\*.res", recursive=True)
to_delete += glob.glob(g_output_folder + r"\**\*.map", recursive=True) to_delete += glob.glob(folder + r"\**\*.map", recursive=True)
to_delete += glob.glob(g_output_folder + r"\**\*.~*", recursive=True) to_delete += glob.glob(folder + r"\**\*.~*", recursive=True)
to_delete += glob.glob(g_output_folder + r"\**\*.rsm", recursive=True) to_delete += glob.glob(folder + r"\**\*.rsm", recursive=True)
to_delete += glob.glob(g_output_folder + r"\**\*.drc", recursive=True) to_delete += glob.glob(folder + r"\**\*.drc", recursive=True)
to_delete += glob.glob(g_output_folder + r"\**\*.log", recursive=True) to_delete += glob.glob(folder + r"\**\*.log", recursive=True)
to_delete += glob.glob(g_output_folder + r"\**\*.local", recursive=True) to_delete += glob.glob(folder + r"\**\*.local", recursive=True)
to_delete += glob.glob(g_output_folder + r"\**\*.gitignore", recursive=True) to_delete += glob.glob(folder + r"\**\*.gitignore", recursive=True)
to_delete += glob.glob(g_output_folder + r"\**\*.gitattributes", recursive=True) to_delete += glob.glob(folder + r"\**\*.gitattributes", recursive=True)
for f in to_delete: for f in to_delete:
print(f"Deleting {f}")
os.remove(f) os.remove(f)
rmtree(folder + r"\lib\loggerpro\Win32", True)
rmtree(folder + r"\lib\loggerpro\packages\d100\__history", True)
rmtree(folder + r"\lib\loggerpro\packages\d100\Win32\Debug", True)
rmtree(folder + r"\lib\loggerpro\packages\d101\__history", True)
rmtree(folder + r"\lib\loggerpro\packages\d101\Win32\Debug", True)
rmtree(folder + r"\lib\loggerpro\packages\d102\__history", True)
rmtree(folder + r"\lib\loggerpro\packages\d102\Win32\Debug", True)
rmtree(folder + r"\lib\loggerpro\packages\d103\__history", True)
rmtree(folder + r"\lib\loggerpro\packages\d103\Win32\Debug", True)
rmtree(folder + r"\lib\dmustache\.git", True)
rmtree(folder + r"\lib\swagdoc\lib", True)
rmtree(folder + r"\lib\swagdoc\deploy", True)
rmtree(folder + r"\lib\swagdoc\demos", True)
@task(pre=[tests]) @task(pre=[tests])
def release(ctx, version="DEBUG", delphi_version=DEFAULT_DELPHI_VERSION, skip_build=False): def release(
ctx, version="DEBUG", delphi_version=DEFAULT_DELPHI_VERSION, skip_build=False
):
"""Builds all the projects, executes integration tests and prepare the release""" """Builds all the projects, executes integration tests and prepare the release"""
init_build(version) init_build(version)
if not skip_build: if not skip_build:
delphi_projects = get_delphi_projects_to_build('', delphi_version) delphi_projects = get_delphi_projects_to_build("", delphi_version)
if not build_delphi_project_list(ctx, delphi_projects, version, '', delphi_version): if not build_delphi_project_list(
return False #fails build ctx, delphi_projects, version, "", delphi_version
):
return False # fails build
print(Fore.RESET) print(Fore.RESET)
copy_sources() copy_sources()
copy_libs(ctx) copy_libs(ctx)
@ -310,20 +343,25 @@ def release(ctx, version="DEBUG", delphi_version=DEFAULT_DELPHI_VERSION, skip_bu
@task @task
def build_samples(ctx, version="DEBUG", filter="", delphi_version=DEFAULT_DELPHI_VERSION): def build_samples(
ctx, version="DEBUG", filter="", delphi_version=DEFAULT_DELPHI_VERSION
):
"""Builds samples""" """Builds samples"""
init_build(version) init_build(version)
delphi_projects = get_delphi_projects_to_build('samples', delphi_version) delphi_projects = get_delphi_projects_to_build("samples", delphi_version)
return build_delphi_project_list(ctx, delphi_projects, version, filter, delphi_version) return build_delphi_project_list(
ctx, delphi_projects, version, filter, delphi_version
)
@task @task(post=[tests])
def build_core(ctx, version="DEBUG", delphi_version=DEFAULT_DELPHI_VERSION): def build_core(ctx, version="DEBUG", delphi_version=DEFAULT_DELPHI_VERSION):
"""Builds core packages extensions""" """Builds core packages extensions"""
init_build(version) init_build(version)
delphi_projects = get_delphi_projects_to_build('core', delphi_version) delphi_projects = get_delphi_projects_to_build("core", delphi_version)
return build_delphi_project_list(ctx, delphi_projects, version, '', delphi_version) ret = build_delphi_project_list(ctx, delphi_projects, version, "", delphi_version)
if not ret:
raise Exit("Build failed")
def parse_template(tmpl: List[str]): def parse_template(tmpl: List[str]):
@ -331,49 +369,60 @@ def parse_template(tmpl: List[str]):
intf_tmpl = [] intf_tmpl = []
impl_tmpl = [] impl_tmpl = []
state = 'verbatim' state = "verbatim"
for row in tmpl: for row in tmpl:
if row.upper().strip() == '///INTERFACE.BEGIN': if row.upper().strip() == "///INTERFACE.BEGIN":
state = 'parsing.interface' state = "parsing.interface"
continue continue
if row.upper().strip() == '///IMPLEMENTATION.BEGIN': if row.upper().strip() == "///IMPLEMENTATION.BEGIN":
state = 'parsing.implementation' state = "parsing.implementation"
continue continue
if row.upper().strip() in ['///INTERFACE.END','///IMPLEMENTATION.END']: if row.upper().strip() in ["///INTERFACE.END", "///IMPLEMENTATION.END"]:
if state == 'parsing.interface': if state == "parsing.interface":
main_tmpl.append('$INTERFACE$') main_tmpl.append("$INTERFACE$")
if state == 'parsing.implementation': if state == "parsing.implementation":
main_tmpl.append('$IMPLEMENTATION$') main_tmpl.append("$IMPLEMENTATION$")
state = 'verbatim' state = "verbatim"
continue continue
if state == 'parsing.interface': if state == "parsing.interface":
intf_tmpl.append(row) intf_tmpl.append(row)
elif state == 'parsing.implementation': elif state == "parsing.implementation":
impl_tmpl.append(row) impl_tmpl.append(row)
elif state == 'verbatim': elif state == "verbatim":
main_tmpl.append(row) main_tmpl.append(row)
return main_tmpl, intf_tmpl, impl_tmpl return main_tmpl, intf_tmpl, impl_tmpl
@task @task
def generate_nullables(ctx): def generate_nullables(ctx):
import pathlib import pathlib
src_folder = pathlib.Path(__file__).parent.joinpath("sources") src_folder = pathlib.Path(__file__).parent.joinpath("sources")
template_unitname = src_folder.joinpath("MVCFramework.Nullables.pas.template") template_unitname = src_folder.joinpath("MVCFramework.Nullables.pas.template")
output_unitname = src_folder.joinpath("MVCFramework.Nullables.pas") output_unitname = src_folder.joinpath("MVCFramework.Nullables.pas")
with open(template_unitname, 'r') as f: with open(template_unitname, "r") as f:
rows = f.readlines() rows = f.readlines()
main_tmpl, intf_tmpl, impl_tmpl = parse_template(rows) main_tmpl, intf_tmpl, impl_tmpl = parse_template(rows)
delphi_types = [ delphi_types = [
'String','Currency','Boolean', "String",
'TDate','TTime','TDateTime', "Currency",
'Single','Double','Extended', "Boolean",
'Int16','UInt16', "TDate",
'Int32','UInt32', "TTime",
'Int64','UInt64' "TDateTime",
"Single",
"Double",
"Extended",
"Int16",
"UInt16",
"Int32",
"UInt32",
"Int64",
"UInt64",
] ]
str_main_tmpl = "".join(main_tmpl) str_main_tmpl = "".join(main_tmpl)
@ -383,28 +432,24 @@ def generate_nullables(ctx):
intf_out = "" intf_out = ""
impl_out = "" impl_out = ""
for delphi_type in delphi_types: for delphi_type in delphi_types:
intf_out += f"//**************************\n// ** Nullable{delphi_type}\n//**************************\n\n" + \ intf_out += (
str_intf_tmpl.replace('$TYPE$',delphi_type) f"//**************************\n// ** Nullable{delphi_type}\n//**************************\n\n"
impl_out += str_impl_tmpl.replace('$TYPE$',delphi_type) + "\n" + str_intf_tmpl.replace("$TYPE$", delphi_type)
)
impl_out += str_impl_tmpl.replace("$TYPE$", delphi_type) + "\n"
str_main_tmpl = str_main_tmpl \ str_main_tmpl = str_main_tmpl.replace("$INTERFACE$", intf_out).replace(
.replace('$INTERFACE$',intf_out) \ "$IMPLEMENTATION$", impl_out
.replace('$IMPLEMENTATION$', impl_out) )
with open(output_unitname, "w") as f:
with open(output_unitname, 'w') as f:
f.writelines(str_main_tmpl) f.writelines(str_main_tmpl)
with open(src_folder.joinpath('main.out.txt'), 'w') as f: with open(src_folder.joinpath("main.out.txt"), "w") as f:
f.writelines(main_tmpl) f.writelines(main_tmpl)
with open(src_folder.joinpath('interface.out.txt'), 'w') as f: with open(src_folder.joinpath("interface.out.txt"), "w") as f:
f.writelines(intf_tmpl) f.writelines(intf_tmpl)
with open(src_folder.joinpath('implementation.out.txt'), 'w') as f: with open(src_folder.joinpath("implementation.out.txt"), "w") as f:
f.writelines(impl_tmpl) f.writelines(impl_tmpl)

View File

@ -133,11 +133,13 @@
<PropertyGroup Condition="'$(Cfg_4_Win32)'!=''"> <PropertyGroup Condition="'$(Cfg_4_Win32)'!=''">
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<DCC_ExeOutput>.\bin</DCC_ExeOutput>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_5_Win32)'!=''"> <PropertyGroup Condition="'$(Cfg_5_Win32)'!=''">
<DCC_Define>CI;$(DCC_Define)</DCC_Define> <DCC_Define>CI;$(DCC_Define)</DCC_Define>
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<DCC_ExeOutput>.\bin</DCC_ExeOutput>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_3)'!=''"> <PropertyGroup Condition="'$(Cfg_3)'!=''">
<DCC_UnitSearchPath>$(BDS)\source\DunitX;$(DCC_UnitSearchPath)</DCC_UnitSearchPath> <DCC_UnitSearchPath>$(BDS)\source\DunitX;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
@ -146,6 +148,7 @@
<PropertyGroup Condition="'$(Cfg_3_Win32)'!=''"> <PropertyGroup Condition="'$(Cfg_3_Win32)'!=''">
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes> <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<DCC_ExeOutput>.\bin</DCC_ExeOutput>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''"> <PropertyGroup Condition="'$(Cfg_2)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys> <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>

View File

@ -461,9 +461,13 @@ begin
end; end;
procedure TTestServerController.TestGetImagePng; procedure TTestServerController.TestGetImagePng;
var
lFName: string;
begin begin
ContentType := TMVCMediaType.IMAGE_PNG; ContentType := TMVCMediaType.IMAGE_PNG;
Render(TFile.OpenRead('..\..\sample.png')); lFName := TPath.Combine(TPath.GetDirectoryName(ParamStr(0)), '..\..') + '\sample.png';
//Render(TFile.OpenRead('..\..\sample.png'));
Render(TFile.OpenRead(lFName));
end; end;
procedure TTestServerController.TestGetPersonByID; procedure TTestServerController.TestGetPersonByID;