#wip(py,sql,cs,js): Starting project.
This commit is contained in:
parent
42126e52f2
commit
58548a6576
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/Data
|
||||||
|
/Public/data
|
||||||
|
__pycache__
|
||||||
|
.sass-cache
|
||||||
|
*.[Ss]ecret.*
|
||||||
|
*.[Ss]ecrets.*
|
||||||
|
*.deleted.*
|
||||||
|
/CSharp/bin
|
||||||
|
/CSharp/obj
|
||||||
|
/SQLServer/data
|
||||||
|
/SQLServer/scripts
|
||||||
|
/SQLServer/temporary
|
||||||
29
AnPv2.sln.old
Normal file
29
AnPv2.sln.old
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.5.2.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CSharp", "CSharp", "{B41BF331-FCCB-2ADF-CDB6-767964B34647}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnP", "CSharp\AnP.csproj", "{720E15E3-2F0D-4B91-98F1-400300826A0A}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{720E15E3-2F0D-4B91-98F1-400300826A0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{720E15E3-2F0D-4B91-98F1-400300826A0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{720E15E3-2F0D-4B91-98F1-400300826A0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{720E15E3-2F0D-4B91-98F1-400300826A0A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{720E15E3-2F0D-4B91-98F1-400300826A0A} = {B41BF331-FCCB-2ADF-CDB6-767964B34647}
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {47442BB3-05F5-4AAF-A859-D456A81FC0A2}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
23
CSharp/AnP.csproj
Executable file
23
CSharp/AnP.csproj
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFrameworks>net10.0;net462</TargetFrameworks>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
<RootNamespace>AnP</RootNamespace>
|
||||||
|
<AssemblyName>AnP</AssemblyName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
3
CSharp/AnP.slnx
Executable file
3
CSharp/AnP.slnx
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
<Solution>
|
||||||
|
<Project Path="AnP.csproj" />
|
||||||
|
</Solution>
|
||||||
9
CSharp/Application/AnP.cs
Executable file
9
CSharp/Application/AnP.cs
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
using AnP.Interfaces.Application;
|
||||||
|
|
||||||
|
namespace AnP.Application{
|
||||||
|
class AnP:AnPInterface{
|
||||||
|
|
||||||
|
public AnP(object? inputs = null){}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
5
CSharp/Interfaces/Application/AnPInterface.cs
Normal file
5
CSharp/Interfaces/Application/AnPInterface.cs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
namespace AnP.Interfaces.Application{
|
||||||
|
public interface AnPInterface{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
14
CSharp/Interfaces/Managers/I18NManagerInterface.cs
Normal file
14
CSharp/Interfaces/Managers/I18NManagerInterface.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace AnP.Interface.Managers{
|
||||||
|
|
||||||
|
public interface I18NManagerInterface{
|
||||||
|
|
||||||
|
public string get(List<string> strings, object? inputs = null, List<string>? languages = null, int custom_options = 0);
|
||||||
|
|
||||||
|
public void add(object? items, int custom_options = 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
58
CSharp/Managers/I18NManager.cs
Normal file
58
CSharp/Managers/I18NManager.cs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using AnP.Types;
|
||||||
|
using AnP.Utils;
|
||||||
|
using AnP.Interfaces.Application;
|
||||||
|
|
||||||
|
namespace AnP.Managers{
|
||||||
|
public class I18NManager{
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, Dictionary<string, I18NSentenceType>> DEFAULT_SENTENCES = new Dictionary<string, Dictionary<string, I18NSentenceType>>{
|
||||||
|
{"english", new Dictionary<string, I18NSentenceType>{
|
||||||
|
{"greeting", new I18NSentenceType.Text("Hello, World!")}
|
||||||
|
}}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly Options GET_OPTIONS = new Options();
|
||||||
|
|
||||||
|
public AnPInterface anp;
|
||||||
|
private Dictionary<string, Dictionary<string, I18NSentenceType>> sentences;
|
||||||
|
private string language;
|
||||||
|
private string default_language;
|
||||||
|
|
||||||
|
public I18NManager(AnPInterface anp){
|
||||||
|
this.anp = anp;
|
||||||
|
sentences = new Dictionary<string, Dictionary<string, I18NSentenceType>>(DEFAULT_SENTENCES);
|
||||||
|
language = default_language = "english";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string get(object strings, object? inputs = null, object? languages = null, int custom_options = 0){
|
||||||
|
|
||||||
|
List<string> keys = Common.get_keys(strings);
|
||||||
|
Options options = new Options(custom_options, GET_OPTIONS);
|
||||||
|
|
||||||
|
if(keys.Count != 0){
|
||||||
|
|
||||||
|
List<string> languages_used = new List<string>();
|
||||||
|
|
||||||
|
foreach(string language in Common.get_keys(languages).Concat<string>(
|
||||||
|
new List<string>{this.language, default_language}
|
||||||
|
).Concat<string>(sentences.Keys))
|
||||||
|
if(!languages_used.Contains(language)){
|
||||||
|
languages_used.Add(language);
|
||||||
|
if(sentences.ContainsKey(language))
|
||||||
|
foreach(string key in keys)
|
||||||
|
if(sentences[language].ContainsKey(key))
|
||||||
|
return sentences[language][key] switch{
|
||||||
|
I18NSentenceType.Text text => text.value,
|
||||||
|
I18NSentenceType.List list => string.Join("", list.value),
|
||||||
|
_ => ""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return Common.get_strings(strings).FirstOrDefault() ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(object? items, int custom_options = 0){}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
31
CSharp/Managers/SettingsManager.cs
Normal file
31
CSharp/Managers/SettingsManager.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using AnP.Utils;
|
||||||
|
using AnP.Interfaces.Application;
|
||||||
|
|
||||||
|
namespace AnP.Managers{
|
||||||
|
public class SettingsManager{
|
||||||
|
|
||||||
|
public static readonly Dictionary<string, object?> DEFAULT_SETTINGS = new Dictionary<string, object?>{};
|
||||||
|
public static readonly Options GET_OPTIONS = new Options(Options.ALLOW_NULLS);
|
||||||
|
public static readonly Options ADD_OPTIONS = new Options(Options.NO_OVERWRITE);
|
||||||
|
|
||||||
|
public AnPInterface anp;
|
||||||
|
public Dictionary<string, object?> settings = new Dictionary<string, object?>(){};
|
||||||
|
public Dictionary<string, object?> secrets = new Dictionary<string, object?>(){};
|
||||||
|
public Dictionary<string, object?> inputs;
|
||||||
|
|
||||||
|
public SettingsManager(AnPInterface anp, object? inputs = null){
|
||||||
|
this.anp = anp;
|
||||||
|
this.inputs = Common.get_dictionary<object?>(inputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T? get<T>(object keys, object? inputs, T? _default = default(T?), int custom_options = 0){
|
||||||
|
return Common.get<T>(keys, new object?[]{
|
||||||
|
inputs, this.inputs, secrets, settings, DEFAULT_SETTINGS
|
||||||
|
}, _default, new Options(custom_options, GET_OPTIONS).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(object? items, int custom_options = 0){}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
9
CSharp/Program.cs
Executable file
9
CSharp/Program.cs
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace AnP{
|
||||||
|
class Program{
|
||||||
|
static void Main(string[] args){
|
||||||
|
Console.WriteLine("Hello World!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
CSharp/Types/ColorType.cs
Normal file
14
CSharp/Types/ColorType.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using AnP.Utils;
|
||||||
|
|
||||||
|
namespace AnP.Types{
|
||||||
|
public abstract record ColorType{
|
||||||
|
|
||||||
|
private ColorType(){}
|
||||||
|
|
||||||
|
public sealed record String(string value):ColorType;
|
||||||
|
public sealed record List(IEnumerable<string> value):ColorType;
|
||||||
|
public sealed record Integer(int value):ColorType;
|
||||||
|
public sealed record Instance(Color value):ColorType;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
10
CSharp/Types/I18NSentenceType.cs
Normal file
10
CSharp/Types/I18NSentenceType.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace AnP.Types{
|
||||||
|
public abstract record I18NSentenceType{
|
||||||
|
|
||||||
|
private I18NSentenceType(){}
|
||||||
|
|
||||||
|
public sealed record Text(string value):I18NSentenceType;
|
||||||
|
public sealed record List(IEnumerable<string> value):I18NSentenceType;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
41
CSharp/Utils/Check.cs
Executable file
41
CSharp/Utils/Check.cs
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AnP.Utils{
|
||||||
|
public class Check{
|
||||||
|
|
||||||
|
public static bool is_string(object? item){
|
||||||
|
return item is string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static bool is_key(object? item){
|
||||||
|
return item is string && RE.KEY.IsMatch((string)item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool is_dictionary<T>(object? item){
|
||||||
|
return item is IDictionary<string, T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool is_dictionary(object? item){
|
||||||
|
return item is IDictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool is_array<T>(object? item){
|
||||||
|
return item is IEnumerable<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool is_array(object? item){
|
||||||
|
return item is IEnumerable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool is_integer(object? item){
|
||||||
|
return item is int;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool is_float(object? item){
|
||||||
|
return item is float || item is double || item is decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
140
CSharp/Utils/Color.cs
Executable file
140
CSharp/Utils/Color.cs
Executable file
@ -0,0 +1,140 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AnP.Utils{
|
||||||
|
public class Color{
|
||||||
|
|
||||||
|
public int red = 0x00;
|
||||||
|
public int green = 0x00;
|
||||||
|
public int blue = 0x00;
|
||||||
|
public int alpha = 0xFF;
|
||||||
|
|
||||||
|
public Color(string code){
|
||||||
|
|
||||||
|
if(code.StartsWith("#")){
|
||||||
|
|
||||||
|
code = code.Substring(1);
|
||||||
|
|
||||||
|
if(code.Length == 3 || code.Length == 4)
|
||||||
|
code = string.Concat(code.Select(c => $"{c}{c}"));
|
||||||
|
code = code.PadLeft(8, 'F');
|
||||||
|
|
||||||
|
alpha = Convert.ToInt32(code.Substring(0, 2), 16);
|
||||||
|
red = Convert.ToInt32(code.Substring(2, 2), 16);
|
||||||
|
green = Convert.ToInt32(code.Substring(4, 2), 16);
|
||||||
|
blue = Convert.ToInt32(code.Substring(6, 2), 16);
|
||||||
|
|
||||||
|
}else if(code.StartsWith("rgb")){
|
||||||
|
|
||||||
|
string[] items = code.Substring(code.IndexOf("(") + 1, code.LastIndexOf(")") - code.IndexOf("(") - 1).Split(",");
|
||||||
|
|
||||||
|
red = items.Length > 0 ? Convert.ToInt32(items[0]) : 0;
|
||||||
|
green = items.Length > 1 ? Convert.ToInt32(items[1]) : 0;
|
||||||
|
blue = items.Length > 2 ? Convert.ToInt32(items[2]) : 0;
|
||||||
|
alpha = items.Length > 3 ? (
|
||||||
|
items[3].Contains(".") ? (int)(Convert.ToSingle(items[3]) * 0xFF) :
|
||||||
|
Convert.ToInt32(items[3])) : 0xFF;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color(int color){
|
||||||
|
alpha = 0xFF - ((color >> 24) & 0xFF);
|
||||||
|
red = (color >> 16) & 0xFF;
|
||||||
|
green = (color >> 8) & 0xFF;
|
||||||
|
blue = color & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color(IEnumerable inputs, string type = "rgba"){
|
||||||
|
|
||||||
|
object[] array = ((IEnumerable)inputs).Cast<object>().ToArray();
|
||||||
|
|
||||||
|
if(type == "rgb" || type == "rgba" || true){
|
||||||
|
red = array.Length > 0 ? (int)array[0] : 0;
|
||||||
|
green = array.Length > 1 ? (int)array[1] : 0;
|
||||||
|
blue = array.Length > 2 ? (int)array[2] : 0;
|
||||||
|
alpha = array.Length > 3 ? (
|
||||||
|
Check.is_integer(array[3]) ? (int)array[3] :
|
||||||
|
Check.is_float(array[3]) ? (int)((float)array[3] * 0xFF) :
|
||||||
|
0xFF) : 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color(Color color){
|
||||||
|
red = color.red;
|
||||||
|
green = color.green;
|
||||||
|
blue = color.blue;
|
||||||
|
alpha = color.alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string to_rgba(){
|
||||||
|
return $"rgba({red}, {green}, {blue}, {(float)alpha / 0xFF:0.##})";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string to_rgb(){
|
||||||
|
return $"rgb({red}, {green}, {blue})";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string to_hex(bool with_alpha = false){
|
||||||
|
return $"#{(with_alpha ? $"{alpha:X2}" : "")}{red:X2}{green:X2}{blue:X2}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color mix(params object[] colors){
|
||||||
|
if(colors.Length == 0)
|
||||||
|
return new Color(0);
|
||||||
|
|
||||||
|
Color _base;
|
||||||
|
int l = colors.Length;
|
||||||
|
|
||||||
|
if(Check.is_string(colors[0]))
|
||||||
|
_base = new Color((string)colors[0]);
|
||||||
|
else if(Check.is_integer(colors[0]))
|
||||||
|
_base = new Color((int)colors[0]);
|
||||||
|
else if(Check.is_array(colors[0]))
|
||||||
|
_base = new Color((IEnumerable)colors[0]);
|
||||||
|
else if(colors[0] is Color)
|
||||||
|
_base = new Color((Color)colors[0]);
|
||||||
|
else
|
||||||
|
return new Color(0);
|
||||||
|
|
||||||
|
if(l != 1){
|
||||||
|
|
||||||
|
for(int i = 1; i < l; i ++){
|
||||||
|
|
||||||
|
Color subcolor;
|
||||||
|
|
||||||
|
if(Check.is_string(colors[i]))
|
||||||
|
subcolor = new Color((string)colors[i]);
|
||||||
|
else if(Check.is_integer(colors[i]))
|
||||||
|
subcolor = new Color((int)colors[i]);
|
||||||
|
else if(Check.is_array(colors[i]))
|
||||||
|
subcolor = new Color((IEnumerable)colors[i]);
|
||||||
|
else if(colors[i] is Color)
|
||||||
|
subcolor = new Color((Color)colors[i]);
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_base.red += subcolor.red;
|
||||||
|
_base.green += subcolor.green;
|
||||||
|
_base.blue += subcolor.blue;
|
||||||
|
_base.alpha += subcolor.alpha;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_base.red /= l;
|
||||||
|
_base.green /= l;
|
||||||
|
_base.blue /= l;
|
||||||
|
_base.alpha /= l;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return _base;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
99
CSharp/Utils/Common.cs
Executable file
99
CSharp/Utils/Common.cs
Executable file
@ -0,0 +1,99 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AnP.Utils{
|
||||||
|
public class Common{
|
||||||
|
|
||||||
|
public static readonly Options GET_DICTIONARY_OPTIONS = new Options(Options.NO_OVERWRITE);
|
||||||
|
public static readonly Options GET_OPTIONS = new Options(Options.ALLOW_NULLS);
|
||||||
|
|
||||||
|
public static List<string> get_strings(object? items){
|
||||||
|
|
||||||
|
List<string> strings = new List<string>();
|
||||||
|
|
||||||
|
if(items != null){
|
||||||
|
if(Check.is_string(items))
|
||||||
|
strings.Add((string)items);
|
||||||
|
else if(Check.is_array<object>(items))
|
||||||
|
foreach(object item in (IEnumerable<object>)items)
|
||||||
|
if(Check.is_string(item))
|
||||||
|
strings.Add((string)item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<string> get_keys(object? items){
|
||||||
|
|
||||||
|
List<string> keys = new List<string>();
|
||||||
|
|
||||||
|
if(items != null){
|
||||||
|
if(Check.is_key(items))
|
||||||
|
keys.Add((string)items);
|
||||||
|
else if(Check.is_array<object>(items))
|
||||||
|
foreach(object item in (IEnumerable<object>)items)
|
||||||
|
if(Check.is_key(item)){
|
||||||
|
|
||||||
|
string key = (string)item;
|
||||||
|
|
||||||
|
if(!keys.Contains(key))
|
||||||
|
keys.Add(key);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<IDictionary<string, T>> get_dictionaries<T>(object? items){
|
||||||
|
|
||||||
|
List<IDictionary<string, T>> dictionaries = new List<IDictionary<string, T>>();
|
||||||
|
|
||||||
|
if(items != null){
|
||||||
|
if(Check.is_dictionary<T>(items))
|
||||||
|
dictionaries.Add((Dictionary<string, T>)items);
|
||||||
|
else if(Check.is_array<object>(items))
|
||||||
|
foreach(object item in (IEnumerable<object>)items)
|
||||||
|
if(Check.is_dictionary<T>(item))
|
||||||
|
dictionaries.Add((IDictionary<string, T>)item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dictionaries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dictionary<string, T> get_dictionary<T>(object? items, int custom_options = 0){
|
||||||
|
|
||||||
|
Dictionary<string, T> dictionary = new Dictionary<string, T>();
|
||||||
|
Options options = new Options(custom_options, GET_DICTIONARY_OPTIONS);
|
||||||
|
|
||||||
|
if(items != null){
|
||||||
|
if(Check.is_dictionary<T>(items))
|
||||||
|
dictionary = (Dictionary<string, T>)items;
|
||||||
|
else if(Check.is_array<object>(items))
|
||||||
|
foreach(object item in (IEnumerable<object>)items)
|
||||||
|
if(Check.is_dictionary<T>(item))
|
||||||
|
foreach(KeyValuePair<string, T> pair in (IDictionary<string, T>)item)
|
||||||
|
if(options.overwrite == true || !dictionary.ContainsKey(pair.Key))
|
||||||
|
dictionary[pair.Key] = pair.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T? get<T>(object keys, object inputs, T? _default = default(T?), int custom_options = 0){
|
||||||
|
|
||||||
|
Options options = new Options(custom_options, GET_OPTIONS);
|
||||||
|
List<string> keys_list = get_keys(keys);
|
||||||
|
|
||||||
|
if(keys_list.Count != 0)
|
||||||
|
foreach(IDictionary<string, T> subinputs in get_dictionaries<T>(inputs))
|
||||||
|
foreach(string key in keys_list)
|
||||||
|
if(subinputs.ContainsKey(key) && (
|
||||||
|
options.allow_null == true ||
|
||||||
|
subinputs[key] != null
|
||||||
|
))
|
||||||
|
return subinputs[key];
|
||||||
|
return _default;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
57
CSharp/Utils/Options.cs
Executable file
57
CSharp/Utils/Options.cs
Executable file
@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AnP.Utils{
|
||||||
|
public class Options{
|
||||||
|
|
||||||
|
public const int OVERWRITING = 0;
|
||||||
|
public static readonly int OVERWRITE = 1 * (int)Math.Pow(3, OVERWRITING);
|
||||||
|
public static readonly int NO_OVERWRITE = 2 * (int)Math.Pow(3, OVERWRITING);
|
||||||
|
|
||||||
|
public const int NULLISH = 1;
|
||||||
|
public static readonly int ALLOW_NULLS = 1 * (int)Math.Pow(3, NULLISH);
|
||||||
|
public static readonly int NO_NULLS = 2 * (int)Math.Pow(3, NULLISH);
|
||||||
|
|
||||||
|
public static readonly Options DEFAULT = new Options(NO_OVERWRITE + ALLOW_NULLS);
|
||||||
|
|
||||||
|
public static bool? get(int value, int option){
|
||||||
|
|
||||||
|
int ternary = value / (int)Math.Pow(3, option) % 3;
|
||||||
|
|
||||||
|
return (
|
||||||
|
ternary == 1 ? true :
|
||||||
|
ternary == 2 ? false :
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool? overwrite = null;
|
||||||
|
public bool? allow_null = null;
|
||||||
|
|
||||||
|
public Options(int value = 0, Options? _default = null){
|
||||||
|
|
||||||
|
if(_default == null)
|
||||||
|
_default = DEFAULT;
|
||||||
|
|
||||||
|
overwrite = get(value, OVERWRITING) ?? _default?.overwrite;
|
||||||
|
allow_null = get(value, NULLISH) ?? _default?.allow_null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int get(){
|
||||||
|
|
||||||
|
int code = 0;
|
||||||
|
|
||||||
|
foreach(KeyValuePair<int, bool?> pair in new Dictionary<int, bool?>{
|
||||||
|
{OVERWRITING, overwrite},
|
||||||
|
{NULLISH, allow_null}
|
||||||
|
})
|
||||||
|
code += (
|
||||||
|
pair.Value == true ? 1 :
|
||||||
|
pair.Value == false ? 2 :
|
||||||
|
0) * (int)Math.Pow(3, pair.Key);
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
7
CSharp/Utils/Patterns.cs
Executable file
7
CSharp/Utils/Patterns.cs
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace AnP.Utils{
|
||||||
|
public class RE{
|
||||||
|
public static readonly Regex KEY = new Regex(@"^[a-z_][a-z0-9_]*$", RegexOptions.IgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
5
DotNET/Dockerfile
Normal file
5
DotNET/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from mcr.microsoft.com/dotnet/sdk:10.0
|
||||||
|
env dotnet_cli_telemetry_output=1
|
||||||
|
run apt update && apt install -y procps build-essential cmake g++ gdb git
|
||||||
|
run rm -rf /var/lib/apt/lists/*
|
||||||
|
workdir /workspace
|
||||||
4
DotNET/docker.rebuild.sh
Executable file
4
DotNET/docker.rebuild.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
directory=`dirname $(readlink -f "$0")`
|
||||||
|
[ "$(docker images -q anp:dotnet 2>/dev/null)" ] && docker image remove anp:dotnet --force
|
||||||
|
docker build -f $directory/Dockerfile -t anp:dotnet $directory --no-cache
|
||||||
7
DotNET/scripts/entrypoint.sh
Executable file
7
DotNET/scripts/entrypoint.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
trap "exit 0" INT TERM
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
sleep 1 & wait $!
|
||||||
|
done
|
||||||
69
JSON/AnP.settings.json
Normal file
69
JSON/AnP.settings.json
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
|
||||||
|
"anp_start" : null,
|
||||||
|
"anp_show_building_message" : true,
|
||||||
|
"anp_show_built_message" : true,
|
||||||
|
"anp_show_starting_message" : true,
|
||||||
|
"anp_show_already_started_message" : true,
|
||||||
|
"anp_show_started_message" : true,
|
||||||
|
"anp_show_updating_message" : true,
|
||||||
|
"anp_show_updated_message" : true,
|
||||||
|
"anp_show_closing_message" : true,
|
||||||
|
"anp_show_already_closed_message" : true,
|
||||||
|
"anp_show_closed_message" : true,
|
||||||
|
"print_format" : "[{type}] {yyyy}{mm}{dd} {hh}:{ii}:{ss} [{line}]{file_relative}({method}): {message}",
|
||||||
|
"exception_format" : " '{file}({method})[{line}]'{lines}\n\n{message}",
|
||||||
|
"trace_line_format" : " [{i}] {trace_line}",
|
||||||
|
"autostart" : true,
|
||||||
|
"anp_end" : null,
|
||||||
|
|
||||||
|
"anp_print_types_manager_start" : null,
|
||||||
|
"default_print_types" : [
|
||||||
|
["#888", ["unkn", "unknown"]],
|
||||||
|
["#00F", ["info", "information", "default"]],
|
||||||
|
["#FF0", ["warn", "warning", "caution"]],
|
||||||
|
["#F00", ["erro", "err", "no", "x", "n", "error", "panic", "danger", "critical"]],
|
||||||
|
["#0F0", [" ok ", "ok", "yes", "y", "success", "done", "complete"]],
|
||||||
|
["#888", ["test", "debug", "trace", "debugging"]],
|
||||||
|
["#F00", ["exce", "except", "exception"]]
|
||||||
|
],
|
||||||
|
"anp_print_types_manager_show_building_message" : true,
|
||||||
|
"anp_print_types_manager_show_built_message" : true,
|
||||||
|
"anp_print_types_manager_show_starting_message" : true,
|
||||||
|
"anp_print_types_manager_show_already_started_message" : true,
|
||||||
|
"anp_print_types_manager_show_started_message" : true,
|
||||||
|
"anp_print_types_manager_show_updating_message" : true,
|
||||||
|
"anp_print_types_manager_show_updated_message" : true,
|
||||||
|
"anp_print_types_manager_show_closing_message" : true,
|
||||||
|
"anp_print_types_manager_show_already_closed_message" : true,
|
||||||
|
"anp_print_types_manager_show_closed_message" : true,
|
||||||
|
"anp_print_types_manager_end" : null,
|
||||||
|
|
||||||
|
"anp_settings_manager_start" : null,
|
||||||
|
"default_settings_files" : "JSON/AnP.settings.json",
|
||||||
|
"default_secrets_files" : "JSON/AnP.secrets.json",
|
||||||
|
"default_value" : null,
|
||||||
|
"allow_nulls" : true,
|
||||||
|
"default_text" : "",
|
||||||
|
"anp_settings_manager_show_building_message" : true,
|
||||||
|
"anp_settings_manager_show_built_message" : true,
|
||||||
|
"anp_settings_manager_show_starting_message" : true,
|
||||||
|
"anp_settings_manager_show_already_started_message" : true,
|
||||||
|
"anp_settings_manager_show_started_message" : true,
|
||||||
|
"anp_settings_manager_show_updating_message" : true,
|
||||||
|
"anp_settings_manager_show_updated_message" : true,
|
||||||
|
"anp_settings_manager_show_closing_message" : true,
|
||||||
|
"anp_settings_manager_show_already_closed_message" : true,
|
||||||
|
"anp_settings_manager_show_closed_message" : true,
|
||||||
|
"anp_settings_manager_add_show_ok" : false,
|
||||||
|
"anp_settings_manager_add_show_errors" : true,
|
||||||
|
"anp_settings_manager_add_check_errors" : true,
|
||||||
|
"anp_settings_manager_add_secrets_show_ok" : false,
|
||||||
|
"anp_settings_manager_add_secrets_show_errors" : true,
|
||||||
|
"anp_settings_manager_add_secrets_check_errors" : true,
|
||||||
|
"anp_settings_manager_get_show_ok" : false,
|
||||||
|
"anp_settings_manager_get_show_errors" : true,
|
||||||
|
"anp_settings_manager_get_check_errors" : true,
|
||||||
|
"anp_settings_manager_end" : null
|
||||||
|
|
||||||
|
}
|
||||||
44
JSON/I18N/AnP.i18n.espanol.json
Normal file
44
JSON/I18N/AnP.i18n.espanol.json
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"espanol" : {
|
||||||
|
|
||||||
|
"anp_start" : null,
|
||||||
|
"anp_building" : "La aplicación AnP se está construyendo...",
|
||||||
|
"anp_built" : "La aplicación AnP se ha construido.",
|
||||||
|
"anp_starting" : "La aplicación AnP se está iniciando...",
|
||||||
|
"anp_already_started" : "La aplicación AnP ya se ha iniciado.",
|
||||||
|
"anp_started" : "La aplicación AnP se ha iniciado.",
|
||||||
|
"anp_updating" : "La aplicación AnP se está actualizando...",
|
||||||
|
"anp_updated" : "La aplicación AnP se ha actualizado.",
|
||||||
|
"anp_closing" : "La aplicación AnP se está cerrando...",
|
||||||
|
"anp_already_closed" : "La aplicación AnP ya se ha cerrado.",
|
||||||
|
"anp_closed" : "La aplicación AnP se ha cerrado.",
|
||||||
|
"anp_end" : null,
|
||||||
|
|
||||||
|
"anp_print_types_manager_start" : null,
|
||||||
|
"anp_print_types_manager_building" : "El Administrador de Tipos de Impresión se está construyendo...",
|
||||||
|
"anp_print_types_manager_built" : "El Administrador de Tipos de Impresión se ha construido.",
|
||||||
|
"anp_print_types_manager_starting" : "El Administrador de Tipos de Impresión se está iniciando...",
|
||||||
|
"anp_print_types_manager_already_started" : "El Administrador de Tipos de Impresión ya se ha iniciado.",
|
||||||
|
"anp_print_types_manager_started" : "El Administrador de Tipos de Impresión se ha iniciado.",
|
||||||
|
"anp_print_types_manager_updating" : "El Administrador de Tipos de Impresión se está actualizando...",
|
||||||
|
"anp_print_types_manager_updated" : "El Administrador de Tipos de Impresión se ha actualizado.",
|
||||||
|
"anp_print_types_manager_closing" : "El Administrador de Tipos de Impresión se está cerrando...",
|
||||||
|
"anp_print_types_manager_already_closed" : "El Administrador de Tipos de Impresión ya se ha cerrado.",
|
||||||
|
"anp_print_types_manager_closed" : "El Administrador de Tipos de Impresión se ha cerrado.",
|
||||||
|
"anp_print_types_manager_end" : null,
|
||||||
|
|
||||||
|
"anp_settings_manager_start" : null,
|
||||||
|
"anp_settings_manager_building" : "El Administrador de Configuraciones se está construyendo...",
|
||||||
|
"anp_settings_manager_built" : "El Administrador de Configuraciones se ha construido.",
|
||||||
|
"anp_settings_manager_starting" : "El Administrador de Configuraciones se está iniciando...",
|
||||||
|
"anp_settings_manager_already_started" : "El Administrador de Configuraciones ya se ha iniciado.",
|
||||||
|
"anp_settings_manager_started" : "El Administrador de Configuraciones se ha iniciado.",
|
||||||
|
"anp_settings_manager_updating" : "El Administrador de Configuraciones se está actualizando...",
|
||||||
|
"anp_settings_manager_updated" : "El Administrador de Configuraciones se ha actualizado.",
|
||||||
|
"anp_settings_manager_closing" : "El Administrador de Configuraciones se está cerrando...",
|
||||||
|
"anp_settings_manager_already_closed" : "El Administrador de Configuraciones ya se ha cerrado.",
|
||||||
|
"anp_settings_manager_closed" : "El Administrador de Configuraciones se ha cerrado.",
|
||||||
|
"anp_settings_manager_end" : null
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
190
Public/ecma/Abstracts/BaseAbstract.ecma.js
Normal file
190
Public/ecma/Abstracts/BaseAbstract.ecma.js
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import("../Application/AnP.ecma.js").AnP} AnP
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {Utils} from "../Utils/Utils.ecma";
|
||||||
|
import {Check} from "../Utils/Check.ecma";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract
|
||||||
|
* @class BaseAbstract
|
||||||
|
* @constructor
|
||||||
|
* @param {!any} base
|
||||||
|
* @param {!AnP} anp
|
||||||
|
* @param {!string} key
|
||||||
|
* @param {?(Object.<string, any|null>|Array.<any|null>)} [inputs = null]
|
||||||
|
* @param {!Object.<string, any|null>} [print_options = {}]
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
export const BaseAbstract = (function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callable base_abstract_callback_end
|
||||||
|
* @param {!boolean} ok
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callable base_abstract_get_value
|
||||||
|
* @param {!(string|Array.<string>)} keys
|
||||||
|
* @param {?(Object.<string, any|null>|Array.<any|null>)} [inputs = null]
|
||||||
|
* @param {?any} [default_value = null]
|
||||||
|
* @returns {any|null}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructs BaseAbstract
|
||||||
|
* @param {!any} base
|
||||||
|
* @param {!AnP} anp
|
||||||
|
* @param {?(Object.<string, any|null>|Array.<any|null>)} [inputs = null]
|
||||||
|
* @param {!string} key
|
||||||
|
* @param {!Object.<string, any|null>} [print_options = {}]
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
const BaseAbstract = function(base, anp, key, inputs = null, print_options = {}){
|
||||||
|
|
||||||
|
/** @type {BaseAbstract} */
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this._build = () => true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} type
|
||||||
|
* @param {!(string|Array.<string>)} message
|
||||||
|
* @param {?(Object.<string, any|null>|Array.<any|null>)} [inputs = null]
|
||||||
|
* @param {!number} [i = 0]
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.print = (type, message, inputs = null, i = 0) => {
|
||||||
|
self.allow_print.message === false ||
|
||||||
|
anp.print(type, key + "_" + message, [print_options, inputs], i + 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {void}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
const constructor = () => {
|
||||||
|
|
||||||
|
/** @type {base_abstract_get_value} */
|
||||||
|
const get_value = anp.settings ? anp.settings.get : Utils.get_value;
|
||||||
|
|
||||||
|
/** @type {Object.<string, boolean>} */
|
||||||
|
this.allow_print = [
|
||||||
|
"building", "built",
|
||||||
|
"starting", "started", "already_started",
|
||||||
|
"closing", "closed", "already_closed"
|
||||||
|
].reduce((item, action) => {
|
||||||
|
|
||||||
|
item[key] = get_value(key + "_print_" + action + "_message", inputs, true);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
self.print("info", "building");
|
||||||
|
|
||||||
|
this.key = key;
|
||||||
|
/** @type {boolean} */
|
||||||
|
this.started = false;
|
||||||
|
/** @type {boolean} */
|
||||||
|
this.closed = true;
|
||||||
|
|
||||||
|
self.extends(base);
|
||||||
|
|
||||||
|
self._build();
|
||||||
|
|
||||||
|
self.print("ok", "built");
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!any} item
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.extends = item => {
|
||||||
|
Utils.extends(self, item);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?base_abstract_callback_end} [callback = null]
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this._start = (callback = null) => Check.is_function(callback) ? callback(true) : true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?base_abstract_callback_end} [callback = null]
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.start = (callback = null) => {
|
||||||
|
|
||||||
|
/** @type {base_abstract_callback_end} */
|
||||||
|
const end = ok => Check.is_function(callback) ? callback(ok) : ok;
|
||||||
|
|
||||||
|
self.print("info", "starting");
|
||||||
|
|
||||||
|
if(self.started){
|
||||||
|
self.print("warn", "already_started");
|
||||||
|
return end(false);
|
||||||
|
};
|
||||||
|
self.started = true;
|
||||||
|
|
||||||
|
return self._start(ok => {
|
||||||
|
self.closed = false;
|
||||||
|
self.print("ok", "started");
|
||||||
|
return end(ok);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?base_abstract_callback_end} [callback = null]
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this._close = (callback = null) => Check.is_function(callback) ? callback(true) : true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?base_abstract_callback_end} [callback = null]
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.close = (callback = null) => {
|
||||||
|
|
||||||
|
/** @type {base_abstract_callback_end} */
|
||||||
|
const end = ok => Check.is_function(callback) ? callback(ok) : ok;
|
||||||
|
|
||||||
|
self.print("info", "closing");
|
||||||
|
|
||||||
|
if(self.closed){
|
||||||
|
self.print("warn", "already_closed");
|
||||||
|
return end(false);
|
||||||
|
};
|
||||||
|
self.closed = true;
|
||||||
|
|
||||||
|
return self._close(ok => {
|
||||||
|
self.started = false;
|
||||||
|
self.print("ok", "closed");
|
||||||
|
return end(ok);
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return BaseAbstract;
|
||||||
|
})();
|
||||||
67
Public/ecma/Application/AnP.ecma.js
Normal file
67
Public/ecma/Application/AnP.ecma.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
import {I18NManager} from "../Managers/I18NManager.ecma.js";
|
||||||
|
import {SettingsManager} from "../Managers/SettingsManager.ecma.js";
|
||||||
|
import {Components} from "./Components.ecma.js";
|
||||||
|
import {FilesDriver} from "../Drivers/FilesDriver.ecma.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class AnP
|
||||||
|
* @constructor
|
||||||
|
* @param {?(Object.<string, any|null>|Array.<any|null>)} [inputs = null]
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
export const AnP = (function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructs AnP
|
||||||
|
* @param {?(Object.<string, any|null>|Array.<any|null>)} [inputs = null]
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
const AnP = function(inputs = null){
|
||||||
|
|
||||||
|
/** @type {AnP} */
|
||||||
|
const self = this;
|
||||||
|
/** @type {boolean} */
|
||||||
|
let started = false,
|
||||||
|
/** @type {boolean} */
|
||||||
|
closed = false;
|
||||||
|
|
||||||
|
/** @type {SettingsManager}*/
|
||||||
|
this.settings = new SettingsManager(self, inputs);
|
||||||
|
/** @type {I18NManager}*/
|
||||||
|
this.i18n = new I18NManager(self);
|
||||||
|
/** @type {Components} */
|
||||||
|
this.comp = this.components = new Components(self);
|
||||||
|
/** @type {FilesDriver} */
|
||||||
|
this.files = new FilesDriver(self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
const constructor = () => {};
|
||||||
|
|
||||||
|
this.start = (callback = null) => {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!any} module
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.extends = module => {
|
||||||
|
for(const key in self)
|
||||||
|
module[key] === undefined &&
|
||||||
|
(module[key] = self[key]);
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return AnP;
|
||||||
|
})();
|
||||||
412
Public/ecma/Application/Components.ecma.js
Normal file
412
Public/ecma/Application/Components.ecma.js
Normal file
@ -0,0 +1,412 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
import {Check} from "../Utils/Check.ecma.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import("../Application/AnP.ecma.js").AnP} AnP
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Components
|
||||||
|
* @constructor
|
||||||
|
* @param {!AnP} anp
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
export const Components = (function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback components_event_callback
|
||||||
|
* @param {!HTMLElement} item
|
||||||
|
* @param {!Event} event
|
||||||
|
* @returns {boolean|void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructs Components
|
||||||
|
* @param {!AnP} anp
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
const Components = function(anp){
|
||||||
|
|
||||||
|
/** @type {Components} */
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
const constructor = () => {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!(string|Array.<string>)} i18n
|
||||||
|
* @param {!string} [tag = "span"]
|
||||||
|
* @param {?string} [_default = null]
|
||||||
|
* @returns {[string, Object.<string, string>, string]}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.i18n = (i18n, tag = "span", _default = null) => [tag, {data_i18n : i18n}, anp.i18n.get(i18n, null, _default)];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} name
|
||||||
|
* @param {!string} [tag = "span"]
|
||||||
|
* @returns {[string, Object.<string, string>]}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.icon = (name, tag = "span") => [tag, {data_icon : name}];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} name
|
||||||
|
* @param {?components_event_callback} [on_click = null]
|
||||||
|
* @param {!string} [type = "button"]
|
||||||
|
* @param {?string} [default_text = null]
|
||||||
|
* @returns {[string, Object.<string, (string|function)>, Array.<(string|[string, Object.<string, string>, string])>]}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.button = (name, on_click = null, type = "button", default_text) => ["button", {
|
||||||
|
type : type,
|
||||||
|
data_i18n : name,
|
||||||
|
data_i18n_without : true,
|
||||||
|
title : anp.i18n.get(name, null, default_text),
|
||||||
|
...(on_click ? {on_click : on_click} : {})
|
||||||
|
}, [
|
||||||
|
self.icon(name),
|
||||||
|
self.i18n(name, "span", default_text)
|
||||||
|
]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} type
|
||||||
|
* @param {!string} name
|
||||||
|
* @param {!boolean} checked
|
||||||
|
* @param {?components_event_callback} on_change
|
||||||
|
* @param {?string} default_text
|
||||||
|
* @param {!boolean} [role_button = false]
|
||||||
|
* @returns {[string, Object.<string, (string|function)>, Array.<(string|[string, Object.<string, string>, string])>]}
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
const select_item = (type, name, checked, on_change, default_text, role_button = false) => {
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
|
const id = name.slice(-2) == "[]" ? anp.identifiers.get() : name;
|
||||||
|
|
||||||
|
return ["label", {
|
||||||
|
for : id,
|
||||||
|
class : type + "-input",
|
||||||
|
data_i18n : name,
|
||||||
|
data_i18n_without : true,
|
||||||
|
title : anp.i18n.get(name, null, default_text),
|
||||||
|
...(role_button ? {role : "button"} : {})
|
||||||
|
}, [
|
||||||
|
["input", {
|
||||||
|
type : type,
|
||||||
|
id : id,
|
||||||
|
name : name,
|
||||||
|
...(on_change ? {on_change : on_change} : {}),
|
||||||
|
...(checked ? {checked : "checked"} : {})
|
||||||
|
}],
|
||||||
|
self.icon(type, "span"),
|
||||||
|
self.i18n(name, "span", default_text)
|
||||||
|
]];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} name
|
||||||
|
* @param {!boolean} [checked = false]
|
||||||
|
* @param {?components_event_callback} [on_change = null]
|
||||||
|
* @param {?string} [default_text = null]
|
||||||
|
* @param {!boolean} [role_button = false]
|
||||||
|
* @returns {[string, Object.<string, (string|function)>, Array.<(string|[string, Object.<string, string>, string])>]}
|
||||||
|
*/
|
||||||
|
this.checkbox = (name, checked = false, on_change = null, default_text, role_button = false) => (
|
||||||
|
select_item("checkbox", name, checked, on_change, default_text, role_button)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} name
|
||||||
|
* @param {!boolean} [checked = false]
|
||||||
|
* @param {?components_event_callback} [on_change = null]
|
||||||
|
* @param {?string} [default_text = null]
|
||||||
|
* @returns {[string, Object.<string, (string|function)>, Array.<(string|[string, Object.<string, string>, string])>]}
|
||||||
|
*/
|
||||||
|
this.radio = (name, checked = false, on_change = null, default_text) => (
|
||||||
|
select_item("radio", name, checked, on_change, default_text)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} name
|
||||||
|
* @param {?number} [value = null]
|
||||||
|
* @param {?number} [minimum = null]
|
||||||
|
* @param {?number} [maximum = null]
|
||||||
|
* @param {?number} [step = null]
|
||||||
|
* @param {?components_event_callback} [on_change = null]
|
||||||
|
* @param {?string} [default_text = null]
|
||||||
|
* @returns {[string, Object.<string, (string|number|function)>, Array.<(string|[string, Object.<string, string>, string])>]}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.number = (name, value = null, minimum = null, maximum = null, step = null, on_change = null, default_text) => {
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
|
const text = anp.i18n.get(name, null, default_text);
|
||||||
|
|
||||||
|
return ["label", {
|
||||||
|
for : name,
|
||||||
|
class : "number-input",
|
||||||
|
data_i18n : name,
|
||||||
|
data_i18n_without : true,
|
||||||
|
title : text,
|
||||||
|
}, [
|
||||||
|
["input", {
|
||||||
|
type : "number",
|
||||||
|
id : name,
|
||||||
|
name : name,
|
||||||
|
...(value !== null ? {value : value} : {}),
|
||||||
|
...(minimum !== null ? {min : minimum} : {}),
|
||||||
|
...(maximum !== null ? {max : maximum} : {}),
|
||||||
|
...(step !== null ? {step : step} : {}),
|
||||||
|
...(on_change ? {on_change : on_change} : {}),
|
||||||
|
data_i18n : name,
|
||||||
|
data_i18n_without : true,
|
||||||
|
placeholder : text + "..."
|
||||||
|
}],
|
||||||
|
["span", {class : "minimum"}, minimum || "-∞"],
|
||||||
|
["span", {class : "maximum"}, maximum || "∞"]
|
||||||
|
]];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} type
|
||||||
|
* @param {!string} name
|
||||||
|
* @param {?string} [value = null]
|
||||||
|
* @param {?number} [maximum_length = null]
|
||||||
|
* @param {?string} [pattern = null]
|
||||||
|
* @param {?components_event_callback} [on_change = null]
|
||||||
|
* @param {?string} [default_text = null]
|
||||||
|
* @returns {[string, Object.<string, (string|function)>, Array.<(string|[string, Object.<string, string>, string])>]}
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
const text = (type, name, value = null, maximum_length = null, pattern = null, on_change = null, default_text = null) => {
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
|
const text = anp.i18n.get(name, null, default_text);
|
||||||
|
|
||||||
|
return ["label", {
|
||||||
|
for : name,
|
||||||
|
class : "input-" + type
|
||||||
|
}, [
|
||||||
|
["input", {
|
||||||
|
type : type,
|
||||||
|
id : name,
|
||||||
|
name : name,
|
||||||
|
...(value !== null ? {value : value} : {}),
|
||||||
|
...(pattern !== null ? {pattern : pattern} : {}),
|
||||||
|
...(on_change ? {on_input : on_change} : {}),
|
||||||
|
data_i18n : name,
|
||||||
|
data_i18n_without : true,
|
||||||
|
placeholder : text + "..."
|
||||||
|
}],
|
||||||
|
["span", {class : "length"}, 0],
|
||||||
|
...(maximum_length ? [["span", {class : "maximum-length"}, maximum_length || "∞"]] : [])
|
||||||
|
]];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} name
|
||||||
|
* @param {?string} [value = null]
|
||||||
|
* @param {?number} [maximum_length = null]
|
||||||
|
* @param {?string} [pattern = null]
|
||||||
|
* @param {?components_event_callback} [on_change = null]
|
||||||
|
* @param {?string} [default_text = null]
|
||||||
|
* @returns {[string, Object.<string, (string|function)>, Array.<(string|[string, Object.<string, string>, string])>]}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.text = (name, value = null, maximum_length = null, pattern = null, on_change = null, default_text = null) => (
|
||||||
|
text("text", name, value, maximum_length, pattern, on_change, default_text)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} name
|
||||||
|
* @param {?string} [value = null]
|
||||||
|
* @param {?number} [maximum_length = null]
|
||||||
|
* @param {?string} [pattern = null]
|
||||||
|
* @param {?components_event_callback} [on_change = null]
|
||||||
|
* @param {?string} [default_text = null]
|
||||||
|
* @returns {[string, Object.<string, (string|function)>, Array.<(string|[string, Object.<string, string>, string])>]}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.password = (name, value = null, maximum_length = null, pattern = null, on_change = null, default_text = null) => (
|
||||||
|
text("password", name, value, maximum_length, pattern, on_change, default_text)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {...[string, components_event_callback|null, string, string|null]} buttons
|
||||||
|
* @returns {[string, Object.<string, string>, Array.<(string|[string, Object.<string, string>, string])>]}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.buttons = (...buttons) => ["div", {class : "buttons"}, buttons.map(button => self.button(...button))];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} name
|
||||||
|
* @param {...any} items
|
||||||
|
* @returns {[string, Object.<string, string>, Array.<(string|[string, Object.<string, string>, string])>]}
|
||||||
|
*/
|
||||||
|
this.group = (name, ...items) => ["div", {
|
||||||
|
class : "group",
|
||||||
|
data_i18n : name,
|
||||||
|
data_i18n_without : true,
|
||||||
|
title : anp.i18n.get(name)
|
||||||
|
}, items];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} name
|
||||||
|
* @param {!Array.<any|null>} structure
|
||||||
|
* @param {?components_event_callback} on_submit
|
||||||
|
* @param {...(components_event_callback|null)} [extra_actions]
|
||||||
|
* @returns {[string, Object.<string, (string|function)>, Array.<(string|[string, Object.<string, string>, string])>]}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.form = (name, structure, on_submit, ...extra_actions) => ["form", {
|
||||||
|
class : "form",
|
||||||
|
data_name : name,
|
||||||
|
method : "get",
|
||||||
|
action : "#",
|
||||||
|
...(on_submit ? {on_submit : on_submit} : {})
|
||||||
|
}, [
|
||||||
|
["fieldset", {}, [
|
||||||
|
self.i18n(name, "legend"),
|
||||||
|
self.i18n(name + "_text", "p"),
|
||||||
|
["div", {class : "structure"}, structure.map(([type, name, ...item], i) => {
|
||||||
|
return ["div", {
|
||||||
|
data_i : i,
|
||||||
|
data_type : type,
|
||||||
|
data_i18n : name,
|
||||||
|
data_i18n_without : true,
|
||||||
|
title : anp.i18n.get(name, null, item[1] || name)
|
||||||
|
}, [
|
||||||
|
["label", {for : name}, [
|
||||||
|
self.i18n(name),
|
||||||
|
self.i18n(name + "_description")
|
||||||
|
]],
|
||||||
|
["span", {class : "input"}, self[type] ? [self[type](name, ...item)] : item],
|
||||||
|
["ul", {class : "errors"}]
|
||||||
|
]];
|
||||||
|
})],
|
||||||
|
["ul", {class : "form-errors"}],
|
||||||
|
self.buttons(
|
||||||
|
["clean", null, "clean"],
|
||||||
|
...extra_actions,
|
||||||
|
on_submit ? ["submit", null, "submit"] : null
|
||||||
|
)
|
||||||
|
]]
|
||||||
|
]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!HTMLElement} form
|
||||||
|
* @returns {HTMLFormElement|null}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.get_form = form => {
|
||||||
|
|
||||||
|
if(form)
|
||||||
|
while(form.tagName.toLowerCase() != "form" && (form = form.parentNode));
|
||||||
|
|
||||||
|
return form;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!HTMLElement} form
|
||||||
|
* @returns {Object.<string, (string|number|boolean|Array.<(string|number|boolean)>)>}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.get_form_data = form => (
|
||||||
|
[...self.get_form(form).querySelectorAll("[name]")].reduce((data, item) => {
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
|
let name_value = item.getAttribute("name");
|
||||||
|
/** @type {string} */
|
||||||
|
const name = name_value.replace(/\[\]$/i, ""),
|
||||||
|
/** @type {boolean} */
|
||||||
|
is_array = name_value != name;
|
||||||
|
|
||||||
|
is_array && !(name in data) && (data[name] = []);
|
||||||
|
|
||||||
|
switch(item.getAttribute("type")){
|
||||||
|
case "radio":
|
||||||
|
data[name] == [] && (data[name] = false);
|
||||||
|
item.checked && (data[name] = Number(item.value));
|
||||||
|
break;
|
||||||
|
case "checkbox":
|
||||||
|
if(is_array)
|
||||||
|
data[name].push(item.checked);
|
||||||
|
else
|
||||||
|
data[name] = item.checked;
|
||||||
|
break;
|
||||||
|
case "number":
|
||||||
|
if(is_array)
|
||||||
|
data[name].push(Number(item.value));
|
||||||
|
else
|
||||||
|
data[name] = Number(item.value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(is_array)
|
||||||
|
data[name].push(item.value);
|
||||||
|
else
|
||||||
|
data[name] = item.value;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}, {})
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!(string|Array.<string>)} sources
|
||||||
|
* @param {?(string|Array.<string>)} [i18n = null]
|
||||||
|
* @param {?string} [default_text = null]
|
||||||
|
* @returns {[string, Object.<string, (string|number|function)>, (string|[string, Object.<string, string>, string])>]}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.image = (sources, i18n = null, default_text = null) => {
|
||||||
|
|
||||||
|
/** @type {number} */
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
Check.is_array(sources) || (sources = [sources]);
|
||||||
|
|
||||||
|
return ["span", {
|
||||||
|
class : "image",
|
||||||
|
data_status : "loading",
|
||||||
|
...(
|
||||||
|
i18n ? {data_i18n : i18n, title : anp.i18n.get(i18n, null, default_text)} :
|
||||||
|
default_text ? {title : default_text} :
|
||||||
|
{}),
|
||||||
|
}, [
|
||||||
|
["img", {
|
||||||
|
src : sources[i],
|
||||||
|
...(
|
||||||
|
i18n ? {data_i18n : i18n, alt : anp.i18n.get(i18n, null, default_text)} :
|
||||||
|
default_text ? {alt : default_text} :
|
||||||
|
{}),
|
||||||
|
on_error : (image, event) => {
|
||||||
|
if(i >= sources.length)
|
||||||
|
image.parentNode.setAttribute("data-status", "error");
|
||||||
|
else
|
||||||
|
image.parentNode.setAttribute("src", sources[++ i]);
|
||||||
|
},
|
||||||
|
on_load : (image, event) => {
|
||||||
|
image.parentNode.setAttribute("data-status", "loaded");
|
||||||
|
image.parentNode.querySelector("span").style.backgroundImage = "url('" + sources[i] + "')";
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
["span"]
|
||||||
|
]];
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return Components;
|
||||||
|
})();
|
||||||
155
Public/ecma/Drivers/FilesDriver.ecma.js
Normal file
155
Public/ecma/Drivers/FilesDriver.ecma.js
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import("../Application/AnP.ecma.js").AnP} AnP
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class FilesDriver
|
||||||
|
* @constructor
|
||||||
|
* @param {!AnP} anp
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
export const FilesDriver = (function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback files_driver_start_callback
|
||||||
|
* @param {!boolean} ok
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructs FilesDriver
|
||||||
|
* @param {!AnP} anp
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
const FilesDriver = function(anp){
|
||||||
|
|
||||||
|
/** @type {FilesDriver} */
|
||||||
|
const self = this;
|
||||||
|
/** @type {boolean} */
|
||||||
|
let started = false,
|
||||||
|
/** @type {boolean} */
|
||||||
|
closed = false,
|
||||||
|
/** @type {string} */
|
||||||
|
default_http_method = "GET",
|
||||||
|
/** @type {boolean} */
|
||||||
|
default_http_asynchronous = true,
|
||||||
|
/** @type {number} */
|
||||||
|
default_timeout = 2000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
const constructor = () => {
|
||||||
|
|
||||||
|
self.update();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?files_driver_start_callback} [callback = null]
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.update = (callback = null) => {
|
||||||
|
|
||||||
|
default_http_method = anp.settings.get([
|
||||||
|
"http_method", "default_http_method"
|
||||||
|
], null, default_http_method);
|
||||||
|
default_http_asynchronous = anp.settings.get([
|
||||||
|
"http_asynchronous", "default_http_asynchronous"
|
||||||
|
], null, default_http_asynchronous);
|
||||||
|
default_timeout = anp.settings.get([
|
||||||
|
"timeout", "default_timeout"
|
||||||
|
], null, default_timeout);
|
||||||
|
|
||||||
|
Utils.execute(callback);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?files_driver_start_callback} [callback = null]
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.start = (callback = null) => {
|
||||||
|
|
||||||
|
if(started){
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
started = true;
|
||||||
|
|
||||||
|
self.update(callback);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.load = (path, callback = null, inputs = null) => {
|
||||||
|
|
||||||
|
/** @type {boolean} */
|
||||||
|
let ended = false,
|
||||||
|
/** @type {number} */
|
||||||
|
error = 0;
|
||||||
|
/** @type {XMLHttpRequest} */
|
||||||
|
const ajax = new XMLHttpRequest(),
|
||||||
|
/** @type {number} */
|
||||||
|
timeout = Utils.get_value([
|
||||||
|
"timeout", "ajax_timeout", "default_timeout"
|
||||||
|
], inputs, default_timeout),
|
||||||
|
/** @type {number} */
|
||||||
|
date = Date.now(),
|
||||||
|
end = code => {
|
||||||
|
code && (error |= 1 << code);
|
||||||
|
!ended && (ended = true) &&
|
||||||
|
Utils.execute(
|
||||||
|
callback,
|
||||||
|
ajax.responseText,
|
||||||
|
ajax.status,
|
||||||
|
ajax.readyState,
|
||||||
|
error,
|
||||||
|
error === 0
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ajax.open(
|
||||||
|
Utils.get_value([
|
||||||
|
"method", "http_method", "default_http_method"
|
||||||
|
], inputs, default_http_method),
|
||||||
|
path,
|
||||||
|
Utils.get_value([
|
||||||
|
"asynchronous", "http_asynchronous", "default_http_asynchronous"
|
||||||
|
], inputs, default_http_asynchronous)
|
||||||
|
);
|
||||||
|
ajax.timeout = timeout;
|
||||||
|
ajax.onreadystatechange = function(){
|
||||||
|
if(ended)
|
||||||
|
return;
|
||||||
|
if(ajax.readyState === 4)
|
||||||
|
end((
|
||||||
|
ajax.status >= 200 && ajax.status < 300
|
||||||
|
) || [301, 302, 304].includes(ajax.status) ? 0 : 1);
|
||||||
|
else if(Date.now() - date >= timeout)
|
||||||
|
end(2);
|
||||||
|
};
|
||||||
|
ajax.send(null);
|
||||||
|
|
||||||
|
ajax.onerror = () => {end(3);}
|
||||||
|
ajax.onabort = () => {end(4);}
|
||||||
|
ajax.ontimeout = () => {end(5);}
|
||||||
|
|
||||||
|
return ajax;
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return FilesDriver;
|
||||||
|
})();
|
||||||
139
Public/ecma/Managers/I18NManager.ecma.js
Normal file
139
Public/ecma/Managers/I18NManager.ecma.js
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
import {Check} from "../Utils/Check.ecma.js";
|
||||||
|
import {Utils} from "../Utils/Utils.ecma.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import("../Application/AnP.ecma.js").AnP} AnP
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class I18NManager
|
||||||
|
* @constructor
|
||||||
|
* @param {!AnP} anp
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
export const I18NManager = (function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback i18n_manager_default_callback
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructs I18NManager
|
||||||
|
* @param {!AnP} anp
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
const I18NManager = function(anp){
|
||||||
|
|
||||||
|
/** @type {I18NManager} */
|
||||||
|
const self = this,
|
||||||
|
/** @type {Object.<string, Object.<string, string|Array.<string>>} */
|
||||||
|
sentences = {};
|
||||||
|
/** @type {string} */
|
||||||
|
let language_selected = "espanol",
|
||||||
|
/** @type {string} */
|
||||||
|
default_language = "espanol";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
const constructor = () => {
|
||||||
|
|
||||||
|
language_selected = anp.settings.get(["language_selected", "default_language"], null, language_selected);
|
||||||
|
default_language = anp.settings.get(["default_language", "language_selected"], null, default_language);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?i18n_manager_default_callback} [callback = null]
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.start = (callback = null) => {
|
||||||
|
Utils.execute_array([
|
||||||
|
"default_i18n_files", "i18n_files"
|
||||||
|
], (key, next_callback) => {
|
||||||
|
self.add(anp.settings.get(key), next_callback, true);
|
||||||
|
}, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!(string|Array.<string>)} texts
|
||||||
|
* @param {?(Object.<string, any|null>|Array.<any|null>)} [variables = null]
|
||||||
|
* @param {?any} [_default = null]
|
||||||
|
* @returns {string|null}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.get = (texts, variables = null, _default = null) => {
|
||||||
|
|
||||||
|
/** @type {string|Array.<string>|null} */
|
||||||
|
let text = null;
|
||||||
|
/** @type {Array.<string>} */
|
||||||
|
const used = [],
|
||||||
|
/** @type {Array.<string>} */
|
||||||
|
languages = [language_selected, default_language].concat(Object.keys(sentences)),
|
||||||
|
/** @type {Array.<string>} */
|
||||||
|
keys = Utils.get_keys(texts);
|
||||||
|
|
||||||
|
if(keys.length)
|
||||||
|
for(const language of languages){
|
||||||
|
if(!used.includes(language) && sentences[language])
|
||||||
|
for(const key of keys){
|
||||||
|
if(sentences[language][key] !== undefined){
|
||||||
|
text = sentences[language][key];
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if(text !== undefined)
|
||||||
|
break;
|
||||||
|
used.push(language);
|
||||||
|
};
|
||||||
|
|
||||||
|
text === null && (text = (
|
||||||
|
_default !== null ? _default :
|
||||||
|
texts !== null ? (
|
||||||
|
Check.is_string(texts) ? texts :
|
||||||
|
Check.is_array(texts) && texts.length ? texts[0] :
|
||||||
|
null) :
|
||||||
|
null))
|
||||||
|
|
||||||
|
return Utils.string_variables((
|
||||||
|
Check.is_array(text) ? text.join("") :
|
||||||
|
text), variables, _default);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!(Object.<string, Object.<string, string|Array.<string>|null>>|Array.<any|null>|string)} inputs
|
||||||
|
* @param {?i18n_manager_default_callback} [callback = null]
|
||||||
|
* @param {!boolean} [overwrite = false]
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.add = (inputs, callback = null, overwrite = false) => {
|
||||||
|
anp.load_json(inputs, (item, next_callback) => {
|
||||||
|
for(const language in item){
|
||||||
|
sentences[language] || (sentences[language] = {});
|
||||||
|
for(const key in item[language])
|
||||||
|
(overwrite || Check.is_null_or_undefined(sentences[language][key])) &&
|
||||||
|
(sentences[language][key] = item[language][key]);
|
||||||
|
};
|
||||||
|
next_callback();
|
||||||
|
}, callback, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @type {Object.<string, any|null>} */
|
||||||
|
I18NManager.DEFAULT_SETTINGS = {};
|
||||||
|
|
||||||
|
return I18NManager;
|
||||||
|
})();
|
||||||
89
Public/ecma/Managers/IdentifiersManager.ecma.js
Normal file
89
Public/ecma/Managers/IdentifiersManager.ecma.js
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
import {Utils} from "../Utils/Utils.ecma.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import("../Application/AnP.ecma.js").AnP} AnP
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class IdentifiersManager
|
||||||
|
* @constructor
|
||||||
|
* @param {!AnP} anp
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
export const IdentifiersManager = (function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructs IdentifiersManager
|
||||||
|
* @param {!AnP} anp
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
const IdentifiersManager = function(anp){
|
||||||
|
|
||||||
|
/** @type {IdentifiersManager} */
|
||||||
|
const self = this,
|
||||||
|
/** @type {Array.<string>} */
|
||||||
|
identifiers = [];
|
||||||
|
/** @type {Array.<string>|string} */
|
||||||
|
let alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
|
||||||
|
/** @type {number} */
|
||||||
|
length = 11;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
const constructor = () => {
|
||||||
|
|
||||||
|
alphabet = anp.settings.get(["identifiers_alphabet", "default_identifiers_alphabet"], null, alphabet);
|
||||||
|
length = anp.settings.get(["identifiers_length", "default_identifiers_length"], null, length);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!(string|Array.<string>)} keys
|
||||||
|
* @param {?(Object.<string, any|null>|Array.<any|null>)} [inputs = null]
|
||||||
|
* @param {?any} [_default = null]
|
||||||
|
* @returns {any|null}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.get = () => {
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
|
let identifier;
|
||||||
|
|
||||||
|
do{
|
||||||
|
identifier = "";
|
||||||
|
while((identifier += Utils.get_random(alphabet)).length < length);
|
||||||
|
}while(
|
||||||
|
identifiers.includes(identifier) ||
|
||||||
|
/^[^a-z]/i.test(identifier) ||
|
||||||
|
document.querySelector("." + identifier + ",#" + identifier + ",[name=" + identifier + "]")
|
||||||
|
);
|
||||||
|
identifiers.push(identifier);
|
||||||
|
|
||||||
|
return identifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} identifier
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
this.remove = identifier => {
|
||||||
|
identifier in identifiers && identifiers.splice(identifiers.indexOf(identifier), 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @type {Object.<string, any|null>} */
|
||||||
|
IdentifiersManager.DEFAULT_SETTINGS = {};
|
||||||
|
|
||||||
|
return IdentifiersManager;
|
||||||
|
})();
|
||||||
135
Public/ecma/Managers/SettingsManager.ecma.js
Normal file
135
Public/ecma/Managers/SettingsManager.ecma.js
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
import {Utils} from "../Utils/Utils.ecma.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import("../Application/AnP.ecma.js").AnP} AnP
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class SettingsManager
|
||||||
|
* @constructor
|
||||||
|
* @param {!AnP} anp
|
||||||
|
* @param {?(Object.<string, any|null>|Array.<any|null>)} customs
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
export const SettingsManager = (function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback settings_manager_default_callback
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructs SettingsManager
|
||||||
|
* @param {!AnP} anp
|
||||||
|
* @param {?(Object.<string, any|null>|Array.<any|null>)} customs
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
const SettingsManager = function(anp, customs = null){
|
||||||
|
|
||||||
|
/** @type {SettingsManager} */
|
||||||
|
const self = this,
|
||||||
|
/** @type {Object.<string, any|null>} */
|
||||||
|
settings = {},
|
||||||
|
/** @type {Object.<string, any|null>} */
|
||||||
|
secrets = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
const constructor = () => {
|
||||||
|
|
||||||
|
customs = Utils.get_dictionary(customs);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?settings_manager_default_callback} [callback = null]
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.start = (callback = null) => {
|
||||||
|
Utils.execute_array([
|
||||||
|
"default_settings_files", "settings_files"
|
||||||
|
], (key, next_callback) => {
|
||||||
|
self.add(self.get(key), next_callback, true);
|
||||||
|
}, () => {
|
||||||
|
Utils.execute_array([
|
||||||
|
"default_secrets_files", "secrets_files"
|
||||||
|
], (key, next_callback) => {
|
||||||
|
self.add_secrets(self.get(key), next_callback, true);
|
||||||
|
}, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!(string|Array.<string>)} keys
|
||||||
|
* @param {?(Object.<string, any|null>|Array.<any|null>)} [inputs = null]
|
||||||
|
* @param {?any} [_default = null]
|
||||||
|
* @returns {any|null}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.get = (keys, inputs = null, _default = null) => (
|
||||||
|
Utils.get_value(keys, [inputs, customs, secrets, settings, SettingsManager.DEFAULT_SETTINGS], _default)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!(Object.<string, Object.<string, string|Array.<string>|null>>|Array.<any|null>|string)} inputs
|
||||||
|
* @param {?i18n_manager_default_callback} callback
|
||||||
|
* @param {!boolean} overwrite
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.add = (inputs, callback = null, overwrite = false) => {
|
||||||
|
anp.load_json(inputs, (item, next_callback) => {
|
||||||
|
for(key in item)
|
||||||
|
(overwrite || Check.is_null_or_undefined(settings[key])) &&
|
||||||
|
(settings[key] = item[key]);
|
||||||
|
next_callback();
|
||||||
|
}, callback, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!(Object.<string, any|null>|Array.<any|null>|string)} inputs
|
||||||
|
* @param {?settings_manager_default_callback} [callback = null]
|
||||||
|
* @param {!boolean} [overwrite = false]
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.add_secrets = (inputs, callback = null, overwrite = false) => {
|
||||||
|
anp.load_json(inputs, (item, next_callback) => {
|
||||||
|
for(const key in item)
|
||||||
|
(overwrite || Check.is_null_or_undefined(secrets[key])) &&
|
||||||
|
(secrets[key] = item[key]);
|
||||||
|
next_callback();
|
||||||
|
}, callback, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @type {Object.<string, any|null>} */
|
||||||
|
SettingsManager.DEFAULT_SETTINGS = {
|
||||||
|
/** @type {Array.<string>|string|Object.<string, any|null>} */
|
||||||
|
default_settings_files : ["/json/AnP.settings.json"],
|
||||||
|
/** @type {Array.<string>|string|Object.<string, any|null>} */
|
||||||
|
default_secrets_files : ["/json/AnP.secrets.json"],
|
||||||
|
/** @type {Array.<string>|string|Object.<string, any|null>} */
|
||||||
|
default_i18n_files : [
|
||||||
|
"/json/i18n/AnP.i18n.espanol.json",
|
||||||
|
"/json/i18n/AnP.i18n.galego.json",
|
||||||
|
"/json/i18n/AnP.i18n.english.json"
|
||||||
|
],
|
||||||
|
/** @type {Array.<string>|string|Object.<string, any|null>} */
|
||||||
|
default_database_files : ["/json/database.json"],
|
||||||
|
};
|
||||||
|
|
||||||
|
return SettingsManager;
|
||||||
|
})();
|
||||||
102
Public/ecma/Utils/Check.ecma.js
Normal file
102
Public/ecma/Utils/Check.ecma.js
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
import {RE} from "./Patterns.ecma.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Check
|
||||||
|
* @constructor
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
export const Check = (function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructs Check
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
const Check = function(){};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} item
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Check.is_string = item => typeof item == "string";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} item
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Check.is_key = item => item && Check.is_string(item) && RE.KEY.test(item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} item
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Check.is_array = item => item instanceof Array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} item
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Check.is_dictionary = item => item && item.constructor == Object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} item
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Check.is_function = item => typeof item == "function";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} item
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Check.is_html_item = item => item && (item.tagName || item.nodeName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} item
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Check.is_number = item => typeof item == "number";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} item
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Check.is_integer = item => Check.is_number(item) && item == item >> 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Check.is_dark_mode = () => !!window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} item
|
||||||
|
* @returns {boolean}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Check.is_null_or_undefined = item => item === null || item === undefined;
|
||||||
|
|
||||||
|
return Check;
|
||||||
|
})();
|
||||||
113
Public/ecma/Utils/Options.ecma.js
Normal file
113
Public/ecma/Utils/Options.ecma.js
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Options
|
||||||
|
* @constructor
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
export const Options = (function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructs Options
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
const Options = function(options, _default = null){
|
||||||
|
|
||||||
|
/** @type {Options} */
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
/** @type {boolean|null} */
|
||||||
|
this.overwrite = null;
|
||||||
|
/** @type {boolean|null} */
|
||||||
|
this.allow_nulls = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
const constructor = () => {
|
||||||
|
|
||||||
|
_default || (_default = Options.DEFAULT);
|
||||||
|
|
||||||
|
[
|
||||||
|
["overwrite", Options.OVERWRITE],
|
||||||
|
["allow_nulls", Options.NULLISH]
|
||||||
|
].forEach(([key, option]) => {
|
||||||
|
|
||||||
|
/** @type {boolean|null} */
|
||||||
|
const value = Options.get_value(options, option);
|
||||||
|
|
||||||
|
self[key] = value !== null ? value : _default[key];
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
this.get = () => {
|
||||||
|
|
||||||
|
/** @type {number} */
|
||||||
|
let code = 0;
|
||||||
|
|
||||||
|
[
|
||||||
|
[Options.OVERWRITING, self.overwrite],
|
||||||
|
[Options.NULLISH, self.allow_nulls],
|
||||||
|
].forEach(([option, value]) => {
|
||||||
|
code += (
|
||||||
|
value ? 1 :
|
||||||
|
value === false ? 2 :
|
||||||
|
0) * 3 ** option;
|
||||||
|
});
|
||||||
|
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @type {number} */
|
||||||
|
Options.OVERWRITING = 0;
|
||||||
|
/** @type {number} */
|
||||||
|
Options.OVERWRITE = 1 + 3 * Options.OVERWRITING;
|
||||||
|
/** @type {number} */
|
||||||
|
Options.NO_OVERWRITE = 2 + 3 * Options.OVERWRITING;
|
||||||
|
|
||||||
|
/** @type {number} */
|
||||||
|
Options.NULLISH = 1;
|
||||||
|
/** @type {number} */
|
||||||
|
Options.ALLOW_NULLS = 1 + 3 * Options.NULLISH;
|
||||||
|
/** @type {number} */
|
||||||
|
Options.NOT_NULLS = 2 + 3 * Options.NULLISH;
|
||||||
|
|
||||||
|
/** @type {Options} */
|
||||||
|
Options.DEFAULT = new Options(Options.NO_OVERWRITE | Options.ALLOW_NULLS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!number} value
|
||||||
|
* @param {!number} option
|
||||||
|
* @returns {boolean|null}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Options.get_value = (value, option) => {
|
||||||
|
|
||||||
|
/** @type {number} */
|
||||||
|
const ternary = (value / 3 ** option >> 0) % 3;
|
||||||
|
|
||||||
|
return (
|
||||||
|
ternary === 1 ? true :
|
||||||
|
ternary === 2 ? false :
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Options;
|
||||||
|
})();
|
||||||
24
Public/ecma/Utils/Patterns.ecma.js
Normal file
24
Public/ecma/Utils/Patterns.ecma.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class RE
|
||||||
|
* @constructor
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
export const RE = (function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructs RE
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
const RE = function(){};
|
||||||
|
|
||||||
|
/** @type {RegExp} */
|
||||||
|
RE.KEY = /^[a-z_][a-z0-9_]*$/i;
|
||||||
|
|
||||||
|
return RE;
|
||||||
|
})();
|
||||||
404
Public/ecma/Utils/Utils.ecma.js
Normal file
404
Public/ecma/Utils/Utils.ecma.js
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
import {Check} from "./Check.ecma.js";
|
||||||
|
import {Options} from "./Options.ecma.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Utils
|
||||||
|
* @constructor
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
export const Utils = (function(){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback utils_execute_callback
|
||||||
|
* @param {...(any|null)} inputs
|
||||||
|
* @returns {any|null}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback utils_default_callback
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback utils_execute_array_each_callback
|
||||||
|
* @param {?any} item
|
||||||
|
* @param {!utils_default_callback} callback
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructs Utils
|
||||||
|
* @returns {void}
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
const Utils = function(){};
|
||||||
|
|
||||||
|
/** @type {Options} */
|
||||||
|
Utils.GET_DICTIONARY_OPTIONS = new Options(Options.NO_OVERWRITE);
|
||||||
|
/** @type {Options} */
|
||||||
|
Utils.GET_VALUE_OPTIONS = new Options(Options.ALLOW_NULLS);
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
|
Utils.BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||||
|
/** @type {string} */
|
||||||
|
Utils.RANDOM_ALPHABET = "bHMnuamw/RUBk+xNvCXghsPdlSFG12rLoT0O3VZ=5QeWyI8pADqjcEfJ9Kt64i7Yz";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {...(any|null)} items
|
||||||
|
* @returns {Array<string>}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.get_keys = (...items) => items.reduce((keys, item) => {
|
||||||
|
|
||||||
|
if(Check.is_key(item))
|
||||||
|
item in keys || keys.push(item);
|
||||||
|
else if(Check.is_array(item))
|
||||||
|
Utils.get_keys(...item).forEach(key => key in keys || keys.push(key));
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {...(any|null)} items
|
||||||
|
* @returns {Array.<Object.<string, any|null>>}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.get_dictionaries = (...items) => items.reduce((dictionaries, item) => {
|
||||||
|
|
||||||
|
if(Check.is_dictionary(item))
|
||||||
|
dictionaries.push(item);
|
||||||
|
else if(Check.is_array(item))
|
||||||
|
dictionaries.push(...Utils.get_dictionaries(...item));
|
||||||
|
|
||||||
|
return dictionaries;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} items
|
||||||
|
* @param {!number} [custom_options = 0]
|
||||||
|
* @returns {Object.<string, any|null>}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.get_dictionary = (items, custom_options = 0) => {
|
||||||
|
|
||||||
|
/** @type {Object.<string, any|null>} */
|
||||||
|
const dictionary = {},
|
||||||
|
/** @type {Options} */
|
||||||
|
options = new Options(custom_options, Utils.GET_DICTIONARY_OPTIONS);
|
||||||
|
|
||||||
|
if(Check.is_dictionary(items)){
|
||||||
|
for(const [key, value] of Object.entries(items))
|
||||||
|
dictionary[key] = value;
|
||||||
|
}else if(Check.is_array(items))
|
||||||
|
items.forEach(item => {
|
||||||
|
for(const [key, value] of Object.entries(Utils.get_dictionary(item, options)))
|
||||||
|
if(options.overwrite || !(key in dictionary))
|
||||||
|
dictionary[key] = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
return dictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!(string|Array.<string>)} keys
|
||||||
|
* @param {!(Object.<string, any|null>|Array.<any|null>)} inputs
|
||||||
|
* @param {?any} [_default = null]
|
||||||
|
* @param {!number} [custom_options = 0]
|
||||||
|
* @returns {any|null}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.get_value = (keys, inputs, _default = null, custom_options = 0) => {
|
||||||
|
|
||||||
|
/** @type {number} */
|
||||||
|
const l = (keys = Utils.get_keys(keys)).length,
|
||||||
|
/** @type {Options} */
|
||||||
|
options = new Options(custom_options, Utils.GET_VALUE_OPTIONS);
|
||||||
|
|
||||||
|
if(l){
|
||||||
|
|
||||||
|
/** @type {number} */
|
||||||
|
const m = (inputs = Utils.get_dictionaries(inputs)).length;
|
||||||
|
|
||||||
|
for(let i = 0; i < l; i++)
|
||||||
|
for(let j = 0; j < m; j++)
|
||||||
|
if(keys[i] in inputs[j] && (options.allow_nulls || inputs[j][keys[i]] !== null))
|
||||||
|
return inputs[j][keys[i]];
|
||||||
|
};
|
||||||
|
return _default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} string
|
||||||
|
* @param {!(Object.<string, any|null>|Array.<any|null>)} variables
|
||||||
|
* @param {?any} _default
|
||||||
|
* @returns {string}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.string_variables = (string, variables, _default = null) => {
|
||||||
|
|
||||||
|
variables = Utils.get_dictionary(variables || {});
|
||||||
|
|
||||||
|
return ("" + string).replace(/\{([a-z_][a-z0-9_]*)\}/gi, (all, key) => (
|
||||||
|
key in variables ? variables[key] :
|
||||||
|
_default === null ? all :
|
||||||
|
_default));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} string
|
||||||
|
* @returns {string}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.to_kebab_case = string => ("" + string).replace(/([A-Z]+)|[^a-z0-9]+/g, (_, upper) => (
|
||||||
|
upper ? "-" + upper.toLowerCase() :
|
||||||
|
"-"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} string
|
||||||
|
* @returns {string}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.to_snake_case = string => ("" + string).replace(/([A-Z]+)|[^a-z0-9]+/g, (_, upper) => (
|
||||||
|
upper ? "_" + upper.toLowerCase() :
|
||||||
|
"_"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!HTMLElement} item
|
||||||
|
* @param {...Object.<string, any|null>} attributes
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.attributes = (item, attributes) => {
|
||||||
|
for(const [key, value] of Object.entries(attributes)){
|
||||||
|
if(/^on[_\-]?/i.test(key) && Check.is_function(value))
|
||||||
|
item.addEventListener(key.toLowerCase().replace(/^on[_\-]?/, ""), event => {
|
||||||
|
Utils.execute(value, item, event);
|
||||||
|
});
|
||||||
|
else
|
||||||
|
item.setAttribute(Utils.to_kebab_case(key), value);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!HTMLElement} item
|
||||||
|
* @param {...(string|HTMLElement|[string, Object.<string, any|null>|null, string|Array.<string>|null]|null)} structure
|
||||||
|
* @returns {Array.<HTMLElement>}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.html = (item, ...structure) => {
|
||||||
|
|
||||||
|
/** @type {Array.<HTMLElement>} */
|
||||||
|
const items = [];
|
||||||
|
|
||||||
|
item || (item = document.createDocumentFragment());
|
||||||
|
|
||||||
|
for(const node of structure)
|
||||||
|
if(Check.is_string(node))
|
||||||
|
item.innerHTML += node;
|
||||||
|
else if(Check.is_html_item(node))
|
||||||
|
items.push(item.appendChild(node));
|
||||||
|
else if(Check.is_array(node)){
|
||||||
|
|
||||||
|
/** @type {[string, Object.<string, any|null>|null, Array.<any|null>|null]} */
|
||||||
|
const [tag, attributes, children] = node.concat(null, null).slice(0, 3),
|
||||||
|
/** @type {HTMLElement} */
|
||||||
|
element = document.createElement(tag);
|
||||||
|
|
||||||
|
attributes && Utils.attributes(element, attributes);
|
||||||
|
if(children && children.length){
|
||||||
|
if(Check.is_string(children))
|
||||||
|
element.innerHTML += children;
|
||||||
|
else
|
||||||
|
Utils.html(element, ...children);
|
||||||
|
};
|
||||||
|
items.push(item.appendChild(element));
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return items;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} item
|
||||||
|
* @returns {any|null}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.unique = item => (
|
||||||
|
Check.is_array(item) ? item.filter((item, i, array) => array.indexOf(item) == i) :
|
||||||
|
Check.is_string(item) ? item.split("").filter((char, i, array) => array.indexOf(char) == i).join("") :
|
||||||
|
item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?(number|Array.<any|null>|string)} [from = null]
|
||||||
|
* @param {?number} [to = null]
|
||||||
|
* @returns {any|null}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.get_random = (from = null, to = null) => (
|
||||||
|
Check.is_array(from) || Check.is_string(from) ? from.length ? from[Math.random() * from.length >> 0] : null :
|
||||||
|
Check.is_integer(from) ? (
|
||||||
|
to === null ? Math.random() * from >> 0 :
|
||||||
|
Check.is_integer(to) ? from + (Math.random() * (to - from + 1) >> 0) :
|
||||||
|
Check.is_number(to) ? from + Math.random() * (to - from) :
|
||||||
|
null) :
|
||||||
|
Check.is_number(from) ? (
|
||||||
|
to === null ? Math.random() * from :
|
||||||
|
Check.is_number(to) ? from + Math.random() * (to - from) :
|
||||||
|
null) :
|
||||||
|
from === null ? Math.random() :
|
||||||
|
null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} data
|
||||||
|
* @returns {string}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.encode_data = data => btoa(encodeURIComponent(JSON.stringify(data)).replace(/%([0-9A-F]{2})/g, (_, p1) => String.fromCharCode("0x" + p1)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} code
|
||||||
|
* @param {!boolean} [is_json = true]
|
||||||
|
* @returns {any|null}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.decode_data = (code, is_json = true) => {
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
|
const data = decodeURIComponent(atob(code).split("").map(c => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2)).join(""));
|
||||||
|
|
||||||
|
if(is_json)
|
||||||
|
try{
|
||||||
|
return JSON.parse(data) || data;
|
||||||
|
}catch(exception){};
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!utils_execute_callback} callback
|
||||||
|
* @param {...(any|null)} inputs
|
||||||
|
* @returns {any|null}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.execute = (callback, ...inputs) => (
|
||||||
|
Check.is_function(callback) ? callback(...inputs) :
|
||||||
|
null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!Array.<any|null>} array
|
||||||
|
* @param {!utils_execute_array_each_callback} each_callback
|
||||||
|
* @param {?utils_default_callback} [end_callback = null]
|
||||||
|
* @param {!number} [i = 0]
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.execute_array = (array, each_callback, end_callback = null, i = 0) => {
|
||||||
|
if(i < array.length)
|
||||||
|
Utils.execute(each_callback, array[i], () => {
|
||||||
|
Utils.execute_array(array, each_callback, end_callback, i + 1);
|
||||||
|
});
|
||||||
|
else
|
||||||
|
Utils.execute(end_callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} item
|
||||||
|
* @returns {Array.<any|null>}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.get_array = item => Check.is_array(item) ? item : [item];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!string} string
|
||||||
|
* @returns {string}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.randomize_string = string => string.split("").sort(() => Utils.get_random() - 0.5).join("");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {?any} data
|
||||||
|
* @returns {string}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.encrypt_data = data => Utils.encode_data(data).split("").map(character => Utils.RANDOM_ALPHABET[Utils.BASE64_ALPHABET.indexOf(character)]).join("");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} data
|
||||||
|
* @returns {any|null}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.decrypt_data = data => {
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
|
const results = Utils.decode_data(data.split("").map(character => Utils.BASE64_ALPHABET[Utils.RANDOM_ALPHABET.indexOf(character)]).join(""), false);
|
||||||
|
|
||||||
|
try{
|
||||||
|
return JSON.parse(results) || results;
|
||||||
|
}catch(exception){};
|
||||||
|
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!Array.<any|null>} array
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.randomize_array = array => {
|
||||||
|
|
||||||
|
/** @type {number} */
|
||||||
|
const l = array.length - 1;
|
||||||
|
|
||||||
|
array.forEach((item, i) => {
|
||||||
|
|
||||||
|
/** @type {number} */
|
||||||
|
const j = Utils.get_random(l);
|
||||||
|
|
||||||
|
i != j && ([array[i], array[j]] = [array[j], array[i]]);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!any} base
|
||||||
|
* @param {...any} items
|
||||||
|
* @returns {void}
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
Utils.extends = (base, ...items) => {
|
||||||
|
items.forEach(item => {
|
||||||
|
Object.entries(item).forEach(([key, value]) => {
|
||||||
|
base[key] = value;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return Utils;
|
||||||
|
})();
|
||||||
1
Public/json/AnP.settings.json
Normal file
1
Public/json/AnP.settings.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
3
Public/json/i18n/anP.i18n.espanol.json
Normal file
3
Public/json/i18n/anP.i18n.espanol.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"espanol" : {}
|
||||||
|
}
|
||||||
44
Python/Abstracts/BaseAbstract.py
Normal file
44
Python/Abstracts/BaseAbstract.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Self, Callable, Optional
|
||||||
|
from Interfaces.Application.AnPInterface import AnPInterface
|
||||||
|
|
||||||
|
class BaseAbstract:
|
||||||
|
|
||||||
|
def _build(self:Self) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self:Self, anp:AnPInterface, key:str) -> None:
|
||||||
|
self.anp:AnPInterface = anp
|
||||||
|
self.key:str = key
|
||||||
|
self._built:bool = False
|
||||||
|
self._started:bool = False
|
||||||
|
self._stopped:bool = False
|
||||||
|
|
||||||
|
self._build()
|
||||||
|
self._built = True
|
||||||
|
|
||||||
|
def _start(self:Self, callback:Optional[Callable[[bool], bool]] = None) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def start(self:Self, callback:Optional[Callable[[bool], bool]] = None) -> bool:
|
||||||
|
if self._started:
|
||||||
|
return False if callback is None else callback(False)
|
||||||
|
self._started = True
|
||||||
|
|
||||||
|
self._stopped = False
|
||||||
|
return True if callback is None else callback(True)
|
||||||
|
|
||||||
|
def _close(self:Self, callback:Optional[Callable[[bool], bool]] = None) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def close(self:Self, callback:Optional[Callable[[bool], bool]] = None) -> bool:
|
||||||
|
if self._stopped:
|
||||||
|
return False if callback is None else callback(False)
|
||||||
|
self._started = False
|
||||||
|
|
||||||
|
self._close(callback)
|
||||||
|
|
||||||
|
self._stopped = True
|
||||||
|
return True if callback is None else callback(True)
|
||||||
33
Python/Application/AnP.py
Normal file
33
Python/Application/AnP.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Self, Any, Optional, Sequence
|
||||||
|
from Managers.SettingsManager import SettingsManager
|
||||||
|
from Managers.I18NManager import I18NManager
|
||||||
|
from Managers.PrintTypesManager import PrintTypesManager
|
||||||
|
|
||||||
|
class AnP:
|
||||||
|
|
||||||
|
def __init__(self:Self,
|
||||||
|
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None
|
||||||
|
) -> None:
|
||||||
|
self.i18n:I18NManager = I18NManager(self)
|
||||||
|
self.print_types:PrintTypesManager = PrintTypesManager(self)
|
||||||
|
self.settings:SettingsManager = SettingsManager(self, inputs)
|
||||||
|
|
||||||
|
def print(self:Self,
|
||||||
|
_type:str,
|
||||||
|
data:Any|None,
|
||||||
|
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None,
|
||||||
|
i:int = 0
|
||||||
|
) -> None:
|
||||||
|
|
||||||
|
own:dict[str, Any|None] = {}
|
||||||
|
|
||||||
|
def exception(self:Self,
|
||||||
|
exception:Exception,
|
||||||
|
message:str|Sequence[str],
|
||||||
|
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None,
|
||||||
|
i:int = 0
|
||||||
|
) -> None:
|
||||||
|
pass
|
||||||
31
Python/Interfaces/Application/AnPInterface.py
Normal file
31
Python/Interfaces/Application/AnPInterface.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Self, Any, Optional, Sequence
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from Interfaces.Managers.SettingsManagerInterface import SettingsManagerInterface
|
||||||
|
from Interfaces.Managers.I18NManagerInterface import I18NManagerInterface
|
||||||
|
from Interfaces.Managers.PrintTypesManagerInterface import PrintTypesManagerInterface
|
||||||
|
|
||||||
|
class AnPInterface(ABC):
|
||||||
|
|
||||||
|
def __init__(self:Self, inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None) -> None:
|
||||||
|
self.print_types:PrintTypesManagerInterface = None
|
||||||
|
self.i18n:I18NManagerInterface = None
|
||||||
|
self.settings:SettingsManagerInterface = None
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def print(self:Self,
|
||||||
|
_type:str,
|
||||||
|
data:Any|None,
|
||||||
|
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None,
|
||||||
|
i:int = 0
|
||||||
|
) -> None:pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def exception(self:Self,
|
||||||
|
exception:Exception,
|
||||||
|
message:str|Sequence[str],
|
||||||
|
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None,
|
||||||
|
i:int = 0
|
||||||
|
) -> None:pass
|
||||||
18
Python/Interfaces/Managers/I18NManagerInterface.py
Normal file
18
Python/Interfaces/Managers/I18NManagerInterface.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Any, Self, Sequence, Optional
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
class I18NManagerInterface(ABC):
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get(self:Self,
|
||||||
|
strings:str|Sequence[str],
|
||||||
|
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None,
|
||||||
|
languages:Optional[str|Sequence[str]] = None,
|
||||||
|
custom_options:int = 0
|
||||||
|
) -> Any|None:pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def add(self:Self, inputs:Any|None, custom_options:int = 0) -> None:pass
|
||||||
13
Python/Interfaces/Managers/PrintTypesManagerInterface.py
Normal file
13
Python/Interfaces/Managers/PrintTypesManagerInterface.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Any, Self
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
class PrintTypesManagerInterface(ABC):
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get(self:Self, _type:str) -> str:pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def add(self:Self, inputs:Any|None, custom_options:int = 0) -> None:pass
|
||||||
18
Python/Interfaces/Managers/SettingsManagerInterface.py
Normal file
18
Python/Interfaces/Managers/SettingsManagerInterface.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Any, Self, Sequence, Optional
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
class SettingsManagerInterface(ABC):
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get(self:Self,
|
||||||
|
keys:str|Sequence[str],
|
||||||
|
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None,
|
||||||
|
default:Any|None = None,
|
||||||
|
custom_options:int = 0
|
||||||
|
) -> Any|None:pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def add(self:Self, inputs:Any|None, custom_options:int = 0) -> None:pass
|
||||||
72
Python/Managers/I18NManager.py
Normal file
72
Python/Managers/I18NManager.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Any, Self, Sequence, Optional
|
||||||
|
from Interfaces.Application.AnPInterface import AnPInterface
|
||||||
|
from Utils.Utils import Utils
|
||||||
|
from Utils.Options import Options
|
||||||
|
|
||||||
|
class I18NManager:
|
||||||
|
|
||||||
|
DEFAULT_SENTENCES:dict[str, Any|None] = {
|
||||||
|
"english" : {}
|
||||||
|
}
|
||||||
|
|
||||||
|
GET_OPTIONS:Options = Options(Options.ALLOW_NULLS)
|
||||||
|
ADD_OPTIONS:Options = Options(Options.NO_OVERWRITE)
|
||||||
|
|
||||||
|
def __init__(self:Self, anp:AnPInterface) -> None:
|
||||||
|
self.anp:AnPInterface = anp
|
||||||
|
|
||||||
|
self.__sentences:dict[str, Any|None] = self.DEFAULT_SENTENCES
|
||||||
|
self.__language:str = "english"
|
||||||
|
self.__default_language:str = "english"
|
||||||
|
|
||||||
|
def __get_sentence(self:Self,
|
||||||
|
strings:str|Sequence[str],
|
||||||
|
languages:list[str],
|
||||||
|
options:Options
|
||||||
|
) -> str|list[str]|None:
|
||||||
|
|
||||||
|
keys:list[str] = Utils.get_keys(strings)
|
||||||
|
|
||||||
|
if len(keys):
|
||||||
|
|
||||||
|
languages_used:list[str] = []
|
||||||
|
language:str
|
||||||
|
|
||||||
|
for language in languages + [
|
||||||
|
self.__language, self.__default_language
|
||||||
|
] + list(self.__sentences.keys()):
|
||||||
|
if language in languages_used:
|
||||||
|
continue
|
||||||
|
|
||||||
|
key:str
|
||||||
|
|
||||||
|
languages_used.append(language)
|
||||||
|
|
||||||
|
for key in keys:
|
||||||
|
if key in self.__sentences[language] and (
|
||||||
|
options.allow_null or
|
||||||
|
self.__sentences[language][key] is not None
|
||||||
|
):
|
||||||
|
return self.__sentences[language][key]
|
||||||
|
return Utils.get_strings(strings)[0]
|
||||||
|
|
||||||
|
def get(self:Self,
|
||||||
|
strings:str|Sequence[str],
|
||||||
|
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None,
|
||||||
|
languages:Optional[str|Sequence[str]] = None,
|
||||||
|
custom_options:int = 0
|
||||||
|
) -> Any|None:
|
||||||
|
|
||||||
|
options:Options = Options(custom_options, self.GET_OPTIONS)
|
||||||
|
text:str|list[str]|None = self.__get_sentence(strings, Utils.get_array(languages), options)
|
||||||
|
|
||||||
|
return Utils.string_variables((
|
||||||
|
text if isinstance(text, str) else
|
||||||
|
"".join(text) if isinstance(text, (list, tuple)) else
|
||||||
|
str(text)), inputs)
|
||||||
|
|
||||||
|
def add(self:Self, inputs:Any|None, custom_options:int = 0) -> None:
|
||||||
|
pass
|
||||||
26
Python/Managers/PrintTypesManager.py
Normal file
26
Python/Managers/PrintTypesManager.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Any, Self
|
||||||
|
from Interfaces.Application.AnPInterface import AnPInterface
|
||||||
|
from Models.PrintTypeModel import PrintTypeModel
|
||||||
|
|
||||||
|
class PrintTypesManager:
|
||||||
|
|
||||||
|
def __init__(self:Self, anp:AnPInterface) -> None:
|
||||||
|
self.anp:AnPInterface = anp
|
||||||
|
self.__print_types:list[PrintTypeModel] = [
|
||||||
|
PrintTypeModel(["unkn", "unknown"], "#888")
|
||||||
|
]
|
||||||
|
|
||||||
|
def get(self:Self, _type:str) -> str:
|
||||||
|
|
||||||
|
subset:list[str]
|
||||||
|
|
||||||
|
for subset in self.__print_types:
|
||||||
|
if _type in subset:
|
||||||
|
return subset[0]
|
||||||
|
return self.__print_types[0][0]
|
||||||
|
|
||||||
|
def add(self:Self, inputs:Any|None, custom_options:int = 0) -> None:
|
||||||
|
pass
|
||||||
36
Python/Managers/SettingsManager.py
Normal file
36
Python/Managers/SettingsManager.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Any, Self, Sequence, Optional
|
||||||
|
from Interfaces.Application.AnPInterface import AnPInterface
|
||||||
|
from Utils.Utils import Utils
|
||||||
|
from Utils.Options import Options
|
||||||
|
|
||||||
|
class SettingsManager:
|
||||||
|
|
||||||
|
DEFAUTL_SETTINGS:dict[str, Any|None] = {}
|
||||||
|
|
||||||
|
GET_OPTIONS:Options = Options(Options.ALLOW_NULLS)
|
||||||
|
ADD_OPTIONS:Options = Options(Options.NO_OVERWRITE)
|
||||||
|
|
||||||
|
def __init__(self:Self,
|
||||||
|
anp:AnPInterface,
|
||||||
|
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None
|
||||||
|
) -> None:
|
||||||
|
self.anp:AnPInterface = anp
|
||||||
|
|
||||||
|
self.__inputs:dict[str, Any|None] = Utils.get_dictionary(inputs, Options.OVERWRITE)
|
||||||
|
self.__secrets:dict[str, Any|None] = {}
|
||||||
|
|
||||||
|
def get(self:Self,
|
||||||
|
keys:str|Sequence[str],
|
||||||
|
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None,
|
||||||
|
default:Any|None = None,
|
||||||
|
custom_options:int = 0
|
||||||
|
) -> Any|None:
|
||||||
|
return Utils.get_value(keys, (
|
||||||
|
inputs, self.__inputs, self.__secrets, self.DEFAUTL_SETTINGS
|
||||||
|
), default, Options(custom_options, self.GET_OPTIONS).get())
|
||||||
|
|
||||||
|
def add(self:Self, inputs:Any|None, custom_options:int = 0) -> None:
|
||||||
|
pass
|
||||||
30
Python/Models/PrintTypeModel.py
Normal file
30
Python/Models/PrintTypeModel.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Optional, Self, Sequence
|
||||||
|
from Utils.Color import Color
|
||||||
|
from Utils.Utils import Utils
|
||||||
|
|
||||||
|
class PrintTypeModel:
|
||||||
|
|
||||||
|
def __init__(self:Self,
|
||||||
|
names:str|Sequence[str],
|
||||||
|
fore:str|int|Sequence[int]|Color,
|
||||||
|
back:Optional[str|int|Sequence[int]|Color] = None
|
||||||
|
) -> None:
|
||||||
|
|
||||||
|
self.names:list[str] = []
|
||||||
|
self.name:str
|
||||||
|
self.fore:Color = Color(fore)
|
||||||
|
self.back:Color|None = None if back is None else Color(back)
|
||||||
|
|
||||||
|
self.add_names(names)
|
||||||
|
self.name = self.names[0].upper()
|
||||||
|
|
||||||
|
def add_names(self:Self, names:str|Sequence[str]) -> None:
|
||||||
|
|
||||||
|
name:str
|
||||||
|
|
||||||
|
for name in Utils.get_keys(names, self.names):
|
||||||
|
if name not in self.names:
|
||||||
|
self.names.append(name)
|
||||||
27
Python/Utils/Check.py
Normal file
27
Python/Utils/Check.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Any, Self
|
||||||
|
from Utils.Patterns import RE
|
||||||
|
|
||||||
|
class Check:
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_string(value:Any|None) -> bool:
|
||||||
|
return isinstance(value, str)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_key(cls:type[Self], value:Any|None) -> bool:
|
||||||
|
return cls.is_string(value) and RE.KEY.match(value) is not None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_array(value:Any|None) -> bool:
|
||||||
|
return isinstance(value, (list, tuple))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_dictionary(value:Any|None) -> bool:
|
||||||
|
return isinstance(value, dict)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_integer(value:Any|None) -> bool:
|
||||||
|
return isinstance(value, int)
|
||||||
75
Python/Utils/Color.py
Normal file
75
Python/Utils/Color.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Self, Sequence
|
||||||
|
from Utils.Check import Check
|
||||||
|
|
||||||
|
class Color:
|
||||||
|
|
||||||
|
def __init__(self:Self, inputs:str|int|Sequence[int]|Self, _type:str = "rgba") -> None:
|
||||||
|
|
||||||
|
self.red:int = 0x00
|
||||||
|
self.green:int = 0x00
|
||||||
|
self.blue:int = 0x00
|
||||||
|
self.alpha:int = 0xFF
|
||||||
|
|
||||||
|
if Check.is_string(inputs):
|
||||||
|
if inputs.startswith("#"):
|
||||||
|
inputs = inputs[1:]
|
||||||
|
if len(inputs) in (3, 4):
|
||||||
|
inputs = "".join([character * 2 for character in inputs])
|
||||||
|
if len(inputs) in (7, 9):
|
||||||
|
inputs = ("FF" + inputs[1:])[-8:]
|
||||||
|
self.alpha, self.red, self.green, self.blue = [int(inputs[i:i + 2], 16) for i in (0, 2, 4, 6)]
|
||||||
|
elif inputs.startswith("rgb"):
|
||||||
|
self.red, self.green, self.blue, self.alpha = ([(
|
||||||
|
int(item) if i < 3 else
|
||||||
|
int(float(item) * 0xFF)) for item, i in enumerate(inputs[inputs.find("(") + 1:inputs.find(")")].split(","))] + [0xFF])[:4]
|
||||||
|
elif Check.is_integer(inputs):
|
||||||
|
self.alpha = 0xFF - ((inputs >> 24) & 0xFF)
|
||||||
|
self.red = (inputs >> 16) & 0xFF
|
||||||
|
self.green = (inputs >> 8) & 0xFF
|
||||||
|
self.blue = inputs & 0xFF
|
||||||
|
elif Check.is_array(inputs):
|
||||||
|
if _type in ("rgb", "rgba") or True:
|
||||||
|
self.red, self.green, self.blue, self.alpha = (inputs + [0xFF] * 4)[:4]
|
||||||
|
elif isinstance(inputs, Color):
|
||||||
|
self.red = inputs.red
|
||||||
|
self.green = inputs.green
|
||||||
|
self.blue = inputs.blue
|
||||||
|
self.alpha = inputs.alpha
|
||||||
|
|
||||||
|
def to_rgba(self:Self) -> str:
|
||||||
|
return f"rgba({self.red}, {self.green}, {self.blue}, {self.alpha / 0xFF:.2f})"
|
||||||
|
|
||||||
|
def to_rgb(self:Self) -> str:
|
||||||
|
return f"rgb({self.red}, {self.green}, {self.blue})"
|
||||||
|
|
||||||
|
def to_hex(self:Self, with_alpha:bool = False) -> str:
|
||||||
|
return "#" + (f"{self.alpha:02X}" if with_alpha else "") + f"{self.red:02X}{self.green:02X}{self.blue:02X}"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def mix(*colors:str|int|Sequence[int]|Self) -> Self:
|
||||||
|
if len(colors) == 0:
|
||||||
|
return Color(0)
|
||||||
|
|
||||||
|
base:Color = Color(colors[0])
|
||||||
|
color:str|int|Sequence[int]|Color
|
||||||
|
l:int = len(colors)
|
||||||
|
|
||||||
|
if l != 1:
|
||||||
|
for color in colors[1:]:
|
||||||
|
|
||||||
|
subcolor:Color = Color(color)
|
||||||
|
|
||||||
|
base.red += subcolor.red
|
||||||
|
base.green += subcolor.green
|
||||||
|
base.blue += subcolor.blue
|
||||||
|
base.alpha += subcolor.alpha
|
||||||
|
|
||||||
|
base.red //= l
|
||||||
|
base.green //= l
|
||||||
|
base.blue //= l
|
||||||
|
base.alpha //= l
|
||||||
|
|
||||||
|
return base
|
||||||
60
Python/Utils/Options.py
Normal file
60
Python/Utils/Options.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Self, Optional
|
||||||
|
|
||||||
|
class Options:
|
||||||
|
|
||||||
|
OVERWRITING:int = 0
|
||||||
|
OVERWRITE:int = 1 * 3 ** OVERWRITING
|
||||||
|
NO_OVERWRITE:int = 2 * 3 ** OVERWRITING
|
||||||
|
|
||||||
|
NULLISH:int = 1
|
||||||
|
ALLOW_NULLS:int = 1 * 3 ** NULLISH
|
||||||
|
NOT_NULLS:int = 2 * 3 ** NULLISH
|
||||||
|
|
||||||
|
DEFAULT:Self = Self(NO_OVERWRITE + ALLOW_NULLS)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_value(cls:type[Self], value:int, option:int) -> bool|None:
|
||||||
|
|
||||||
|
ternary:int = value // 3 ** option % 3
|
||||||
|
|
||||||
|
return (
|
||||||
|
True if ternary == 1 else
|
||||||
|
False if ternary == 2 else
|
||||||
|
None)
|
||||||
|
|
||||||
|
def __init__(self:Self, options:int = 0, default:Optional[Self] = None) -> None:
|
||||||
|
|
||||||
|
self.overwrite:bool|None
|
||||||
|
self.allow_null:bool|None
|
||||||
|
|
||||||
|
if default is None:
|
||||||
|
default = self.DEFAULT
|
||||||
|
|
||||||
|
for key, option in (
|
||||||
|
("overwrite", self.OVERWRITE),
|
||||||
|
("allow_null", self.NULLISH)
|
||||||
|
):
|
||||||
|
|
||||||
|
value:bool|None = self.get_value(options, option)
|
||||||
|
|
||||||
|
setattr(self, key, getattr(default, key) if value is None and default is not None else value)
|
||||||
|
|
||||||
|
def get(self:Self) -> int:
|
||||||
|
|
||||||
|
code:int = 0
|
||||||
|
option:int
|
||||||
|
value:bool|None
|
||||||
|
|
||||||
|
for option, value in (
|
||||||
|
(self.OVERWRITING, self.overwrite),
|
||||||
|
(self.NULLISH, self.allow_null)
|
||||||
|
):
|
||||||
|
code += (
|
||||||
|
1 if value is True else
|
||||||
|
2 if value is False else
|
||||||
|
0) * 3 ** option
|
||||||
|
|
||||||
|
return code
|
||||||
8
Python/Utils/Patterns.py
Normal file
8
Python/Utils/Patterns.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from re import compile as re_compile, Pattern as REPattern, I as RE_IGNORE_CASE
|
||||||
|
|
||||||
|
class RE:
|
||||||
|
KEY:REPattern = re_compile(r'^[a-z_][a-z0-9_]*$', RE_IGNORE_CASE)
|
||||||
|
STRING_VARIABLES:REPattern = re_compile(r'\{([a-z_][a-z0-9_]*)\}', RE_IGNORE_CASE)
|
||||||
140
Python/Utils/Utils.py
Normal file
140
Python/Utils/Utils.py
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Any, Self, Sequence, Optional
|
||||||
|
from re import Match as REMatch
|
||||||
|
from Utils.Check import Check
|
||||||
|
from Utils.Options import Options
|
||||||
|
from Utils.Patterns import RE
|
||||||
|
|
||||||
|
class Utils:
|
||||||
|
|
||||||
|
GET_DICTIONARY_OPTIONS:Options = Options(Options.NO_OVERWRITE)
|
||||||
|
GET_VALUE_OPTIONS:Options = Options(Options.ALLOW_NULLS)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_keys(cls:type[Self], *items:Any|None) -> list[str]:
|
||||||
|
|
||||||
|
keys:list[str] = []
|
||||||
|
item:Any|None
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
if Check.is_key(item):
|
||||||
|
item in keys or keys.append(item)
|
||||||
|
elif Check.is_array(item):
|
||||||
|
|
||||||
|
key:str
|
||||||
|
|
||||||
|
for key in cls.get_keys(*item):
|
||||||
|
key in keys or keys.append(key)
|
||||||
|
|
||||||
|
return keys
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_dictionaries(cls:type[Self], *items:Any|None) -> list[dict[str, Any|None]]:
|
||||||
|
|
||||||
|
dictionaries:list[dict[str, Any|None]] = []
|
||||||
|
item:Any|None
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
if Check.is_dictionary(item):
|
||||||
|
item in dictionaries or dictionaries.append(item)
|
||||||
|
elif Check.is_array(item):
|
||||||
|
|
||||||
|
dictionary:dict
|
||||||
|
|
||||||
|
for dictionary in cls.get_dictionaries(*item):
|
||||||
|
dictionary in dictionaries or dictionaries.append(dictionary)
|
||||||
|
|
||||||
|
return dictionaries
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_dictionary(cls:type[Self], items:Any|None, custom_options:int = 0) -> dict[str, Any|None]:
|
||||||
|
|
||||||
|
dictionary:dict[str, Any|None] = {}
|
||||||
|
|
||||||
|
options:Options = Options(custom_options, cls.GET_DICTIONARY_OPTIONS)
|
||||||
|
|
||||||
|
if Check.is_dictionary(items):
|
||||||
|
dictionary = items
|
||||||
|
elif Check.is_array(items):
|
||||||
|
|
||||||
|
item:Any|None
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
|
||||||
|
key:str
|
||||||
|
value:Any|None
|
||||||
|
|
||||||
|
for key, value in cls.get_dictionary(item, options).items():
|
||||||
|
if options.overwrite or key not in dictionary:
|
||||||
|
dictionary[key] = value
|
||||||
|
|
||||||
|
return dictionary
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_value(cls:type[Self],
|
||||||
|
keys:str|Sequence[str],
|
||||||
|
inputs:dict[str, Any|None]|Sequence[Any|None],
|
||||||
|
default:Optional[Any] = None,
|
||||||
|
custom_options:int = 0
|
||||||
|
) -> Any|None:
|
||||||
|
|
||||||
|
options:Options = Options(custom_options, cls.GET_VALUE_OPTIONS)
|
||||||
|
|
||||||
|
if len(keys := cls.get_keys(keys)):
|
||||||
|
|
||||||
|
subinputs:dict[str, Any|None]
|
||||||
|
|
||||||
|
for subinputs in cls.get_dictionaries(inputs):
|
||||||
|
|
||||||
|
key:str
|
||||||
|
|
||||||
|
for key in keys:
|
||||||
|
if key in subinputs and (
|
||||||
|
options.allow_null or
|
||||||
|
subinputs[key] is not None
|
||||||
|
):
|
||||||
|
return subinputs[key]
|
||||||
|
return default
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_array(value:Any|None) -> list[Any]:
|
||||||
|
return (
|
||||||
|
value if isinstance(value, list) else
|
||||||
|
list(value) if isinstance(value, (set, tuple)) else
|
||||||
|
[value])
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_strings(value:Any|None) -> list[str]:
|
||||||
|
|
||||||
|
strings:list[str] = []
|
||||||
|
item:Any|None
|
||||||
|
|
||||||
|
for item in Utils.get_array(value):
|
||||||
|
if Check.is_string(item):
|
||||||
|
item in strings or strings.append(item)
|
||||||
|
elif Check.is_array(item):
|
||||||
|
strings.extend(Utils.get_strings(item))
|
||||||
|
|
||||||
|
return strings
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def string_variables(cls:type[Self],
|
||||||
|
string:str,
|
||||||
|
variables:dict[str, Any|None],
|
||||||
|
default:Optional[str] = None
|
||||||
|
) -> str:
|
||||||
|
|
||||||
|
variables = Utils.get_dictionary(variables)
|
||||||
|
|
||||||
|
def callback(matches:REMatch) -> str:
|
||||||
|
|
||||||
|
key:str = matches.group(1)
|
||||||
|
|
||||||
|
return (
|
||||||
|
str(variables[key]) if key in variables else
|
||||||
|
default if default is not None else
|
||||||
|
matches.group(0))
|
||||||
|
|
||||||
|
return RE.STRING_VARIABLES.sub(callback, string)
|
||||||
36
README.md
36
README.md
@ -1,3 +1,39 @@
|
|||||||
# AnPv2
|
# AnPv2
|
||||||
|
|
||||||
AnP Framework, version 2.
|
AnP Framework, version 2.
|
||||||
|
|
||||||
|
## .NET
|
||||||
|
|
||||||
|
- Docker Hub del SDK: https://hub.docker.com/r/microsoft/dotnet-sdk
|
||||||
|
- Git del SDK: https://github.com/dotnet/sdk
|
||||||
|
|
||||||
|
Para crear los SLN de la Solución:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
docker exec -it anp-dotnet bash
|
||||||
|
|
||||||
|
cd CSharp
|
||||||
|
dotnet new sln -n AnP
|
||||||
|
dotnet sln add AnP.csproj
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
exit
|
||||||
|
|
||||||
|
sudo chown -R root:$USER CSharp/AnP.slnx
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Instalación del SDK para desarrollo VSCode.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/bin/bash
|
||||||
|
wget https://packages.microsoft.com/config/ubuntu/24.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
|
||||||
|
sudo dpkg -i packages-microsoft-prod.deb
|
||||||
|
rm packages-microsoft-prod.deb
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y dotnet-sdk-10.0
|
||||||
|
```
|
||||||
|
|
||||||
|
Luego, instalar el Pluggin Nuget de Visual Studio Code `C/C++ DevTools`.
|
||||||
690
SQLServer/AnP.1.10.common.server.sql
Normal file
690
SQLServer/AnP.1.10.common.server.sql
Normal file
@ -0,0 +1,690 @@
|
|||||||
|
if (select top 1 0 from sys.databases where name = 'AnP') is null create database AnP collate Latin1_General_CI_AS
|
||||||
|
go
|
||||||
|
use AnP
|
||||||
|
|
||||||
|
if object_id(N'dbo.common_tables_delete', N'P') is not null drop procedure dbo.common_tables_delete
|
||||||
|
go
|
||||||
|
create procedure dbo.common_tables_delete as begin
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
if object_id(N'dbo.fk_sessions_user', N'F') is not null
|
||||||
|
alter table dbo.[Sessions] drop constraint fk_sessions_user
|
||||||
|
|
||||||
|
-- Level 3.
|
||||||
|
if object_id(N'dbo.Logs', N'U') is not null drop table dbo.Logs
|
||||||
|
if object_id(N'dbo.Exceptions', N'U') is not null drop table dbo.Exceptions
|
||||||
|
if object_id(N'dbo.Terminals', N'U') is not null drop table dbo.Terminals
|
||||||
|
if object_id(N'dbo.SessionsIps', N'U') is not null drop table dbo.SessionsIps
|
||||||
|
|
||||||
|
-- Level 2.
|
||||||
|
if object_id(N'dbo.[Sessions]', N'U') is not null drop table dbo.[Sessions]
|
||||||
|
|
||||||
|
-- Level 1.
|
||||||
|
if object_id(N'dbo.[Procedures]', N'U') is not null drop table dbo.[Procedures]
|
||||||
|
if object_id(N'dbo.Users', N'U') is not null drop table dbo.Users
|
||||||
|
|
||||||
|
-- Level 0.
|
||||||
|
if object_id(N'dbo.Ips', N'U') is not null drop table dbo.Ips
|
||||||
|
if object_id(N'dbo.[Databases]', N'U') is not null drop table dbo.[Databases]
|
||||||
|
if object_id(N'dbo.Hashes', N'U') is not null drop table dbo.Hashes
|
||||||
|
if object_id(N'dbo.[Messages]', N'U') is not null drop table dbo.[Messages]
|
||||||
|
if object_id(N'dbo.Errors', N'U') is not null drop table dbo.Errors
|
||||||
|
|
||||||
|
-- Level historical.
|
||||||
|
if object_id(N'dbo.UsersData', N'U') is not null drop table dbo.UsersData
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.common_tables_create', N'P') is not null drop procedure dbo.common_tables_create
|
||||||
|
go
|
||||||
|
create procedure dbo.common_tables_create as begin
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
-- Level historical.
|
||||||
|
if object_id(N'dbo.UsersData', N'U') is null create table dbo.UsersData(
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
entity integer not null,
|
||||||
|
[procedure] integer not null,
|
||||||
|
[session] integer not null,
|
||||||
|
[hash] integer,
|
||||||
|
nick varchar(32) collate database_default,
|
||||||
|
[password] binary(64),
|
||||||
|
accessible bit,
|
||||||
|
date_in datetime not null,
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_users_data primary key clustered (id)
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Level 0.
|
||||||
|
if object_id(N'dbo.[Databases]', N'U') is null create table dbo.[Databases](
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
[name] varchar(64) collate database_default not null,
|
||||||
|
date_in datetime not null constraint df_databases_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_databases primary key clustered (id),
|
||||||
|
constraint uk_databases_name unique nonclustered ([name] asc) with (fillfactor = 90),
|
||||||
|
constraint ck_databases_name check (
|
||||||
|
[name] != '' and
|
||||||
|
[name] like '[a-z_]%' and
|
||||||
|
[name] not like '%[^a-z0-9_]%'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if object_id(N'dbo.[Messages]', N'U') is null create table dbo.[Messages](
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
[message] varchar(max) collate database_default not null,
|
||||||
|
date_in datetime not null constraint df_messages_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_messages primary key clustered (id)
|
||||||
|
)
|
||||||
|
|
||||||
|
if object_id(N'dbo.Hashes', N'U') is null create table dbo.Hashes(
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
[name] varchar(16) collate database_default not null,
|
||||||
|
date_in datetime not null constraint df_hashes_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_hashes primary key clustered (id),
|
||||||
|
constraint uk_hashes_name unique nonclustered ([name] asc) with (fillfactor = 90),
|
||||||
|
constraint ck_hashes_name check ([name] != '')
|
||||||
|
)
|
||||||
|
|
||||||
|
if object_id(N'dbo.Errors', N'U') is null create table dbo.Errors(
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
[error] varchar(512) collate database_default not null,
|
||||||
|
date_in datetime not null constraint df_errors_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_errors primary key clustered (id),
|
||||||
|
constraint uk_errors_error unique nonclustered ([error] asc) with (fillfactor = 90)
|
||||||
|
)
|
||||||
|
|
||||||
|
create table dbo.Ips(
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
[ip] varchar(45) collate database_default not null, -- 3x4+3=15 for IPv4; 8x4+7=39 for IPv6; 30+15 for Hibrid.
|
||||||
|
date_in datetime not null constraint df_ips_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_ips primary key clustered (id),
|
||||||
|
constraint uk_ips_ip unique nonclustered ([ip] asc) with (fillfactor = 90),
|
||||||
|
constraint ck_ips_ip check (len([ip]) > 1 and [ip] not like '%[^0-9a-f:.]%'),
|
||||||
|
index ix_ips_ip nonclustered ([ip] asc) with (fillfactor = 90)
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Level 1.
|
||||||
|
if object_id(N'dbo.[Procedures]', N'U') is null begin
|
||||||
|
create table dbo.[Procedures](
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
[database] integer not null,
|
||||||
|
[name] varchar(64) collate database_default not null,
|
||||||
|
date_in datetime not null constraint df_procedures_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_procedures primary key clustered (id),
|
||||||
|
constraint fk_procedures_database foreign key([database]) references dbo.[Databases](id),
|
||||||
|
constraint uk_procedures_name unique([database], [name]),
|
||||||
|
constraint ck_procedures_database check ([database] > 0),
|
||||||
|
constraint ck_procedures_name check (
|
||||||
|
[name] != '' and
|
||||||
|
[name] like '[a-z_]%' and
|
||||||
|
[name] not like '%[^a-z0-9_]%'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
create nonclustered index ix_procedures_name on dbo.[Procedures]([name] asc) include ([database]) with (fillfactor = 90)
|
||||||
|
end
|
||||||
|
|
||||||
|
if object_id(N'dbo.Users', N'U') is null create table dbo.Users(
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
[hash] integer not null constraint df_users_hash default 1,
|
||||||
|
nick varchar(32) collate database_default not null,
|
||||||
|
[password] binary(64),
|
||||||
|
accessible bit not null constraint df_users_accessible default 1,
|
||||||
|
date_in datetime not null constraint df_users_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_users_id primary key clustered (id),
|
||||||
|
constraint fk_users_hash foreign key([hash]) references dbo.Hashes(id),
|
||||||
|
constraint uk_users_nick unique nonclustered (nick asc) with (fillfactor = 90),
|
||||||
|
constraint ck_users_hash check ([hash] > 0),
|
||||||
|
constraint ck_users_nick check (nick != ''),
|
||||||
|
index ix_users_hash nonclustered ([hash] asc) with (fillfactor = 90),
|
||||||
|
index ix_users_nick nonclustered (nick asc) with (fillfactor = 90)
|
||||||
|
)
|
||||||
|
|
||||||
|
-- level 2.
|
||||||
|
if object_id(N'dbo.[Sessions]', N'U') is null create table dbo.[Sessions](
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
[user] integer not null,
|
||||||
|
date_last datetime not null constraint df_sessions_date_last default getdate(),
|
||||||
|
date_in datetime not null constraint df_sessions_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_sessions primary key clustered (id),
|
||||||
|
constraint fk_sessions_user foreign key([user]) references dbo.Users(id),
|
||||||
|
constraint ck_sessions_user check ([user] > 0),
|
||||||
|
index ix_sessions_user nonclustered ([user] asc) with (fillfactor = 90)
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Level 3.
|
||||||
|
if object_id(N'dbo.Logs', N'U') is null begin
|
||||||
|
create table dbo.Logs(
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
[procedure] integer not null,
|
||||||
|
[session] integer not null,
|
||||||
|
[message] integer not null,
|
||||||
|
error integer,
|
||||||
|
parameters text,
|
||||||
|
date_in datetime not null constraint df_logs_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_logs primary key clustered (id),
|
||||||
|
constraint fk_logs_procedure foreign key([procedure]) references dbo.[Procedures](id),
|
||||||
|
constraint fk_logs_session foreign key([session]) references dbo.[Sessions](id),
|
||||||
|
constraint fk_logs_message foreign key([message]) references dbo.[Messages](id),
|
||||||
|
constraint fk_logs_error foreign key(error) references dbo.Errors(id),
|
||||||
|
constraint ck_logs_procedure check ([procedure] > 0),
|
||||||
|
constraint ck_logs_session check ([session] > 0),
|
||||||
|
constraint ck_logs_message check ([message] > 0),
|
||||||
|
constraint ck_logs_error check (error is null or error > 0)
|
||||||
|
)
|
||||||
|
create nonclustered index ix_logs_procedure on dbo.Logs ([procedure] asc) include ([session], [message], error) with (fillfactor = 90)
|
||||||
|
create nonclustered index ix_logs_session on dbo.Logs ([session] asc) include ([procedure], [message], error) with (fillfactor = 90)
|
||||||
|
create nonclustered index ix_logs_error on dbo.Logs (error asc) include ([procedure], [session], [message]) with (fillfactor = 90)
|
||||||
|
create nonclustered index ix_logs_message on dbo.Logs ([message] asc) include ([procedure], [session], error) with (fillfactor = 90)
|
||||||
|
end
|
||||||
|
|
||||||
|
if object_id(N'dbo.Exceptions', N'U') is null begin
|
||||||
|
create table dbo.Exceptions(
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
[procedure] integer not null,
|
||||||
|
[session] integer not null,
|
||||||
|
[message] integer not null,
|
||||||
|
exception integer not null,
|
||||||
|
parameters text,
|
||||||
|
[status] varchar(16) collate database_default,
|
||||||
|
code integer,
|
||||||
|
date_in datetime not null constraint df_exceptions_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_exceptions primary key clustered (id),
|
||||||
|
constraint fk_exceptions_procedure foreign key([procedure]) references dbo.[Procedures](id),
|
||||||
|
constraint fk_exceptions_session foreign key([session]) references dbo.[Sessions](id),
|
||||||
|
constraint fk_exceptions_message foreign key([message]) references dbo.[Messages](id),
|
||||||
|
constraint fk_exceptions_exception foreign key([exception]) references dbo.[Messages](id),
|
||||||
|
constraint ck_exceptions_procedure check ([procedure] > 0),
|
||||||
|
constraint ck_exceptions_session check ([session] > 0),
|
||||||
|
constraint ck_exceptions_message check ([message] > 0),
|
||||||
|
constraint ck_exceptions_exception check ([exception] > 0)
|
||||||
|
)
|
||||||
|
create nonclustered index ix_exceptions_procedure on dbo.Exceptions ([procedure] asc) include ([session], [message], exception) with (fillfactor = 90)
|
||||||
|
create nonclustered index ix_exceptions_session on dbo.Exceptions ([session] asc) include ([procedure], [message], exception) with (fillfactor = 90)
|
||||||
|
create nonclustered index ix_exceptions_exception on dbo.Exceptions (exception asc) include ([procedure], [session], [message]) with (fillfactor = 90)
|
||||||
|
create nonclustered index ix_exceptions_message on dbo.Exceptions ([message] asc) include ([procedure], [session], exception) with (fillfactor = 90)
|
||||||
|
end
|
||||||
|
|
||||||
|
if object_id(N'dbo.Terminals', N'U') is null begin
|
||||||
|
create table dbo.Terminals(
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
[procedure] integer not null,
|
||||||
|
[session] integer not null,
|
||||||
|
[message] varchar(max) collate database_default,
|
||||||
|
date_in datetime not null constraint df_terminals_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_terminals_id primary key clustered (id),
|
||||||
|
constraint fk_terminals_procedure foreign key([procedure]) references dbo.[Procedures](id),
|
||||||
|
constraint fk_terminals_session foreign key([session]) references dbo.[Sessions](id),
|
||||||
|
constraint ck_terminals_procedure check ([procedure] > 0),
|
||||||
|
constraint ck_terminals_session check ([session] > 0)
|
||||||
|
)
|
||||||
|
create nonclustered index ix_terminals_procedure on dbo.Terminals ([procedure] asc) include ([session]) with (fillfactor = 90)
|
||||||
|
create nonclustered index ix_terminals_session on dbo.Terminals ([session] asc) include ([procedure]) with (fillfactor = 90)
|
||||||
|
end
|
||||||
|
|
||||||
|
if object_id(N'dbo.SessionsIps', N'U') is null begin
|
||||||
|
create table dbo.SessionsIps(
|
||||||
|
id integer not null identity(1, 1),
|
||||||
|
[session] integer not null,
|
||||||
|
[ip] integer not null,
|
||||||
|
date_in datetime not null constraint df_sessions_ips_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_sessions_ips_id primary key clustered (id),
|
||||||
|
constraint fk_sessions_ips_session foreign key([session]) references dbo.[Sessions](id),
|
||||||
|
constraint fk_sessions_ips_ip foreign key([ip]) references dbo.Ips(id),
|
||||||
|
constraint ck_sessions_ips_session check ([session] > 0),
|
||||||
|
constraint ck_sessions_ips_ip check ([ip] > 0)
|
||||||
|
)
|
||||||
|
create nonclustered index ix_sessions_ips_session on dbo.SessionsIps ([session] asc) include ([ip]) with (fillfactor = 90)
|
||||||
|
create nonclustered index ix_sessions_ips_ip on dbo.SessionsIps ([ip] asc) include ([session]) with (fillfactor = 90)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.common_tables_update', N'P') is not null drop procedure dbo.common_tables_update
|
||||||
|
go
|
||||||
|
create procedure dbo.common_tables_update as begin
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
execute dbo.common_tables_delete
|
||||||
|
go
|
||||||
|
execute dbo.common_tables_create
|
||||||
|
go
|
||||||
|
execute dbo.common_tables_update
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.sql_set', N'P') is not null drop procedure dbo.sql_set
|
||||||
|
go
|
||||||
|
create procedure dbo.sql_set
|
||||||
|
@database varchar(64),
|
||||||
|
@procedure varchar(64),
|
||||||
|
@session integer
|
||||||
|
as begin
|
||||||
|
|
||||||
|
declare @data binary(128) = (
|
||||||
|
cast(substring(isnull(@database, ''), 1, 62) as binary(62)) +
|
||||||
|
cast(substring(isnull(@procedure, ''), 1, 62) as binary(62)) +
|
||||||
|
cast(isnull(@session, 0) as binary(4))
|
||||||
|
)
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
set context_info @data
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.sql_get', N'P') is not null drop procedure dbo.sql_get
|
||||||
|
go
|
||||||
|
create procedure dbo.sql_get
|
||||||
|
@database varchar(64) output,
|
||||||
|
@procedure varchar(64) output,
|
||||||
|
@session integer output
|
||||||
|
as begin
|
||||||
|
|
||||||
|
declare @context binary(128) = context_info()
|
||||||
|
declare @null char(1) = char(0)
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
set @database = rtrim(replace(cast(substring(@context, 1, 62) as varchar(64)), @null, ''))
|
||||||
|
set @procedure = rtrim(replace(cast(substring(@context, 63, 62) as varchar(64)), @null, ''))
|
||||||
|
set @session = cast(substring(@context, 125, 4) as int)
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.procedure_get', N'P') is not null drop procedure dbo.procedure_get
|
||||||
|
go
|
||||||
|
create procedure dbo.procedure_get
|
||||||
|
@database varchar(64),
|
||||||
|
@procedure varchar(64),
|
||||||
|
@id integer output
|
||||||
|
as begin
|
||||||
|
|
||||||
|
declare @database_id integer = (select top 1 id from dbo.[Databases] where
|
||||||
|
date_out is null and
|
||||||
|
[name] = @database
|
||||||
|
)
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
if @database_id is null begin
|
||||||
|
insert into dbo.[Databases]([name]) values(@database)
|
||||||
|
set @database_id = scope_identity()
|
||||||
|
end
|
||||||
|
|
||||||
|
set @id = (select top 1 id from dbo.[Procedures] where
|
||||||
|
date_out is null and
|
||||||
|
[database] = @database_id and
|
||||||
|
[name] = @procedure
|
||||||
|
)
|
||||||
|
|
||||||
|
if @id is null begin
|
||||||
|
insert into dbo.[Procedures]([database], [name]) values(@database_id, @procedure)
|
||||||
|
set @id = scope_identity()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.users_trigger_update', N'TR') is not null drop trigger dbo.users_trigger_update
|
||||||
|
go
|
||||||
|
create trigger dbo.users_trigger_update on dbo.Users after insert, update as begin
|
||||||
|
|
||||||
|
declare @session integer
|
||||||
|
declare @database varchar(64)
|
||||||
|
declare @procedure varchar(64)
|
||||||
|
declare @procedure_id integer
|
||||||
|
declare @id integer
|
||||||
|
declare @hash integer
|
||||||
|
declare @nick varchar(32)
|
||||||
|
declare @password binary(64)
|
||||||
|
declare @accessible bit
|
||||||
|
declare @date_in datetime
|
||||||
|
declare @date_out datetime
|
||||||
|
declare users_cursor cursor local for (
|
||||||
|
select id, [hash], nick, [password], accessible, date_in, date_out from inserted
|
||||||
|
)
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
execute dbo.sql_get @database output, @procedure output, @session output
|
||||||
|
execute dbo.procedure_get @database, @procedure, @procedure_id output
|
||||||
|
|
||||||
|
open users_cursor
|
||||||
|
while 1 = 1 begin
|
||||||
|
fetch next from users_cursor into @id, @hash, @nick, @password, @accessible, @date_in, @date_out
|
||||||
|
if @@fetch_status != 0
|
||||||
|
break
|
||||||
|
insert into dbo.UsersData(entity, [procedure], [session], [hash], nick, [password], accessible, date_in, date_out) values
|
||||||
|
(@id, @procedure_id, @session, @hash, @nick, @password, @accessible, @date_in, @date_out)
|
||||||
|
end
|
||||||
|
close users_cursor
|
||||||
|
deallocate users_cursor
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.hash_create_name', N'FN') is not null drop function dbo.hash_create_name
|
||||||
|
go
|
||||||
|
create function dbo.hash_create_name(
|
||||||
|
@method varchar(16)
|
||||||
|
) returns varchar(16) as begin
|
||||||
|
return (case
|
||||||
|
when @method = 'md5' then 'md5'
|
||||||
|
when @method = 'sha1' then 'sha1'
|
||||||
|
when @method in (
|
||||||
|
'sha2_256', 'sha2-256', 'sha-256', 'sha256', 'sha_256'
|
||||||
|
) then 'sha2_256'
|
||||||
|
when @method in (
|
||||||
|
'sha2_512', 'sha2-512', 'sha-512', 'sha512', 'sha_512'
|
||||||
|
) then 'sha2_512'
|
||||||
|
else null end)
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.hash_create', N'FN') is not null drop function dbo.hash_create
|
||||||
|
go
|
||||||
|
create function dbo.hash_create(
|
||||||
|
@method varchar(16),
|
||||||
|
@input varchar(max)
|
||||||
|
) returns binary(64) as begin
|
||||||
|
|
||||||
|
set @method = dbo.hash_create_name(@method)
|
||||||
|
|
||||||
|
return (case
|
||||||
|
when @method in (
|
||||||
|
'md5', 'sha1', 'sha2_256', 'sha2_512'
|
||||||
|
) then hashbytes(upper(@method), @input)
|
||||||
|
else cast(@input as binary(64)) end)
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.message_get', N'P') is not null drop procedure dbo.message_get
|
||||||
|
go
|
||||||
|
create procedure dbo.message_get
|
||||||
|
@message varchar(max),
|
||||||
|
@id integer output
|
||||||
|
as begin
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
set @id = (select top 1 id from dbo.[Messages] where date_out is null and [message] = @message)
|
||||||
|
|
||||||
|
if @id is null begin
|
||||||
|
insert into dbo.[Messages]([message]) values(@message)
|
||||||
|
set @id = scope_identity()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.error_get', N'P') is not null drop procedure dbo.error_get
|
||||||
|
go
|
||||||
|
create procedure dbo.error_get
|
||||||
|
@error varchar(512),
|
||||||
|
@id integer output
|
||||||
|
as begin
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
set @id = (select top 1 id from dbo.Errors where date_out is null and [error] = @error)
|
||||||
|
|
||||||
|
if @id is null begin
|
||||||
|
insert into dbo.Errors([error]) values(@error)
|
||||||
|
set @id = scope_identity()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.hash_get', N'P') is not null drop procedure dbo.hash_get
|
||||||
|
go
|
||||||
|
create procedure dbo.hash_get
|
||||||
|
@name varchar(16),
|
||||||
|
@id integer output
|
||||||
|
as begin
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
set @id = (select top 1 id from dbo.Hashes where date_out is null and [name] = @name)
|
||||||
|
|
||||||
|
if @id is null begin
|
||||||
|
insert into dbo.Hashes([name]) values(@name)
|
||||||
|
set @id = scope_identity()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.logs_set', N'P') is not null drop procedure dbo.logs_set
|
||||||
|
go
|
||||||
|
create procedure dbo.logs_set
|
||||||
|
@session integer,
|
||||||
|
@database varchar(64),
|
||||||
|
@procedure varchar(64),
|
||||||
|
@message varchar(max),
|
||||||
|
@parameters varchar(max),
|
||||||
|
@error varchar(512) = '',
|
||||||
|
@level tinyint = 0
|
||||||
|
as begin
|
||||||
|
|
||||||
|
declare @procedure_id integer
|
||||||
|
declare @error_id integer
|
||||||
|
declare @message_id integer
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
execute dbo.procedure_get @database, @procedure, @procedure_id output
|
||||||
|
execute dbo.message_get @message, @message_id output
|
||||||
|
execute dbo.error_get @error, @error_id output
|
||||||
|
|
||||||
|
insert into dbo.Logs([procedure], [session], [message], parameters, [error]) values
|
||||||
|
(@procedure_id, @session, @message_id, @parameters, @error_id)
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.logs_set', N'P') is not null drop procedure dbo.logs_set
|
||||||
|
go
|
||||||
|
create procedure dbo.logs_set
|
||||||
|
@session integer,
|
||||||
|
@database varchar(64),
|
||||||
|
@procedure varchar(64),
|
||||||
|
@message varchar(max),
|
||||||
|
@parameters varchar(max)
|
||||||
|
as begin
|
||||||
|
|
||||||
|
declare @exception varchar(max) = error_message()
|
||||||
|
declare @status varchar(16) = error_state()
|
||||||
|
declare @code integer = error_number()
|
||||||
|
declare @exception_id integer
|
||||||
|
declare @procedure_id integer
|
||||||
|
declare @message_id integer
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
execute dbo.message_get @exception, @exception_id output
|
||||||
|
execute dbo.procedure_get @database, @procedure, @procedure_id output
|
||||||
|
execute dbo.message_get @message, @message_id output
|
||||||
|
|
||||||
|
insert into dbo.Exceptions([procedure], [session], [message], exception, [parameters], [status], code) values
|
||||||
|
(@procedure_id, @session, @message_id, @exception_id, @parameters, @status, @code)
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.common_tables_fill', N'P') is not null drop procedure dbo.common_tables_fill
|
||||||
|
go
|
||||||
|
create procedure dbo.common_tables_fill as begin
|
||||||
|
|
||||||
|
declare @database varchar(64) = 'AnP'
|
||||||
|
declare @procedure varchar(64) = 'common_tables_fill'
|
||||||
|
declare @procedure_id integer
|
||||||
|
declare @local_ip varchar(71) = '::1'
|
||||||
|
declare @main_user varchar(32) = 'machine'
|
||||||
|
declare @user varchar(32)
|
||||||
|
declare @session_id integer = (
|
||||||
|
select top 1 id from dbo.[Sessions] where date_out is null and [user] = (
|
||||||
|
select top 1 id from dbo.Users where date_out is null and nick = @main_user
|
||||||
|
)
|
||||||
|
)
|
||||||
|
declare @has_session bit = case when @session_id is null then 0 else 1 end
|
||||||
|
declare @ip_id integer = (
|
||||||
|
select top 1 id from dbo.Ips where date_out is null and ip = @local_ip
|
||||||
|
)
|
||||||
|
declare @hash_id integer
|
||||||
|
declare @hash varchar(16)
|
||||||
|
declare users_cursor cursor local for (
|
||||||
|
select @main_user as [name] union all
|
||||||
|
select 'guest'
|
||||||
|
)
|
||||||
|
declare hashes_cursor cursor local for (
|
||||||
|
select 'null' as [name] union all
|
||||||
|
select 'md5' union all
|
||||||
|
select 'sha1' union all
|
||||||
|
select 'sha2_256' union all
|
||||||
|
select 'sha2_512'
|
||||||
|
)
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
if @has_session = 0 begin
|
||||||
|
if (select top 1 0 from sys.indexes where name = N'ix_sessions_user') is not null
|
||||||
|
drop index ix_sessions_user on dbo.[Sessions]
|
||||||
|
if object_id(N'dbo.fk_sessions_user', N'F') is not null
|
||||||
|
alter table dbo.[Sessions] drop constraint fk_sessions_user
|
||||||
|
alter table dbo.[Sessions] alter column [user] integer
|
||||||
|
insert into dbo.[Sessions] default values
|
||||||
|
set @session_id = scope_identity()
|
||||||
|
end
|
||||||
|
|
||||||
|
execute dbo.sql_set @database, @procedure, @session_id
|
||||||
|
execute dbo.procedure_get @database, @procedure, @procedure_id output
|
||||||
|
|
||||||
|
open hashes_cursor
|
||||||
|
while 1 = 1 begin
|
||||||
|
fetch next from hashes_cursor into @hash
|
||||||
|
if @@fetch_status != 0
|
||||||
|
break
|
||||||
|
if (select top 1 0 from dbo.Hashes where date_out is null and [name] = @hash) is null
|
||||||
|
insert into dbo.Hashes([name]) values(@hash)
|
||||||
|
end
|
||||||
|
close hashes_cursor
|
||||||
|
deallocate hashes_cursor
|
||||||
|
|
||||||
|
execute dbo.hash_get 'null', @hash_id output
|
||||||
|
|
||||||
|
open users_cursor
|
||||||
|
while 1 = 1 begin
|
||||||
|
fetch next from users_cursor into @user
|
||||||
|
if @@fetch_status != 0
|
||||||
|
break
|
||||||
|
if (select top 1 0 from dbo.Users where date_out is null and nick = @user) is null
|
||||||
|
insert into dbo.Users([hash], nick) values
|
||||||
|
(@hash_id, @user)
|
||||||
|
end
|
||||||
|
close users_cursor
|
||||||
|
deallocate users_cursor
|
||||||
|
|
||||||
|
if @has_session = 0 begin
|
||||||
|
update dbo.[Sessions] set [user] = (
|
||||||
|
select top 1 id from dbo.Users where date_out is null and nick = @main_user
|
||||||
|
) where id = @session_id
|
||||||
|
alter table dbo.[Sessions] alter column [user] integer not null
|
||||||
|
alter table dbo.[Sessions] add constraint fk_sessions_user foreign key([user]) references dbo.Users(id)
|
||||||
|
create nonclustered index ix_sessions_user on dbo.[Sessions]([user] asc) with (fillfactor = 90)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @ip_id is null begin
|
||||||
|
insert into dbo.Ips([ip]) values(@local_ip)
|
||||||
|
set @ip_id = scope_identity()
|
||||||
|
end
|
||||||
|
if (select top 1 0 from dbo.SessionsIps where
|
||||||
|
date_out is null and
|
||||||
|
[session] = @session_id and
|
||||||
|
[ip] = @ip_id
|
||||||
|
) is null
|
||||||
|
insert into dbo.SessionsIps([session], [ip]) values(@session_id, @ip_id)
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
execute dbo.common_tables_fill
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.where_set', N'FN') is not null drop function dbo.where_set
|
||||||
|
go
|
||||||
|
create function dbo.where_set(
|
||||||
|
@old_where varchar(max),
|
||||||
|
@new_where varchar(max)
|
||||||
|
) returns varchar(max) as begin
|
||||||
|
|
||||||
|
set @new_where = ltrim(rtrim(isnull(@new_where, '')))
|
||||||
|
set @old_where = ltrim(rtrim(isnull(@old_where, '')))
|
||||||
|
|
||||||
|
return (case
|
||||||
|
when @new_where = '' then @old_where
|
||||||
|
when @old_where = '' then @new_where
|
||||||
|
else '(' + @old_where + ') and (' + @new_where + ')' end)
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.tables_list', N'P') is not null drop procedure dbo.tables_list
|
||||||
|
go
|
||||||
|
create procedure dbo.tables_list
|
||||||
|
@view varchar(max),
|
||||||
|
@page integer,
|
||||||
|
@items_per_page integer,
|
||||||
|
@where varchar(max),
|
||||||
|
@order_by varchar(max),
|
||||||
|
@has_errors bit,
|
||||||
|
@pages integer output,
|
||||||
|
@items integer output,
|
||||||
|
@results integer output
|
||||||
|
as begin
|
||||||
|
|
||||||
|
declare @where_string varchar(max) = (case
|
||||||
|
when @has_errors = 1 then ' where ' + dbo.where_set('0 = 1', @where)
|
||||||
|
when ltrim(rtrim(isnull(@where, ''))) = '' then ''
|
||||||
|
else ' where ' + @where end)
|
||||||
|
declare @query varchar(max) = N'select top 1 @subitems = count(1) from ' + @view + @where_string
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
execute sp_executesql @query, N'@subitems integer output', @subitems = @items output
|
||||||
|
|
||||||
|
set @pages = ceiling(@items / cast(@items_per_page as float))
|
||||||
|
set @query = (
|
||||||
|
N'select * from ' + @view + @where_string +
|
||||||
|
(case when ltrim(rtrim(isnull(@order_by, ''))) = '' then '' else N' order by ' + @order_by end) +
|
||||||
|
N' offset ' + cast((((case
|
||||||
|
when @page < 1 then 1
|
||||||
|
when @page > @pages then @pages
|
||||||
|
else @page end) - 1) * @items_per_page) as varchar) + N' rows fetch next ' + cast(@items_per_page as varchar) + N' rows only'
|
||||||
|
)
|
||||||
|
|
||||||
|
execute sp_executesql @query
|
||||||
|
set @results = @@rowcount
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
345
SQLServer/AnP.1.11.groups.server.sql
Normal file
345
SQLServer/AnP.1.11.groups.server.sql
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
use AnP
|
||||||
|
|
||||||
|
if object_id(N'dbo.groups_tables_delete', N'P') is not null drop procedure dbo.groups_tables_delete
|
||||||
|
go
|
||||||
|
create procedure dbo.groups_tables_delete as begin
|
||||||
|
|
||||||
|
set nocount on;
|
||||||
|
|
||||||
|
-- Level 3.
|
||||||
|
if object_id(N'dbo.GroupsIps', N'U') is not null drop table dbo.GroupsIps
|
||||||
|
if object_id(N'dbo.GroupsUsers', N'U') is not null drop table dbo.GroupsUsers
|
||||||
|
|
||||||
|
-- Level 1.
|
||||||
|
if object_id(N'dbo.Groups', N'U') is not null drop table dbo.Groups
|
||||||
|
|
||||||
|
-- Level 0.
|
||||||
|
if object_id(N'dbo.GroupsTypes', N'U') is not null drop table dbo.GroupsTypes
|
||||||
|
|
||||||
|
-- Level historical.
|
||||||
|
if object_id(N'dbo.GroupsIpsData', N'U') is not null drop table dbo.GroupsIpsData
|
||||||
|
if object_id(N'dbo.GroupsUsersData', N'U') is not null drop table dbo.GroupsUsersData
|
||||||
|
if object_id(N'dbo.GroupsData', N'U') is not null drop table dbo.GroupsData
|
||||||
|
if object_id(N'dbo.GroupsTypesData', N'U') is not null drop table dbo.GroupsTypesData
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.groups_tables_create', N'P') is not null drop procedure dbo.groups_tables_create
|
||||||
|
go
|
||||||
|
create procedure dbo.groups_tables_create as begin
|
||||||
|
|
||||||
|
set nocount on;
|
||||||
|
|
||||||
|
-- Level historical.
|
||||||
|
if object_id(N'dbo.GroupsTypesData', N'U') is null create table dbo.GroupsTypesData(
|
||||||
|
id integer not null identity(1,1),
|
||||||
|
entity integer not null,
|
||||||
|
[name] varchar(32) not null,
|
||||||
|
[description] varchar(256),
|
||||||
|
date_in datetime not null,
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_groups_types primary key clustered(id)
|
||||||
|
)
|
||||||
|
|
||||||
|
if object_id(N'dbo.GroupsData', N'U') is null create table dbo.GroupsData(
|
||||||
|
id integer not null identity(1,1),
|
||||||
|
entity integer not null,
|
||||||
|
[procedure] integer not null,
|
||||||
|
[session] integer not null,
|
||||||
|
[type] integer not null,
|
||||||
|
[name] varchar(32) not null,
|
||||||
|
[description] varchar(256),
|
||||||
|
date_in datetime not null,
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_groups_data primary key clustered (id)
|
||||||
|
)
|
||||||
|
|
||||||
|
if object_id(N'dbo.GroupsIpsData', N'U') is null create table dbo.GroupsIpsData(
|
||||||
|
id integer not null identity(1,1),
|
||||||
|
entity integer not null,
|
||||||
|
[procedure] integer not null,
|
||||||
|
[session] integer not null,
|
||||||
|
[group] integer not null,
|
||||||
|
[ip] integer not null,
|
||||||
|
belongs bit not null,
|
||||||
|
date_in datetime not null,
|
||||||
|
constraint pk_groups_ips_data primary key clustered (id)
|
||||||
|
)
|
||||||
|
|
||||||
|
if object_id(N'dbo.GroupsUsersData', N'U') is null create table dbo.GroupsUsersData(
|
||||||
|
id integer not null identity(1,1),
|
||||||
|
entity integer not null,
|
||||||
|
[procedure] integer not null,
|
||||||
|
[session] integer not null,
|
||||||
|
[group] integer not null,
|
||||||
|
[user] integer not null,
|
||||||
|
belongs bit not null,
|
||||||
|
date_in datetime not null,
|
||||||
|
constraint pk_groups_users_data primary key clustered (id)
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Level 0.
|
||||||
|
if object_id(N'dbo.GroupsTypes', N'U') is null create table dbo.GroupsTypes(
|
||||||
|
id integer not null identity(1,1),
|
||||||
|
[name] varchar(32) not null,
|
||||||
|
[description] varchar(256),
|
||||||
|
date_in datetime not null constraint df_groups_types_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_groups_types primary key clustered (id),
|
||||||
|
constraint uk_groups_types_name unique nonclustered ([name] asc) with (fillfactor = 90),
|
||||||
|
constraint ck_groups_types_name check ([name] != '')
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Level 1.
|
||||||
|
if object_id(N'dbo.Groups', N'U') is null begin
|
||||||
|
create table dbo.Groups(
|
||||||
|
id integer not null identity(1,1),
|
||||||
|
[type] integer not null,
|
||||||
|
[name] varchar(32) not null,
|
||||||
|
[description] varchar(256),
|
||||||
|
date_in datetime not null constraint df_groups_date_in default getdate(),
|
||||||
|
date_out datetime,
|
||||||
|
constraint pk_groups primary key clustered (id),
|
||||||
|
constraint fk_groups_type foreign key ([type]) references dbo.GroupsTypes(id),
|
||||||
|
constraint uk_groups_type_name unique([name], [type]),
|
||||||
|
constraint ck_groups_type check ([type] > 0),
|
||||||
|
constraint ck_groups_name check ([name] != '')
|
||||||
|
)
|
||||||
|
create nonclustered index ix_groups_type on dbo.Groups([type] asc) include ([name]) with (fillfactor = 90)
|
||||||
|
create nonclustered index ix_groups_name on dbo.Groups([name] asc) include ([type]) with (fillfactor = 90)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Level 2.
|
||||||
|
if object_id(N'dbo.GroupsIps', N'U') is null begin
|
||||||
|
create table dbo.GroupsIps(
|
||||||
|
id integer not null identity(1,1),
|
||||||
|
[group] integer not null,
|
||||||
|
[ip] integer not null,
|
||||||
|
belongs bit not null constraint df_groups_ips_belongs default 1,
|
||||||
|
date_in datetime not null constraint df_groups_ips_date_in default getdate(),
|
||||||
|
constraint pk_groups_ips primary key clustered (id),
|
||||||
|
constraint fk_groups_ips_group foreign key ([group]) references dbo.Groups(id),
|
||||||
|
constraint fk_groups_ips_ip foreign key ([ip]) references dbo.Ips(id),
|
||||||
|
constraint uk_groups_ips_group_ip unique([group], [ip]),
|
||||||
|
constraint ck_groups_ips_group check ([group] > 0),
|
||||||
|
constraint ck_groups_ips_ip check ([ip] > 0)
|
||||||
|
)
|
||||||
|
create nonclustered index ix_groups_ips_group on dbo.GroupsIps([group] asc) include ([ip], belongs) with (fillfactor = 90)
|
||||||
|
create nonclustered index ix_groups_ips_ip on dbo.GroupsIps([ip] asc) include ([group], belongs) with (fillfactor = 90)
|
||||||
|
end
|
||||||
|
|
||||||
|
if object_id(N'dbo.GroupsUsers', N'U') is null begin
|
||||||
|
create table dbo.GroupsUsers(
|
||||||
|
id integer not null identity(1,1),
|
||||||
|
[group] integer not null,
|
||||||
|
[user] integer not null,
|
||||||
|
belongs bit not null constraint df_groups_users_belongs default 1,
|
||||||
|
date_in datetime not null constraint df_groups_users_date_in default getdate(),
|
||||||
|
constraint pk_groups_users primary key clustered (id),
|
||||||
|
constraint fk_groups_users_group foreign key ([group]) references dbo.Groups(id),
|
||||||
|
constraint fk_groups_users_user foreign key ([user]) references dbo.Users(id),
|
||||||
|
constraint uk_groups_users_group_user unique([group], [user]),
|
||||||
|
constraint ck_groups_users_group check ([group] > 0),
|
||||||
|
constraint ck_groups_users_user check ([user] > 0)
|
||||||
|
)
|
||||||
|
create nonclustered index ix_groups_users_group on dbo.GroupsUsers([group] asc) include ([user], belongs) with (fillfactor = 90)
|
||||||
|
create nonclustered index ix_groups_users_user on dbo.GroupsUsers([user] asc) include ([group], belongs) with (fillfactor = 90)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.groups_tables_update', N'P') is not null drop procedure dbo.groups_tables_update
|
||||||
|
go
|
||||||
|
create procedure dbo.groups_tables_update as begin
|
||||||
|
|
||||||
|
set nocount on;
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
execute dbo.groups_tables_delete
|
||||||
|
go
|
||||||
|
execute dbo.groups_tables_create
|
||||||
|
go
|
||||||
|
execute dbo.groups_tables_update
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.groups_trigger_update', N'TR') is not null drop trigger dbo.groups_trigger_update
|
||||||
|
go
|
||||||
|
create trigger dbo.groups_trigger_update on dbo.Groups after insert, update as begin
|
||||||
|
|
||||||
|
declare @database varchar(64)
|
||||||
|
declare @procedure varchar(64)
|
||||||
|
declare @procedure_id integer
|
||||||
|
declare @session integer
|
||||||
|
declare @id integer
|
||||||
|
declare @name varchar(32)
|
||||||
|
declare @description varchar(256)
|
||||||
|
declare @date_in datetime
|
||||||
|
declare @date_out datetime
|
||||||
|
declare groups_cursor cursor local for (
|
||||||
|
select id, [name], [description], date_in, date_out from inserted
|
||||||
|
)
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
execute dbo.sql_get @database output, @procedure output, @session output
|
||||||
|
execute dbo.procedure_get @database, @procedure, @procedure_id output
|
||||||
|
|
||||||
|
open groups_cursor
|
||||||
|
while 1 = 1 begin
|
||||||
|
fetch next from groups_cursor into @id, @procedure, @session, @name, @description, @date_in, @date_out
|
||||||
|
if @@fetch_status != 0
|
||||||
|
break
|
||||||
|
insert into dbo.GroupsData(entity, [procedure], [session], [name], [description], date_in, date_out) values
|
||||||
|
(@id, @procedure, @session, @name, @description, @date_in, @date_out)
|
||||||
|
update dbo.Groups set data_id = scope_identity() where id = @id
|
||||||
|
end
|
||||||
|
close groups_cursor
|
||||||
|
deallocate groups_cursor
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.groups_ips_trigger_update', N'TR') is not null drop trigger dbo.groups_ips_trigger_update
|
||||||
|
go
|
||||||
|
create trigger dbo.groups_ips_trigger_update on dbo.GroupsIps after insert, update as begin
|
||||||
|
|
||||||
|
declare @database varchar(64)
|
||||||
|
declare @procedure varchar(64)
|
||||||
|
declare @procedure_id integer
|
||||||
|
declare @session integer
|
||||||
|
declare @id integer
|
||||||
|
declare @group integer
|
||||||
|
declare @ip integer
|
||||||
|
declare @belongs bit
|
||||||
|
declare @date_in datetime
|
||||||
|
declare groups_ips_cursor cursor local for (
|
||||||
|
select id, [group], [ip], belongs, date_in from inserted
|
||||||
|
)
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
execute dbo.sql_get @database output, @procedure output, @session output
|
||||||
|
execute dbo.procedure_get @database, @procedure, @procedure_id output
|
||||||
|
|
||||||
|
open groups_ips_cursor
|
||||||
|
while 1 = 1 begin
|
||||||
|
fetch next from groups_ips_cursor into @id, @group, @ip, @belongs, @date_in
|
||||||
|
if @@fetch_status != 0
|
||||||
|
break
|
||||||
|
insert into dbo.GroupsIpsData(entity, [procedure], [session], [group], [ip], belongs, date_in) values
|
||||||
|
(@id, @procedure_id, @session_id, @group, @ip, @belongs, @date_in)
|
||||||
|
end
|
||||||
|
close groups_ips_cursor
|
||||||
|
deallocate groups_ips_cursor
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.groups_users_trigger_update', N'TR') is not null drop trigger dbo.groups_users_trigger_update
|
||||||
|
go
|
||||||
|
create trigger dbo.groups_users_trigger_update on dbo.GroupsUsers after insert, update as begin
|
||||||
|
|
||||||
|
declare @database varchar(64)
|
||||||
|
declare @procedure varchar(64)
|
||||||
|
declare @procedure_id integer
|
||||||
|
declare @session integer
|
||||||
|
declare @id integer
|
||||||
|
declare @group integer
|
||||||
|
declare @user integer
|
||||||
|
declare @belongs bit
|
||||||
|
declare @date_in datetime
|
||||||
|
declare groups_users_cursor cursor local for (
|
||||||
|
select id, [group], [user], belongs, date_in from inserted
|
||||||
|
)
|
||||||
|
|
||||||
|
set nocount on
|
||||||
|
|
||||||
|
execute dbo.sql_get @database output, @procedure output, @session output
|
||||||
|
execute dbo.procedure_get @database, @procedure, @procedure_id output
|
||||||
|
|
||||||
|
open groups_users_cursor
|
||||||
|
while 1 = 1 begin
|
||||||
|
fetch next from groups_users_cursor into @id, @procedure, @session, @group, @user, @belongs, @date_in
|
||||||
|
if @@fetch_status != 0
|
||||||
|
break
|
||||||
|
insert into dbo.GroupsUsersData(entity, [procedure], [session], [group], [user], belongs, date_in) values
|
||||||
|
(@id, @procedure, @session, @group, @user, @belongs, @date_in)
|
||||||
|
update dbo.GroupsUsers set data_id = scope_identity() where id = @id
|
||||||
|
end
|
||||||
|
close groups_users_cursor
|
||||||
|
deallocate groups_users_cursor
|
||||||
|
|
||||||
|
end
|
||||||
|
go
|
||||||
|
|
||||||
|
execute dbo.groups_tables_fill
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.IpsView', N'V') is not null drop view dbo.IpsView
|
||||||
|
go
|
||||||
|
create view dbo.IpsView as select
|
||||||
|
ips.id as id,
|
||||||
|
ips.[ip] as [ip],
|
||||||
|
ips.date_in as date_in
|
||||||
|
from dbo.Ips ips
|
||||||
|
where ips.date_out is null
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.UsersView', N'V') is not null drop view dbo.UsersView
|
||||||
|
go
|
||||||
|
create view dbo.UsersView as select
|
||||||
|
users.id as id,
|
||||||
|
users.nick as nick,
|
||||||
|
users.date_in as date_in
|
||||||
|
from dbo.Users users
|
||||||
|
where users.date_out is null
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.GroupsView', N'V') is not null drop view dbo.GroupsView
|
||||||
|
go
|
||||||
|
create view dbo.GroupsView as select
|
||||||
|
groups.id as id,
|
||||||
|
groups.name as [name],
|
||||||
|
groups.description as [description],
|
||||||
|
groups.date_in as date_in
|
||||||
|
from dbo.Groups groups
|
||||||
|
where groups.date_out is null
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.GroupsIpsView', N'V') is not null drop view dbo.GroupsIpsView
|
||||||
|
go
|
||||||
|
create view dbo.GroupsIpsView as select
|
||||||
|
groups_ips.id as id,
|
||||||
|
groups.id as group_id,
|
||||||
|
groups.[name] as [group],
|
||||||
|
ips.id as ip_id,
|
||||||
|
ips.[ip] as [ip],
|
||||||
|
isnull(groups_ips.belongs, 0) as belongs,
|
||||||
|
groups_ips.date_in as date_in
|
||||||
|
from dbo.GroupsViews groups
|
||||||
|
join dbo.IpsViews ips on 1 = 1
|
||||||
|
left join dbo.GroupsIps groups_ips on
|
||||||
|
groups_ips.[group] = groups.id
|
||||||
|
groups_ips.[ip] = ips.id
|
||||||
|
go
|
||||||
|
|
||||||
|
if object_id(N'dbo.GroupsUsersView', N'V') is not null drop view dbo.GroupsUsersView
|
||||||
|
go
|
||||||
|
create view dbo.GroupsUsersView as select
|
||||||
|
groups_users.id as id,
|
||||||
|
groups.id as group_id,
|
||||||
|
groups.[name] as [group],
|
||||||
|
users.id as user_id,
|
||||||
|
users.nick as [user],
|
||||||
|
isnull(groups_users.belongs, 0) as belongs,
|
||||||
|
groups_users.date_in as date_in
|
||||||
|
from dbo.GroupsViews groups
|
||||||
|
join dbo.UsersViews users on 1 = 1
|
||||||
|
left join dbo.GroupsUsers groups_users on
|
||||||
|
groups_users.[group] = groups.id
|
||||||
|
groups_users.[user] = users.id
|
||||||
|
go
|
||||||
4
SQLServer/Dockerfile
Normal file
4
SQLServer/Dockerfile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
from mcr.microsoft.com/mssql/server:2022-latest
|
||||||
|
expose 1433/tcp
|
||||||
|
user root
|
||||||
|
env ACCEPT_EULA=Y
|
||||||
4
SQLServer/docker.rebuild.sh
Executable file
4
SQLServer/docker.rebuild.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
directory=`dirname $(readlink -f "$0")`
|
||||||
|
[ "$(docker images -q anp:sql-server 2>/dev/null)" ] && docker image remove anp:sql-server --force
|
||||||
|
docker build -f $directory/Dockerfile -t anp:sql-server $directory --no-cache
|
||||||
6
Tools/reinstall.dockers.sh
Executable file
6
Tools/reinstall.dockers.sh
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
directory=`dirname $(readlink -f "$0")`
|
||||||
|
for file in $(find $directory/.. -type f -name "docker.rebuild.sh"); do
|
||||||
|
chmod +x $file
|
||||||
|
$file
|
||||||
|
done
|
||||||
4
Tools/run.cs.server.sh
Executable file
4
Tools/run.cs.server.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
cd `dirname $(readlink -f "$0")`/..
|
||||||
|
docker exec -it anp-dotnet dotnet run --project /workspace/CSharp/AnP.csproj -f net10.0
|
||||||
|
cd Tools
|
||||||
3
Tools/run.server.sh
Executable file
3
Tools/run.server.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
directory=`dirname $(readlink -f "$0")`
|
||||||
|
python3 "$directory/../Python/server.py"
|
||||||
3
Tools/sass.sh
Executable file
3
Tools/sass.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
directory=`dirname $(readlink -f "$0")`
|
||||||
|
sass $directory/../Public/scss/AnP.scss ../Public/scss/AnP.css;
|
||||||
41
docker-compose.yml
Normal file
41
docker-compose.yml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
services:
|
||||||
|
|
||||||
|
dotnet:
|
||||||
|
image: anp:dotnet
|
||||||
|
container_name: anp-dotnet
|
||||||
|
volumes:
|
||||||
|
- ./DotNET/scripts:/scripts
|
||||||
|
- ./CSharp:/workspace/CSharp
|
||||||
|
- ./VB:/workspace/VB
|
||||||
|
- ./FSharp:/workspace/FSharp
|
||||||
|
- ./CPP:/workspace/CPP
|
||||||
|
- ./JSON:/workspace/JSON
|
||||||
|
- ./Public:/workspace/Public
|
||||||
|
ports:
|
||||||
|
- 28080:80/tcp
|
||||||
|
entrypoint: /scripts/entrypoint.sh
|
||||||
|
networks:
|
||||||
|
anp-network:
|
||||||
|
ipv4_address: 172.20.11.223
|
||||||
|
|
||||||
|
anp-sql-server:
|
||||||
|
image: anp:sql-server
|
||||||
|
container_name: anp-sql-server
|
||||||
|
environment:
|
||||||
|
- MSSQL_SA_PASSWORD=Abc123..
|
||||||
|
volumes:
|
||||||
|
- ./SQLServer/data:/var/opt/mssql
|
||||||
|
- ./SQLServer/temporary:/temporary
|
||||||
|
- ./SQLServer/scripts:/scripts
|
||||||
|
ports:
|
||||||
|
- 21433:1433/tcp
|
||||||
|
networks:
|
||||||
|
anp-network:
|
||||||
|
ipv4_address: 172.20.11.222
|
||||||
|
|
||||||
|
networks:
|
||||||
|
anp-network:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: 172.20.11.0/24
|
||||||
Loading…
Reference in New Issue
Block a user