Compare commits
42 Commits
885b937b0b
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
ea87c060bd
|
|||
|
1adbd76f58
|
|||
|
e506ab5c43
|
|||
|
9a38dd30fd
|
|||
| 23a3490378 | |||
| dddedfa45c | |||
| 86d7001e79 | |||
| 7417e8c3eb | |||
| 3ea1f2b603 | |||
| 79961edda8 | |||
| de5e729466 | |||
| 92e07790cc | |||
| 6044e5f7e9 | |||
| f87466beb4 | |||
| 3f9a11b17d | |||
| f95d8d3420 | |||
| e439183645 | |||
| 785ab935c6 | |||
| f45f846b37 | |||
| 46046d589e | |||
| 802acad570 | |||
| dd4d3397eb | |||
| 3d92d1b72d | |||
| c550967ecc | |||
| 38bba2aab2 | |||
| 104a1cff41 | |||
| 95692a6a1f | |||
| 13eb3c0033 | |||
| f6d1543108 | |||
| a4721c9739 | |||
| 46bbc34956 | |||
| 047ccfa754 | |||
| b0d9a67c1c | |||
| 3eb043b24c | |||
| 4cd476764d | |||
| 90b4662dda | |||
| e7edc79ebc | |||
| aabeed0aa5 | |||
| e79ec360ea | |||
| 31c1d2804d | |||
| ea4c8b61e0 | |||
| b40e394bcf |
@@ -12,7 +12,7 @@ indent_style = space
|
|||||||
tab_width = 4
|
tab_width = 4
|
||||||
|
|
||||||
# Предпочтения для новых строк
|
# Предпочтения для новых строк
|
||||||
end_of_line = crlf
|
end_of_line = unset
|
||||||
insert_final_newline = false
|
insert_final_newline = false
|
||||||
|
|
||||||
#### Действия кода .NET ####
|
#### Действия кода .NET ####
|
||||||
@@ -244,7 +244,7 @@ dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
|||||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||||
tab_width = 4
|
tab_width = 4
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
end_of_line = crlf
|
end_of_line = unset
|
||||||
dotnet_style_coalesce_expression = true:suggestion
|
dotnet_style_coalesce_expression = true:suggestion
|
||||||
dotnet_style_null_propagation = true:suggestion
|
dotnet_style_null_propagation = true:suggestion
|
||||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
name: Build and Deploy Docker Container
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
[master, 'release/*']
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-and-deploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
|
|
||||||
- name: Build and push Docker image
|
|
||||||
run: |
|
|
||||||
docker build --build-arg NUGET_USERNAME=${{ secrets.NUGET_USERNAME }} --build-arg NUGET_PASSWORD=${{ secrets.NUGET_PASSWORD }} -t ${{ secrets.DOCKER_USERNAME }}/mirea-backend:latest .
|
|
||||||
docker push ${{ secrets.DOCKER_USERNAME }}/mirea-backend:latest
|
|
||||||
|
|
||||||
- name: Start ssh-agent
|
|
||||||
id: ssh-agent
|
|
||||||
uses: webfactory/ssh-agent@v0.9.0
|
|
||||||
with:
|
|
||||||
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
|
||||||
|
|
||||||
- name: Deploy to Server
|
|
||||||
env:
|
|
||||||
SSH_HOST: ${{ secrets.SSH_HOST }}
|
|
||||||
SSH_USER: ${{ secrets.SSH_USER }}
|
|
||||||
DOCKER_IMAGE: ${{ secrets.DOCKER_USERNAME }}/mirea-backend:latest
|
|
||||||
PATH_TO_SAVE: /data
|
|
||||||
SECURITY_SIGNING_TOKEN: ${{ secrets.SECURITY_SIGNING_TOKEN }}
|
|
||||||
SECURITY_ENCRYPTION_TOKEN: ${{ secrets.SECURITY_ENCRYPTION_TOKEN }}
|
|
||||||
SECURITY_LIFE_TIME_RT: ${{ secrets.SECURITY_LIFE_TIME_RT }}
|
|
||||||
SECURITY_LIFE_TIME_JWT: ${{ secrets.SECURITY_LIFE_TIME_JWT }}
|
|
||||||
SECURITY_LIFE_TIME_1_FA: ${{ secrets.SECURITY_LIFE_TIME_1_FA }}
|
|
||||||
SECURITY_JWT_ISSUER: ${{ secrets.SECURITY_JWT_ISSUER }}
|
|
||||||
SECURITY_JWT_AUDIENCE: ${{ secrets.SECURITY_JWT_AUDIENCE }}
|
|
||||||
SECURITY_HASH_ITERATION: ${{ secrets.SECURITY_HASH_ITERATION }}
|
|
||||||
SECURITY_HASH_MEMORY: ${{ secrets.SECURITY_HASH_MEMORY }}
|
|
||||||
SECURITY_HASH_PARALLELISM: ${{ secrets.SECURITY_HASH_PARALLELISM }}
|
|
||||||
SECURITY_HASH_SIZE: ${{ secrets.SECURITY_HASH_SIZE }}
|
|
||||||
SECURITY_HASH_TOKEN: ${{ secrets.SECURITY_HASH_TOKEN }}
|
|
||||||
SECURITY_SALT_SIZE: ${{ secrets.SECURITY_SALT_SIZE }}
|
|
||||||
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
|
|
||||||
GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}
|
|
||||||
YANDEX_CLIENT_ID: ${{ secrets.YANDEX_CLIENT_ID }}
|
|
||||||
YANDEX_CLIENT_SECRET: ${{ secrets.YANDEX_CLIENT_SECRET }}
|
|
||||||
MAILRU_CLIENT_ID: ${{ secrets.MAILRU_CLIENT_ID }}
|
|
||||||
MAILRU_CLIENT_SECRET: ${{ secrets.MAILRU_CLIENT_SECRET }}
|
|
||||||
run: |
|
|
||||||
ssh-keyscan $SSH_HOST >> ~/.ssh/known_hosts
|
|
||||||
ssh $SSH_USER@$SSH_HOST "
|
|
||||||
docker pull $DOCKER_IMAGE &&
|
|
||||||
docker stop mirea-backend || true &&
|
|
||||||
docker rm mirea-backend || true &&
|
|
||||||
docker run -d --name mirea-backend -p 8085:8080 \
|
|
||||||
--restart=on-failure:10 \
|
|
||||||
-v mirea-data:/data \
|
|
||||||
-e PATH_TO_SAVE=$PATH_TO_SAVE \
|
|
||||||
-e SECURITY_SIGNING_TOKEN=$SECURITY_SIGNING_TOKEN \
|
|
||||||
-e SECURITY_ENCRYPTION_TOKEN=$SECURITY_ENCRYPTION_TOKEN \
|
|
||||||
-e SECURITY_LIFE_TIME_RT=$SECURITY_LIFE_TIME_RT \
|
|
||||||
-e SECURITY_LIFE_TIME_JWT=$SECURITY_LIFE_TIME_JWT \
|
|
||||||
-e SECURITY_LIFE_TIME_1_FA=$SECURITY_LIFE_TIME_1_FA \
|
|
||||||
-e SECURITY_JWT_ISSUER=$SECURITY_JWT_ISSUER \
|
|
||||||
-e SECURITY_JWT_AUDIENCE=$SECURITY_JWT_AUDIENCE \
|
|
||||||
-e SECURITY_HASH_ITERATION=$SECURITY_HASH_ITERATION \
|
|
||||||
-e SECURITY_HASH_MEMORY=$SECURITY_HASH_MEMORY \
|
|
||||||
-e SECURITY_HASH_PARALLELISM=$SECURITY_HASH_PARALLELISM \
|
|
||||||
-e SECURITY_HASH_SIZE=$SECURITY_HASH_SIZE \
|
|
||||||
-e SECURITY_HASH_TOKEN=$SECURITY_HASH_TOKEN \
|
|
||||||
-e SECURITY_SALT_SIZE=$SECURITY_SALT_SIZE \
|
|
||||||
-e ACTUAL_SUB_PATH=api \
|
|
||||||
-e SWAGGER_SUB_PATH=swagger \
|
|
||||||
-e TZ=Europe/Moscow \
|
|
||||||
-e GOOGLE_CLIENT_ID=$GOOGLE_CLIENT_ID \
|
|
||||||
-e GOOGLE_CLIENT_SECRET=$GOOGLE_CLIENT_SECRET \
|
|
||||||
-e YANDEX_CLIENT_ID=$YANDEX_CLIENT_ID \
|
|
||||||
-e YANDEX_CLIENT_SECRET=$YANDEX_CLIENT_SECRET \
|
|
||||||
-e MAILRU_CLIENT_ID=$MAILRU_CLIENT_ID \
|
|
||||||
-e MAILRU_CLIENT_SECRET=$MAILRU_CLIENT_SECRET \
|
|
||||||
$DOCKER_IMAGE
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Remove all keys from ssh-agent
|
|
||||||
run: ssh-add -D
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
name: .NET Test Pipeline
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
[master, 'release/*']
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-and-test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up .NET Core
|
|
||||||
uses: actions/setup-dotnet@v4
|
|
||||||
with:
|
|
||||||
dotnet-version: '8.0.x'
|
|
||||||
|
|
||||||
- name: Restore dependencies
|
|
||||||
run: dotnet restore
|
|
||||||
|
|
||||||
- name: Build the solution
|
|
||||||
run: dotnet build --configuration Release
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: dotnet test --configuration Release --no-build --no-restore --verbosity normal
|
|
||||||
92
.github/workflows/deploy.yml
vendored
Normal file
92
.github/workflows/deploy.yml
vendored
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
name: Winsomnia GitOps Pipeline
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Determine environment
|
||||||
|
id: envdetect
|
||||||
|
run: |
|
||||||
|
REPO_SLUG=$(echo "${GITHUB_REPOSITORY#*/}" | tr '[:upper:]' '[:lower:]')
|
||||||
|
|
||||||
|
if [[ "${GITHUB_REF_NAME}" == "master" || "${GITHUB_REF_NAME}" == "main" ]]; then
|
||||||
|
DEPLOY_ENV="prod"
|
||||||
|
else
|
||||||
|
DEPLOY_ENV="dev"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "repo_slug=$REPO_SLUG" >> $GITHUB_OUTPUT
|
||||||
|
echo "deploy_env=$DEPLOY_ENV" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Enable Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to Winsomnia Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ secrets.WINSOMNIA_REGISTRY }}
|
||||||
|
username: ${{ secrets.WINSOMNIA_REGISTRY_USER }}
|
||||||
|
password: ${{ secrets.WINSOMNIA_REGISTRY_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build & Push Docker Image
|
||||||
|
id: build
|
||||||
|
env:
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
|
WINSOMNIA_NUGET_USERNAME: ${{ secrets.WINSOMNIA_NUGET_USERNAME }}
|
||||||
|
WINSOMNIA_NUGET_TOKEN: ${{ secrets.WINSOMNIA_NUGET_TOKEN }}
|
||||||
|
WINSOMNIA_NUGET_SOURCE: ${{ secrets.WINSOMNIA_NUGET_SOURCE }}
|
||||||
|
run: |
|
||||||
|
IMAGE="${{ secrets.WINSOMNIA_REGISTRY }}/winsomnia/${{ steps.envdetect.outputs.repo_slug }}:${GITHUB_REF_NAME}"
|
||||||
|
|
||||||
|
docker build \
|
||||||
|
--secret id=nuget_username,env=WINSOMNIA_NUGET_USERNAME \
|
||||||
|
--secret id=nuget_token,env=WINSOMNIA_NUGET_TOKEN \
|
||||||
|
--secret id=nuget_source,env=WINSOMNIA_NUGET_SOURCE \
|
||||||
|
-t "$IMAGE" .
|
||||||
|
|
||||||
|
docker push "$IMAGE"
|
||||||
|
|
||||||
|
echo "image=$IMAGE" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
image: ${{ steps.build.outputs.image }}
|
||||||
|
repo_slug: ${{ steps.envdetect.outputs.repo_slug }}
|
||||||
|
deploy_env: ${{ steps.envdetect.outputs.deploy_env }}
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
needs: build-and-push
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Add deploy SSH key
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "${{ secrets.WINSOMNIA_DEPLOY_KEY }}" > ~/.ssh/id_ed25519
|
||||||
|
chmod 600 ~/.ssh/id_ed25519
|
||||||
|
|
||||||
|
- name: Add host key
|
||||||
|
run: |
|
||||||
|
ssh-keyscan -H ${{ secrets.WINSOMNIA_DEPLOY_HOST }} >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
- name: Deploy via systemd trigger
|
||||||
|
run: |
|
||||||
|
SERVICE="${{ needs.build-and-push.outputs.repo_slug }}"
|
||||||
|
ENV="${{ needs.build-and-push.outputs.deploy_env }}"
|
||||||
|
IMAGE="${{ needs.build-and-push.outputs.image }}"
|
||||||
|
|
||||||
|
REMOTE_ROOT="${{ secrets.WINSOMNIA_INFRA_ROOT }}"
|
||||||
|
REMOTE_PATH="$REMOTE_ROOT/$SERVICE/$ENV"
|
||||||
|
REMOTE_REQ="$REMOTE_PATH/deploy/incoming/.deploy_req"
|
||||||
|
|
||||||
|
ssh -T -q ${{ secrets.WINSOMNIA_DEPLOY_USER }}@${{ secrets.WINSOMNIA_DEPLOY_HOST }} \
|
||||||
|
"echo 'IMAGE=$IMAGE' > '$REMOTE_REQ' && \
|
||||||
|
sudo /bin/systemctl start winsomnia-deploy@${SERVICE}-${ENV}.service"
|
||||||
@@ -1,13 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>disable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<Company>Winsomnia</Company>
|
|
||||||
<Version>1.0.0</Version>
|
|
||||||
<AssemblyVersion>1.0.3.0</AssemblyVersion>
|
|
||||||
<FileVersion>1.0.3.0</FileVersion>
|
|
||||||
<AssemblyName>Mirea.Api.Dto</AssemblyName>
|
<AssemblyName>Mirea.Api.Dto</AssemblyName>
|
||||||
<RootNamespace>$(AssemblyName)</RootNamespace>
|
<RootNamespace>$(AssemblyName)</RootNamespace>
|
||||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||||
|
|||||||
@@ -24,15 +24,16 @@ public class LoggingRequest
|
|||||||
public string? LogFilePath { get; set; }
|
public string? LogFilePath { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the API key for integrating with Seq, a log aggregation service.
|
/// Gets or sets the endpoint URL for the OpenTelemetry Collector.
|
||||||
/// If provided, logs will be sent to a Seq server using this API key.
|
/// This property specifies the OTLP endpoint to which logs will be sent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ApiKeySeq { get; set; }
|
public string? OpenTelemetryEndpoint { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the server URL for the Seq logging service.
|
/// Gets or sets the logical service name used for OpenTelemetry logging.
|
||||||
/// This property specifies the Seq server endpoint to which logs will be sent.
|
/// This name will be attached to log entries as the "service.name" resource attribute,
|
||||||
/// If <see cref="ApiKeySeq"/> is provided, logs will be sent to this server.
|
/// allowing logs to be grouped and filtered by service in backends like Loki or Grafana.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ApiServerSeq { get; set; }
|
public string? OpenTelemetryServiceName { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 17
|
# Visual Studio Version 18
|
||||||
VisualStudioVersion = 17.8.34330.188
|
VisualStudioVersion = 18.0.11222.15 d18.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Endpoint", "Endpoint\Endpoint.csproj", "{F3A1D12E-F5B2-4339-9966-DBF869E78357}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Endpoint", "Endpoint\Endpoint.csproj", "{F3A1D12E-F5B2-4339-9966-DBF869E78357}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -12,11 +12,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Elements of the solution",
|
|||||||
.env = .env
|
.env = .env
|
||||||
.gitattributes = .gitattributes
|
.gitattributes = .gitattributes
|
||||||
.gitignore = .gitignore
|
.gitignore = .gitignore
|
||||||
.gitea\workflows\deploy-stage.yaml = .gitea\workflows\deploy-stage.yaml
|
Directory.Build.props = Directory.Build.props
|
||||||
Dockerfile = Dockerfile
|
Dockerfile = Dockerfile
|
||||||
LICENSE.txt = LICENSE.txt
|
LICENSE.txt = LICENSE.txt
|
||||||
README.md = README.md
|
README.md = README.md
|
||||||
.gitea\workflows\test.yaml = .gitea\workflows\test.yaml
|
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiDto", "ApiDto\ApiDto.csproj", "{0335FA36-E137-453F-853B-916674C168FE}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiDto", "ApiDto\ApiDto.csproj", "{0335FA36-E137-453F-853B-916674C168FE}"
|
||||||
|
|||||||
14
Directory.Build.props
Normal file
14
Directory.Build.props
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<ImplicitUsings>disable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
|
|
||||||
|
<Company>Winsomnia</Company>
|
||||||
|
<Version>1.2.0</Version>
|
||||||
|
<AssemblyVersion>1.2.0.0</AssemblyVersion>
|
||||||
|
<FileVersion>1.2.0.0</FileVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
33
Dockerfile
33
Dockerfile
@@ -1,28 +1,41 @@
|
|||||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
|
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
|
||||||
LABEL company="Winsomnia"
|
LABEL company="Winsomnia"
|
||||||
LABEL maintainer.name="Wesser" maintainer.email="support@winsomnia.net"
|
LABEL maintainer.name="Wesser" maintainer.email="support@winsomnia.net"
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
|
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||||
CMD curl --fail http://localhost:8080/health || exit 1
|
CMD curl --fail http://localhost:8080/health || exit 1
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
ARG NUGET_USERNAME
|
RUN --mount=type=secret,id=nuget_username \
|
||||||
ARG NUGET_PASSWORD
|
--mount=type=secret,id=nuget_token \
|
||||||
ENV NUGET_USERNAME=$NUGET_USERNAME
|
--mount=type=secret,id=nuget_source \
|
||||||
ENV NUGET_PASSWORD=$NUGET_PASSWORD
|
dotnet nuget add source $(cat /run/secrets/nuget_source) \
|
||||||
|
--name Winsomnia \
|
||||||
|
--username $(cat /run/secrets/nuget_username) \
|
||||||
|
--password $(cat /run/secrets/nuget_token) \
|
||||||
|
--store-password-in-clear-text
|
||||||
|
|
||||||
RUN dotnet restore ./Backend.sln --configfile nuget.config
|
RUN dotnet restore ./Backend.sln
|
||||||
WORKDIR /app
|
|
||||||
WORKDIR /src
|
RUN dotnet publish Endpoint/Endpoint.csproj \
|
||||||
RUN dotnet publish ./Endpoint/Endpoint.csproj -c Release --self-contained false -p:PublishSingleFile=false -o /app
|
-c Release \
|
||||||
|
--self-contained false \
|
||||||
|
-p:PublishSingleFile=false \
|
||||||
|
-o /app
|
||||||
|
|
||||||
FROM base AS final
|
FROM base AS final
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY --from=build /app .
|
COPY --from=build /app .
|
||||||
|
|
||||||
RUN find . -name "*.pdb" -type f -delete
|
RUN find . -name "*.pdb" -type f -delete
|
||||||
|
|
||||||
ENTRYPOINT ["dotnet", "Mirea.Api.Endpoint.dll"]
|
ENTRYPOINT ["dotnet", "Mirea.Api.Endpoint.dll"]
|
||||||
@@ -45,32 +45,31 @@ public static class CronUpdateSkipService
|
|||||||
if (depth <= 0)
|
if (depth <= 0)
|
||||||
return [];
|
return [];
|
||||||
|
|
||||||
currentDate ??= DateOnly.FromDateTime(DateTime.UtcNow);
|
DateTimeOffset nextRunTime = (currentDate?.ToDateTime(TimeOnly.MinValue) ?? DateTime.Now);
|
||||||
DateTimeOffset nextRunTime = currentDate.Value.ToDateTime(new TimeOnly(0, 0, 0));
|
|
||||||
|
|
||||||
List<DateTimeOffset> result = [];
|
List<DateTimeOffset> result = [];
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
var lastSkip = data.FilterDateEntry(nextRunTime.DateTime).LastOrDefault();
|
var lastSkippedEntry = data.FilterDateEntry(nextRunTime.DateTime).LastOrDefault();
|
||||||
|
|
||||||
if (lastSkip is { Start: not null, End: not null })
|
if (lastSkippedEntry is { Start: not null, End: not null })
|
||||||
nextRunTime = new DateTimeOffset(lastSkip.End.Value.AddDays(1), new TimeOnly(0, 0, 0), TimeSpan.Zero);
|
nextRunTime = lastSkippedEntry.End.Value.ToDateTime(TimeOnly.MinValue).AddDays(1);
|
||||||
else if (lastSkip.Date.HasValue)
|
else if (lastSkippedEntry.Date.HasValue)
|
||||||
nextRunTime = new DateTimeOffset(lastSkip.Date.Value.AddDays(1), new TimeOnly(0, 0, 0), TimeSpan.Zero);
|
nextRunTime = lastSkippedEntry.Date.Value.ToDateTime(TimeOnly.MinValue).AddDays(1);
|
||||||
|
|
||||||
var next = expression.GetNextOccurrence(nextRunTime, TimeZoneInfo.Local);
|
var nextOccurrence = expression.GetNextOccurrence(nextRunTime.AddMinutes(-1), TimeZoneInfo.Local);
|
||||||
|
|
||||||
if (!next.HasValue)
|
if (!nextOccurrence.HasValue)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
nextRunTime = next.Value;
|
if (data.FilterDateEntry(nextOccurrence.Value.DateTime).Count != 0)
|
||||||
|
{
|
||||||
if (data.FilterDateEntry(nextRunTime.DateTime).Any())
|
nextRunTime = nextOccurrence.Value.AddDays(1);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
result.Add(nextRunTime);
|
result.Add(nextOccurrence.Value);
|
||||||
nextRunTime = nextRunTime.AddMinutes(1);
|
nextRunTime = nextOccurrence.Value.AddMinutes(1);
|
||||||
|
|
||||||
} while (result.Count < depth);
|
} while (result.Count < depth);
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -9,13 +9,13 @@ public class LogSettings : IIsConfigured
|
|||||||
public bool EnableLogToFile { get; set; }
|
public bool EnableLogToFile { get; set; }
|
||||||
public string? LogFilePath { get; set; }
|
public string? LogFilePath { get; set; }
|
||||||
public string? LogFileName { get; set; }
|
public string? LogFileName { get; set; }
|
||||||
public string? ApiKeySeq { get; set; }
|
public string? OpenTelemetryEndpoint { get; set; }
|
||||||
public string? ApiServerSeq { get; set; }
|
public string? OpenTelemetryServiceName { get; set; }
|
||||||
|
|
||||||
public bool IsConfigured()
|
public bool IsConfigured()
|
||||||
{
|
{
|
||||||
return !EnableLogToFile ||
|
return !EnableLogToFile
|
||||||
!string.IsNullOrEmpty(LogFilePath) &&
|
|| !string.IsNullOrEmpty(LogFilePath)
|
||||||
!string.IsNullOrEmpty(LogFileName);
|
&& !string.IsNullOrEmpty(LogFileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.OpenApi.Models;
|
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Mirea.Api.Endpoint.Configuration.SwaggerOptions;
|
|
||||||
|
|
||||||
public class ActionResultSchemaFilter : IOperationFilter
|
|
||||||
{
|
|
||||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
|
||||||
{
|
|
||||||
var returnType = context.MethodInfo.ReturnType;
|
|
||||||
if (!returnType.IsEquivalentTo(typeof(ActionResult)) &&
|
|
||||||
!returnType.IsEquivalentTo(typeof(ContentResult)) &&
|
|
||||||
!returnType.IsEquivalentTo(typeof(FileStreamResult)) &&
|
|
||||||
!returnType.IsGenericType)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (returnType.IsGenericType &&
|
|
||||||
!returnType.GetGenericTypeDefinition().IsEquivalentTo(typeof(ActionResult<>)) &&
|
|
||||||
!returnType.GetGenericTypeDefinition().IsEquivalentTo(typeof(Task<>)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var genericType = returnType.IsGenericType ? returnType.GetGenericArguments().FirstOrDefault() : returnType;
|
|
||||||
if (genericType == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var responseTypeAttributes = context.MethodInfo.GetCustomAttributes(typeof(ProducesResponseTypeAttribute), false)
|
|
||||||
.Cast<ProducesResponseTypeAttribute>()
|
|
||||||
.Where(attr => attr.StatusCode == 200)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
var contentType = "application/json";
|
|
||||||
|
|
||||||
if (context.MethodInfo.GetCustomAttributes(typeof(ProducesAttribute), false)
|
|
||||||
.FirstOrDefault() is ProducesAttribute producesAttribute)
|
|
||||||
contentType = producesAttribute.ContentTypes.FirstOrDefault() ?? "application/json";
|
|
||||||
|
|
||||||
if (responseTypeAttributes.Count != 0)
|
|
||||||
{
|
|
||||||
var responseType = responseTypeAttributes.First().Type;
|
|
||||||
genericType = responseType;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (genericType.IsEquivalentTo(typeof(ContentResult)) || genericType.IsEquivalentTo(typeof(FileStreamResult)))
|
|
||||||
{
|
|
||||||
operation.Responses["200"] = new OpenApiResponse
|
|
||||||
{
|
|
||||||
Description = "OK",
|
|
||||||
Content = new Dictionary<string, OpenApiMediaType>
|
|
||||||
{
|
|
||||||
[contentType] = new()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (genericType == typeof(ActionResult))
|
|
||||||
{
|
|
||||||
operation.Responses["200"] = new OpenApiResponse { Description = "OK" };
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
OpenApiSchema schema;
|
|
||||||
if (genericType.IsGenericType && genericType.GetGenericTypeDefinition() == typeof(ActionResult<>))
|
|
||||||
schema = context.SchemaGenerator.GenerateSchema(genericType.GetGenericArguments().FirstOrDefault(),
|
|
||||||
context.SchemaRepository);
|
|
||||||
else
|
|
||||||
schema = context.SchemaGenerator.GenerateSchema(genericType, context.SchemaRepository);
|
|
||||||
|
|
||||||
operation.Responses["200"] = new OpenApiResponse
|
|
||||||
{
|
|
||||||
Description = "OK",
|
|
||||||
Content = new Dictionary<string, OpenApiMediaType>
|
|
||||||
{
|
|
||||||
[contentType] = new() { Schema = schema }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,51 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Mvc.ApiExplorer;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|
||||||
using Microsoft.OpenApi.Models;
|
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.Json;
|
|
||||||
|
|
||||||
namespace Mirea.Api.Endpoint.Configuration.SwaggerOptions;
|
|
||||||
|
|
||||||
public class DefaultValues : IOperationFilter
|
|
||||||
{
|
|
||||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
|
||||||
{
|
|
||||||
var apiDescription = context.ApiDescription;
|
|
||||||
operation.Deprecated |= apiDescription.IsDeprecated();
|
|
||||||
|
|
||||||
foreach (var responseType in context.ApiDescription.SupportedResponseTypes)
|
|
||||||
{
|
|
||||||
var responseKey = responseType.IsDefaultResponse ? "default" : responseType.StatusCode.ToString();
|
|
||||||
var response = operation.Responses[responseKey];
|
|
||||||
|
|
||||||
foreach (var contentType in response.Content.Keys)
|
|
||||||
{
|
|
||||||
if (responseType.ApiResponseFormats.All(x => x.MediaType != contentType))
|
|
||||||
response.Content.Remove(contentType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (operation.Parameters == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var parameter in operation.Parameters)
|
|
||||||
{
|
|
||||||
var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);
|
|
||||||
|
|
||||||
parameter.Description ??= description.ModelMetadata.Description;
|
|
||||||
|
|
||||||
if (parameter.Schema.Default == null &&
|
|
||||||
description.DefaultValue != null &&
|
|
||||||
description.DefaultValue is not DBNull &&
|
|
||||||
description.ModelMetadata is ModelMetadata modelMetadata)
|
|
||||||
{
|
|
||||||
var json = JsonSerializer.Serialize(description.DefaultValue, modelMetadata.ModelType);
|
|
||||||
parameter.Schema.Default = OpenApiAnyFactory.CreateFromJson(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
parameter.Required |= description.IsRequired;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
using Microsoft.OpenApi.Any;
|
|
||||||
using Microsoft.OpenApi.Models;
|
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Mirea.Api.Endpoint.Configuration.SwaggerOptions;
|
|
||||||
|
|
||||||
public class EnumSchemaFilter : ISchemaFilter
|
|
||||||
{
|
|
||||||
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
|
|
||||||
{
|
|
||||||
if (!context.Type.IsEnum)
|
|
||||||
return;
|
|
||||||
|
|
||||||
schema.Enum.Clear();
|
|
||||||
|
|
||||||
var enumValues = Enum.GetNames(context.Type)
|
|
||||||
.Select(name => new OpenApiString(name))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
foreach (var value in enumValues)
|
|
||||||
schema.Enum.Add(value);
|
|
||||||
|
|
||||||
schema.Type = "string";
|
|
||||||
schema.Format = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using Microsoft.OpenApi.Models;
|
|
||||||
using Mirea.Api.Endpoint.Common.Attributes;
|
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace Mirea.Api.Endpoint.Configuration.SwaggerOptions;
|
|
||||||
|
|
||||||
public class ExampleFilter : ISchemaFilter
|
|
||||||
{
|
|
||||||
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
|
|
||||||
{
|
|
||||||
var att = context.ParameterInfo?.GetCustomAttribute<SwaggerDefaultAttribute>();
|
|
||||||
if (att != null)
|
|
||||||
schema.Example = new Microsoft.OpenApi.Any.OpenApiString(att.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
|
||||||
using Microsoft.OpenApi.Models;
|
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace Mirea.Api.Endpoint.Configuration.SwaggerOptions;
|
|
||||||
|
|
||||||
public class TagSchemeFilter : IOperationFilter
|
|
||||||
{
|
|
||||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
|
||||||
{
|
|
||||||
if (context.ApiDescription.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var controllerType = controllerActionDescriptor.ControllerTypeInfo;
|
|
||||||
|
|
||||||
var tagsAttribute = controllerType.GetCustomAttributes<TagsAttribute>(inherit: true).FirstOrDefault();
|
|
||||||
|
|
||||||
if (tagsAttribute == null)
|
|
||||||
{
|
|
||||||
var baseType = controllerType.BaseType;
|
|
||||||
while (baseType != null)
|
|
||||||
{
|
|
||||||
tagsAttribute = baseType.GetCustomAttributes<TagsAttribute>(inherit: true).FirstOrDefault();
|
|
||||||
if (tagsAttribute != null)
|
|
||||||
break;
|
|
||||||
|
|
||||||
baseType = baseType.BaseType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tagsAttribute == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
operation.Tags ??= [];
|
|
||||||
operation.Tags.Add(new OpenApiTag { Name = tagsAttribute.Tags[0] });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,6 +23,7 @@ using Mirea.Api.Security.Services;
|
|||||||
using MySqlConnector;
|
using MySqlConnector;
|
||||||
using Npgsql;
|
using Npgsql;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
using Serilog.Sinks.OpenTelemetry;
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -434,26 +435,32 @@ public class SetupController(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(request?.ApiServerSeq))
|
if (!string.IsNullOrEmpty(request?.OpenTelemetryEndpoint)
|
||||||
|
&& !string.IsNullOrEmpty(request.OpenTelemetryServiceName))
|
||||||
{
|
{
|
||||||
settings.ApiServerSeq = request.ApiServerSeq;
|
settings.OpenTelemetryEndpoint = request.OpenTelemetryEndpoint;
|
||||||
settings.ApiKeySeq = request.ApiKeySeq;
|
settings.OpenTelemetryServiceName = request.OpenTelemetryServiceName;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log.Logger = new LoggerConfiguration()
|
using var innerLogger = new LoggerConfiguration()
|
||||||
.WriteTo.Seq(settings.ApiServerSeq, apiKey: settings.ApiKeySeq)
|
.WriteTo.OpenTelemetry(options =>
|
||||||
|
{
|
||||||
|
options.Endpoint = settings.OpenTelemetryEndpoint;
|
||||||
|
options.Protocol = OtlpProtocol.Grpc;
|
||||||
|
options.ResourceAttributes = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["service.name"] = settings.OpenTelemetryServiceName,
|
||||||
|
["deployment.environment"] = "test"
|
||||||
|
};
|
||||||
|
})
|
||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
|
|
||||||
Log.Warning("Testing configuration Seq.");
|
innerLogger.Warning("🚀 Testing OpenTelemetry log delivery.");
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// ignoring
|
Console.WriteLine("Error sending log to OTEL Collector: " + ex.Message);
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
Log.CloseAndFlush();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,8 +484,8 @@ public class SetupController(
|
|||||||
EnableLogToFile = settings.EnableLogToFile,
|
EnableLogToFile = settings.EnableLogToFile,
|
||||||
LogFileName = settings.LogFileName,
|
LogFileName = settings.LogFileName,
|
||||||
LogFilePath = settings.LogFilePath,
|
LogFilePath = settings.LogFilePath,
|
||||||
ApiKeySeq = settings.ApiKeySeq,
|
OpenTelemetryEndpoint = settings.OpenTelemetryEndpoint,
|
||||||
ApiServerSeq = settings.ApiServerSeq
|
OpenTelemetryServiceName = settings.OpenTelemetryServiceName
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Cronos;
|
using Cronos;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
@@ -191,15 +192,27 @@ public class ScheduleController(ILogger<ScheduleController> logger, IOptionsSnap
|
|||||||
filePaths.Add((filePath, defaultCampus[i]));
|
filePaths.Add((filePath, defaultCampus[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
var sync = (ScheduleSynchronizer)ActivatorUtilities.GetServiceOrCreateInstance(provider, typeof(ScheduleSynchronizer));
|
|
||||||
|
|
||||||
if (force)
|
if (force)
|
||||||
{
|
{
|
||||||
dbContext.Lessons.RemoveRange(dbContext.Lessons.ToList());
|
dbContext.Lessons.RemoveRange(await dbContext.Lessons.ToListAsync());
|
||||||
await dbContext.SaveChangesAsync();
|
await dbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = sync.StartSync(filePaths, CancellationToken.None);
|
var scopeFactory = provider.GetRequiredService<IServiceScopeFactory>();
|
||||||
|
ThreadPool.QueueUserWorkItem(async void (_) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var scope = scopeFactory.CreateScope();
|
||||||
|
var sync = (ScheduleSynchronizer)ActivatorUtilities.GetServiceOrCreateInstance(scope.ServiceProvider, typeof(ScheduleSynchronizer));
|
||||||
|
|
||||||
|
await sync.StartSync(filePaths, CancellationToken.None);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.Message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class ImportController(IMediator mediator, IOptionsSnapshot<GeneralConfig
|
|||||||
LessonTypeIds = request.LessonType
|
LessonTypeIds = request.LessonType
|
||||||
})).Schedules.ToList();
|
})).Schedules.ToList();
|
||||||
|
|
||||||
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
ExcelPackage.License.SetNonCommercialOrganization("Winsomnia");
|
||||||
using var package = new ExcelPackage();
|
using var package = new ExcelPackage();
|
||||||
var worksheet = package.Workbook.Worksheets.Add("Расписание");
|
var worksheet = package.Workbook.Worksheets.Add("Расписание");
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,14 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>disable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<Company>Winsomnia</Company>
|
|
||||||
<Version>1.0-rc7</Version>
|
|
||||||
<AssemblyVersion>1.0.2.7</AssemblyVersion>
|
|
||||||
<FileVersion>1.0.2.7</FileVersion>
|
|
||||||
<AssemblyName>Mirea.Api.Endpoint</AssemblyName>
|
<AssemblyName>Mirea.Api.Endpoint</AssemblyName>
|
||||||
<RootNamespace>$(AssemblyName)</RootNamespace>
|
<RootNamespace>$(AssemblyName)</RootNamespace>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<InvariantGlobalization>false</InvariantGlobalization>
|
<InvariantGlobalization>false</InvariantGlobalization>
|
||||||
<UserSecretsId>65cea060-88bf-4e35-9cfb-18fc996a8f05</UserSecretsId>
|
|
||||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
|
||||||
<DockerfileContext>.</DockerfileContext>
|
|
||||||
<SignAssembly>False</SignAssembly>
|
|
||||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||||
<DocumentationFile>docs.xml</DocumentationFile>
|
<DocumentationFile>docs.xml</DocumentationFile>
|
||||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||||
|
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -26,49 +16,54 @@
|
|||||||
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
|
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.Redis" Version="9.0.0" />
|
<PackageReference Include="AspNetCore.HealthChecks.Redis" Version="9.0.0" />
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.System" Version="9.0.0" />
|
<PackageReference Include="AspNetCore.HealthChecks.System" Version="9.0.0" />
|
||||||
<PackageReference Include="Cronos" Version="0.9.0" />
|
<PackageReference Include="Cronos" Version="0.11.1" />
|
||||||
<PackageReference Include="EPPlus" Version="7.5.3" />
|
<PackageReference Include="EPPlus" Version="8.2.1" />
|
||||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.72" />
|
<PackageReference Include="EPPlus.System.Drawing" Version="8.1.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.12" />
|
<PackageReference Include="HtmlAgilityPack" Version="1.12.4" />
|
||||||
<PackageReference Include="Microsoft.Build.Framework" Version="17.12.6" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.1">
|
<PackageReference Include="Microsoft.Bcl.Cryptography" Version="10.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.1">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="9.0.1">
|
<PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="10.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.1" />
|
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.15.0" />
|
||||||
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.3.1" />
|
<PackageReference Include="Microsoft.Win32.SystemEvents" Version="10.0.1" />
|
||||||
<PackageReference Include="Mirea.Tools.Schedule.Parser" Version="1.2.5" />
|
<PackageReference Include="Mirea.Tools.Schedule.Parser" Version="1.2.9" />
|
||||||
<PackageReference Include="Mirea.Tools.Schedule.WebParser" Version="1.0.6" />
|
<PackageReference Include="Mirea.Tools.Schedule.WebParser" Version="1.0.7" />
|
||||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
<PackageReference Include="OpenTelemetry" Version="1.14.0" />
|
||||||
<PackageReference Include="Serilog" Version="4.2.0" />
|
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.14.0" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.14.0" />
|
||||||
|
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.14.0" />
|
||||||
|
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.14.0" />
|
||||||
|
<PackageReference Include="QRCoder" Version="1.7.0" />
|
||||||
|
<PackageReference Include="Serilog" Version="4.3.0" />
|
||||||
|
<PackageReference Include="Serilog.AspNetCore" Version="10.0.0" />
|
||||||
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
|
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.Debug" Version="3.0.0" />
|
<PackageReference Include="Serilog.Sinks.Debug" Version="3.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="10.0.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.Seq" Version="9.0.0" />
|
<PackageReference Include="Serilog.Sinks.OpenTelemetry" Version="4.2.0" />
|
||||||
<PackageReference Include="StackExchange.Redis" Version="2.8.24" />
|
<PackageReference Include="StackExchange.Redis" Version="2.10.1" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.0.1" />
|
||||||
<PackageReference Include="System.CodeDom" Version="[8.0.0, 9.0.0)" />
|
<PackageReference Include="System.Composition" Version="10.0.1" />
|
||||||
<PackageReference Include="System.Composition" Version="[8.0.0, 9.0.0)" />
|
<PackageReference Include="System.Composition.AttributedModel" Version="10.0.1" />
|
||||||
<PackageReference Include="System.Composition.AttributedModel" Version="9.0.1" />
|
<PackageReference Include="System.Composition.Convention" Version="10.0.1" />
|
||||||
<PackageReference Include="System.Composition.Convention" Version="9.0.1" />
|
<PackageReference Include="System.Composition.Hosting" Version="10.0.1" />
|
||||||
<PackageReference Include="System.Composition.Hosting" Version="9.0.1" />
|
<PackageReference Include="System.Composition.Runtime" Version="10.0.1" />
|
||||||
<PackageReference Include="System.Composition.Runtime" Version="9.0.1" />
|
<PackageReference Include="System.Composition.TypedParts" Version="10.0.1" />
|
||||||
<PackageReference Include="System.Composition.TypedParts" Version="9.0.1" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.15.0" />
|
||||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.1" />
|
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="10.0.1" />
|
||||||
<PackageReference Include="System.Drawing.Common" Version="9.0.1" />
|
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="10.0.1" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.3.1" />
|
<PackageReference Include="Z.EntityFramework.Extensions.EFCore" Version="10.105.2" />
|
||||||
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="9.0.1" />
|
|
||||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="9.0.1" />
|
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.1" />
|
|
||||||
<PackageReference Include="System.Threading.Channels" Version="[8.0.0, 9.0.0)" />
|
|
||||||
<PackageReference Include="Z.EntityFramework.Extensions.EFCore" Version="9.103.7" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -78,7 +73,6 @@
|
|||||||
<ProjectReference Include="..\Security\Security.csproj" />
|
<ProjectReference Include="..\Security\Security.csproj" />
|
||||||
<ProjectReference Include="..\SqlData\Migrations\PsqlMigrations\PsqlMigrations.csproj" />
|
<ProjectReference Include="..\SqlData\Migrations\PsqlMigrations\PsqlMigrations.csproj" />
|
||||||
<ProjectReference Include="..\SqlData\Migrations\SqliteMigrations\SqliteMigrations.csproj" />
|
<ProjectReference Include="..\SqlData\Migrations\SqliteMigrations\SqliteMigrations.csproj" />
|
||||||
<ProjectReference Include="..\SqlData\Migrations\MysqlMigrations\MysqlMigrations.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
Binary file not shown.
Binary file not shown.
90
Endpoint/Resources/SharedResources.Designer.cs
generated
Normal file
90
Endpoint/Resources/SharedResources.Designer.cs
generated
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// Этот код создан программой.
|
||||||
|
// Исполняемая версия:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
|
||||||
|
// повторной генерации кода.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace Mirea.Api.Endpoint.Resources {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д.
|
||||||
|
/// </summary>
|
||||||
|
// Этот класс создан автоматически классом StronglyTypedResourceBuilder
|
||||||
|
// с помощью такого средства, как ResGen или Visual Studio.
|
||||||
|
// Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen
|
||||||
|
// с параметром /str или перестройте свой проект VS.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
public class SharedResources {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal SharedResources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
public static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Mirea.Api.Endpoint.Resources.SharedResources", typeof(SharedResources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Перезаписывает свойство CurrentUICulture текущего потока для всех
|
||||||
|
/// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
public static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ищет локализованную строку, похожую на Please provide this traceId to the administrator for further investigation..
|
||||||
|
/// </summary>
|
||||||
|
public static string ProvideTraceId {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ProvideTraceId", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ищет локализованную строку, похожую на Resource not found..
|
||||||
|
/// </summary>
|
||||||
|
public static string ResourceNotFound {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ResourceNotFound", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ищет локализованную строку, похожую на An unexpected error occurred..
|
||||||
|
/// </summary>
|
||||||
|
public static string UnexpectedErrorOccurred {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("UnexpectedErrorOccurred", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
129
Endpoint/Resources/SharedResources.resx
Normal file
129
Endpoint/Resources/SharedResources.resx
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="ProvideTraceId" xml:space="preserve">
|
||||||
|
<value>Please provide this traceId to the administrator for further investigation.</value>
|
||||||
|
</data>
|
||||||
|
<data name="ResourceNotFound" xml:space="preserve">
|
||||||
|
<value>Resource not found.</value>
|
||||||
|
</data>
|
||||||
|
<data name="UnexpectedErrorOccurred" xml:space="preserve">
|
||||||
|
<value>An unexpected error occurred.</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
129
Endpoint/Resources/SharedResources.ru-RU.resx
Normal file
129
Endpoint/Resources/SharedResources.ru-RU.resx
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="ProvideTraceId" xml:space="preserve">
|
||||||
|
<value />
|
||||||
|
</data>
|
||||||
|
<data name="ResourceNotFound" xml:space="preserve">
|
||||||
|
<value />
|
||||||
|
</data>
|
||||||
|
<data name="UnexpectedErrorOccurred" xml:space="preserve">
|
||||||
|
<value>Неизвестная ошибка</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
11
README.md
11
README.md
@@ -1,6 +1,6 @@
|
|||||||
# MIREA schedule by Winsomnia
|
# MIREA schedule by Winsomnia
|
||||||
|
|
||||||
[](https://dotnet.microsoft.com/download/dotnet/8.0)
|
[](https://dotnet.microsoft.com/download/dotnet/10.0)
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
This project is a backend part of an application developed on ASP.NET , which provides an API for getting schedule data.
|
This project is a backend part of an application developed on ASP.NET , which provides an API for getting schedule data.
|
||||||
@@ -86,12 +86,11 @@ To set up the `redirect URL` when registering and logging in using OAuth 2, use
|
|||||||
|
|
||||||
**Where:**
|
**Where:**
|
||||||
|
|
||||||
- `{schema}` is the protocol you are using (`http` or `https').
|
- `{schema}` is the protocol you are using (`http` or `https`).
|
||||||
- `{domain}` is your domain (for example, `mydomain.com ` or IP address).
|
- `{domain}` is your domain (for example, `mydomain.com` or IP address).
|
||||||
- `{portString}` is a port string that is only needed if your application is running on a non—standard port (for
|
- `{portString}` is a port string that is only needed if your application is running on a non-standard port (for
|
||||||
example, `:8080`). If you use standard ports (`80` for `http` and `443` for `https`), this parameter can be omitted.
|
example, `:8080`). If you use standard ports (`80` for `http` and `443` for `https`), this parameter can be omitted.
|
||||||
- `{ACTUAL_SUB_PATH}` is the path to your API that you specify in the settings. If it ends with `/api', then don't add `
|
- `{ACTUAL_SUB_PATH}` is the path to your API that you specify in the settings. If it ends with `/api`, then don't add `/api` at the end of the URL.
|
||||||
/api` at the end of the URL.
|
|
||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>disable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<Company>Winsomnia</Company>
|
|
||||||
<Version>1.1.3</Version>
|
|
||||||
<AssemblyVersion>1.1.3.3</AssemblyVersion>
|
|
||||||
<FileVersion>1.1.3.3</FileVersion>
|
|
||||||
<AssemblyName>Mirea.Api.Security</AssemblyName>
|
<AssemblyName>Mirea.Api.Security</AssemblyName>
|
||||||
<RootNamespace>$(AssemblyName)</RootNamespace>
|
<RootNamespace>$(AssemblyName)</RootNamespace>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
@@ -15,10 +8,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Konscious.Security.Cryptography.Argon2" Version="1.3.1" />
|
<PackageReference Include="Konscious.Security.Cryptography.Argon2" Version="1.3.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.1" />
|
<PackageReference Include="Otp.NET" Version="1.4.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.1" />
|
|
||||||
<PackageReference Include="Otp.NET" Version="1.4.0" />
|
|
||||||
<PackageReference Include="System.Memory" Version="4.6.0" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,22 +1,18 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>disable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<Company>Winsomnia</Company>
|
|
||||||
<Version>1.0.3</Version>
|
|
||||||
<AssemblyVersion>1.0.3.3</AssemblyVersion>
|
|
||||||
<FileVersion>1.0.3.3</FileVersion>
|
|
||||||
<AssemblyName>Mirea.Api.DataAccess.Application</AssemblyName>
|
<AssemblyName>Mirea.Api.DataAccess.Application</AssemblyName>
|
||||||
<RootNamespace>$(AssemblyName)</RootNamespace>
|
<RootNamespace>$(AssemblyName)</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentValidation" Version="11.11.0" />
|
<PackageReference Include="FluentValidation" Version="12.1.1" />
|
||||||
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.11.0" />
|
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.1.1" />
|
||||||
<PackageReference Include="MediatR" Version="12.4.1" />
|
<PackageReference Include="MediatR" Version="14.0.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>disable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<Company>Winsomnia</Company>
|
|
||||||
<Version>1.0.1</Version>
|
|
||||||
<AssemblyVersion>1.0.3.1</AssemblyVersion>
|
|
||||||
<FileVersion>1.0.3.1</FileVersion>
|
|
||||||
<AssemblyName>Mirea.Api.DataAccess.Domain</AssemblyName>
|
<AssemblyName>Mirea.Api.DataAccess.Domain</AssemblyName>
|
||||||
<RootNamespace>$(AssemblyName)</RootNamespace>
|
<RootNamespace>$(AssemblyName)</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<BaseOutputPath>..\..\Persistence\bin\</BaseOutputPath>
|
<BaseOutputPath>..\..\Persistence\bin\</BaseOutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<BaseOutputPath>..\..\Persistence\bin\</BaseOutputPath>
|
<BaseOutputPath>..\..\Persistence\bin\</BaseOutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<BaseOutputPath>..\..\Persistence\bin\</BaseOutputPath>
|
<BaseOutputPath>..\..\Persistence\bin\</BaseOutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,13 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>disable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<Company>Winsomnia</Company>
|
|
||||||
<Version>1.0.3</Version>
|
|
||||||
<AssemblyVersion>1.0.3.3</AssemblyVersion>
|
|
||||||
<FileVersion>1.0.3.3</FileVersion>
|
|
||||||
<AssemblyName>Mirea.Api.DataAccess.Persistence</AssemblyName>
|
<AssemblyName>Mirea.Api.DataAccess.Persistence</AssemblyName>
|
||||||
<RootNamespace>$(AssemblyName)</RootNamespace>
|
<RootNamespace>$(AssemblyName)</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -16,14 +9,8 @@
|
|||||||
<PackageReference Include="AspNetCore.HealthChecks.MySql" Version="9.0.0" />
|
<PackageReference Include="AspNetCore.HealthChecks.MySql" Version="9.0.0" />
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.NpgSql" Version="9.0.0" />
|
<PackageReference Include="AspNetCore.HealthChecks.NpgSql" Version="9.0.0" />
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.Sqlite" Version="9.0.0" />
|
<PackageReference Include="AspNetCore.HealthChecks.Sqlite" Version="9.0.0" />
|
||||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.1" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.1" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="9.0.1" />
|
|
||||||
<PackageReference Include="MySqlConnector" Version="2.4.0" />
|
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.3" />
|
|
||||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0-preview.2.efcore.9.0.0" />
|
|
||||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.10" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
13
nuget.config
13
nuget.config
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<packageSources>
|
|
||||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
|
||||||
<add key="winsomnia.net" value="https://git.winsomnia.net/api/packages/Winsomnia/nuget/index.json" />
|
|
||||||
</packageSources>
|
|
||||||
<packageSourceCredentials>
|
|
||||||
<winsomnia.net>
|
|
||||||
<add key="Username" value="%NUGET_USERNAME%" />
|
|
||||||
<add key="ClearTextPassword" value="%NUGET_PASSWORD%" />
|
|
||||||
</winsomnia.net>
|
|
||||||
</packageSourceCredentials>
|
|
||||||
</configuration>
|
|
||||||
Reference in New Issue
Block a user