#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
|
||||
|
||||
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