mirror of
https://github.com/Sheldan/gw2-tools.git
synced 2026-01-01 06:49:06 +00:00
initial commit of functioning opening tracking
This commit is contained in:
35
.github/workflows/build.yml
vendored
Normal file
35
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
# This workflow will build a Java project with Maven
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||
|
||||
name: Execute Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- feature/**
|
||||
- hotfix/**
|
||||
- bugfix/**
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'corretto'
|
||||
java-version: 21
|
||||
- name: Build with Maven
|
||||
run: mvn -B install --file gw2-tools-backend/pom.xml
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20.x'
|
||||
- name: Install dependencies
|
||||
run: cd gw2-tools-ui && npm ci
|
||||
86
.github/workflows/release.yaml
vendored
Normal file
86
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
name: Publishes a new version of the application
|
||||
on: workflow_dispatch
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: master
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'corretto'
|
||||
java-version: 21
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20.x'
|
||||
- name: Install node dependencies and build
|
||||
working-directory: ./gw2-tools-ui
|
||||
run: npm ci
|
||||
- name: Build ui application
|
||||
working-directory: ./gw2-tools-ui
|
||||
run: npm run build
|
||||
- name: Copy built UI
|
||||
run: cp -R gw2-tools-ui/build/* gw2-tools-frontend/resources
|
||||
- name: Load current version
|
||||
id: version
|
||||
working-directory: ./gw2-tools-backend
|
||||
run: echo "version=$(mvn -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive exec:exec | cut -d- -f1)" >> $GITHUB_ENV
|
||||
- name: Release maven packages
|
||||
uses: qcastel/github-actions-maven-release@v1.12.41
|
||||
env:
|
||||
JAVA_HOME: /usr/lib/jvm/java-21-openjdk/
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
maven-project-folder: "gw2-tools-backend/"
|
||||
git-release-bot-name: "release-bot"
|
||||
git-release-bot-email: "release-bot@sheldan.dev"
|
||||
release-branch-name: master
|
||||
maven-args: "-Dmaven.javadoc.skip=true -s settings.xml -DskipTests"
|
||||
access-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Login to Harbor
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: harbor.sheldan.dev
|
||||
username: ${{ secrets.HARBOR_USERNAME }}
|
||||
password: ${{ secrets.HARBOR_TOKEN }}
|
||||
- name: Update Chart version file
|
||||
uses: fjogeleit/yaml-update-action@v0.13.2
|
||||
with:
|
||||
valueFile: 'ci/gw2-tools/Chart.yaml'
|
||||
propertyPath: 'version'
|
||||
value: ${{ env.version }}
|
||||
commitChange: false
|
||||
- name: Update .env version
|
||||
run:
|
||||
sed -i '2s/.*/VERSION=${{ env.version }}/' .env
|
||||
- name: Update version in package.json
|
||||
working-directory: ./gw2-tools-ui
|
||||
run:
|
||||
npm version ${{ env.version }}
|
||||
- name: Load env file
|
||||
id: dotenv
|
||||
uses: falti/dotenv-action@v1.0.4
|
||||
with:
|
||||
path: .env
|
||||
- name: Build and push Docker containers
|
||||
run: docker-compose build && docker-compose push
|
||||
env:
|
||||
REGISTRY_PREFIX: ${{ steps.dotenv.outputs.registry_prefix }}
|
||||
VERSION: ${{ steps.dotenv.outputs.version }}
|
||||
- name: Helm package and push
|
||||
working-directory: ./ci/
|
||||
run: |-
|
||||
helm registry login -u '${{ secrets.HARBOR_USERNAME }}' -p '${{ secrets.HARBOR_TOKEN }}' harbor.sheldan.dev
|
||||
helm package gw2-tools
|
||||
helm push gw2-tools*.tgz oci://harbor.sheldan.dev/gw2
|
||||
- name: Fix file permissions
|
||||
run:
|
||||
sudo chmod -R ugo+rwX . # https://github.com/actions/checkout/issues/164
|
||||
- name: Commit updated versions
|
||||
uses: EndBug/add-and-commit@v9
|
||||
with:
|
||||
author_name: "release-bot"
|
||||
author_email: "release-bot@sheldan.dev"
|
||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -18,7 +18,19 @@
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
.idea
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
replay_pid*
|
||||
/gw2-tools-frontend/resources/static/
|
||||
/gw2-tools-frontend/resources/favicon.ico
|
||||
/gw2-tools-frontend/resources/asset-manifest.json
|
||||
/gw2-tools-frontend/resources/manifest.json
|
||||
/gw2-tools-frontend/resources/robots.txt
|
||||
/gw2-tools-frontend/resources/logo512.png
|
||||
/gw2-tools-frontend/resources/index.html
|
||||
/gw2-tools-frontend/resources/logo192.png
|
||||
/tilt/gw2-tools-dev/Chart.lock
|
||||
/target/
|
||||
*.tgz
|
||||
|
||||
3
.tiltignore
Normal file
3
.tiltignore
Normal file
@@ -0,0 +1,3 @@
|
||||
*.tgz
|
||||
tilt/gw2-tools-dev/tmpcharts/
|
||||
tilt/gw2-tools-dev/charts/*.tgz
|
||||
9
README
Normal file
9
README
Normal file
@@ -0,0 +1,9 @@
|
||||
Just some tools that I created thinking what could help:
|
||||
for now its a tracker to track openings of containers, to help with drop rate research on the wiki
|
||||
|
||||
|
||||
|
||||
Notice required by Guild wars 2:
|
||||
© ArenaNet LLC. All rights reserved. NCSOFT, ArenaNet, Guild Wars, Guild Wars 2, GW2, Guild Wars 2: Heart of Thorns, Guild Wars 2: Path of Fire, Guild Wars 2: End of Dragons, and Guild Wars 2: Secrets of the Obscure and all associated logos, designs, and composite marks are trademarks or registered trademarks of NCSOFT Corporation.
|
||||
|
||||
As taken from Guild Wars 2 Content Terms of Use on 2024-01-08.
|
||||
44
Tiltfile
Normal file
44
Tiltfile
Normal file
@@ -0,0 +1,44 @@
|
||||
allow_k8s_contexts('k8s-cluster')
|
||||
|
||||
load('ext://restart_process', 'docker_build_with_restart')
|
||||
registry = 'harbor.sheldan.dev/gw2/'
|
||||
|
||||
local_resource(
|
||||
'java-backend-compile',
|
||||
' cd gw2-tools-backend && mvn install && ' +
|
||||
' rm -rf executable/target/jar-staging && ' +
|
||||
' unzip -o executable/target/gw2-tools-exec.jar -d executable/target/jar-staging && ' +
|
||||
' rsync --delete --delete-excluded --inplace --checksum --exclude="*-SNAPSHOT.jar" -r executable/target/jar-staging/ executable/target/jar && ' +
|
||||
' rm -rf executable/target/jar/snapshots && ' +
|
||||
' mkdir executable/target/jar/snapshots && ' +
|
||||
' rsync --delete --delete-excluded --inplace --checksum --include="*/" --include="*-SNAPSHOT.jar" --exclude="*" -r executable/target/jar-staging/BOOT-INF/lib/ executable/target/jar/snapshots',
|
||||
deps=['gw2-tools-backend/pom.xml'], auto_init=False, trigger_mode = TRIGGER_MODE_MANUAL, labels=['compilation'])
|
||||
|
||||
docker_build_with_restart(
|
||||
registry + 'gw2-tools-backend',
|
||||
'./gw2-tools-backend/executable/target/jar',
|
||||
entrypoint=['java', '-noverify', '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005', '-cp', '.:./lib/*', 'dev.sheldan.gw2.tools.ToolApplicationKt'],
|
||||
dockerfile='./gw2-tools-backend/executable/Dockerfile',
|
||||
live_update=[
|
||||
sync('./gw2-tools-backend/executable/target/jar/BOOT-INF/lib', '/app/lib'),
|
||||
sync('./gw2-tools-backend/executable/target/jar/META-INF', '/app/META-INF'),
|
||||
sync('./gw2-tools-backend/executable/target/jar/BOOT-INF/classes', '/app'),
|
||||
sync('./gw2-tools-backend/executable/target/jar/snapshots', '/app/lib')
|
||||
],
|
||||
)
|
||||
|
||||
docker_build(registry + 'gw2-tools-frontend', 'gw2-tools-frontend', dockerfile='gw2-tools-frontend/docker/Dockerfile')
|
||||
docker_build(registry + 'gw2-tools-database', 'gw2-tools-backend/database/src/main', dockerfile='gw2-tools-backend/database/src/main/docker/Dockerfile')
|
||||
|
||||
local('cd tilt/gw2-tools-dev && helm dep up')
|
||||
k8s_yaml(helm('tilt/gw2-tools-dev', values=[
|
||||
'./../drr-environments/argocd/apps/gw2-tools/values/local/values.yaml',
|
||||
'./../drr-environments/argocd/apps/gw2-tools/values/local/values.secrets.yaml'
|
||||
]))
|
||||
|
||||
k8s_resource('backend', port_forwards='5005:5005', labels=['applications'])
|
||||
k8s_resource('frontend', labels=['applications'])
|
||||
k8s_resource('chart-postgresql', port_forwards='5432:5432', labels=['applications'])
|
||||
k8s_resource('db-config-deployment-job', auto_init=False, trigger_mode = TRIGGER_MODE_MANUAL, labels=['deployment'])
|
||||
|
||||
local_resource('ui-build', 'rm -rf gw2-tools-frontend/resources/static && cd gw2-tools-ui && npm run build && cp -R build/* ../gw2-tools-frontend/resources', auto_init=False, trigger_mode = TRIGGER_MODE_MANUAL, labels=['compilation'])
|
||||
23
ci/gw2-tools/.helmignore
Normal file
23
ci/gw2-tools/.helmignore
Normal file
@@ -0,0 +1,23 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
8
ci/gw2-tools/Chart.yaml
Normal file
8
ci/gw2-tools/Chart.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
apiVersion: v2
|
||||
name: gw2-tools
|
||||
description: A Helm chart for Kubernetes
|
||||
|
||||
type: application
|
||||
|
||||
version: 0.0.1
|
||||
|
||||
7
ci/gw2-tools/configuration/db/liquibase.properties
Normal file
7
ci/gw2-tools/configuration/db/liquibase.properties
Normal file
@@ -0,0 +1,7 @@
|
||||
liquibase.secureParsing=false
|
||||
liquibase.liquibaseSchemaName={{ .Values.db.schemaName }}
|
||||
liquibase.command.defaultSchemaName={{ .Values.db.schemaName }}
|
||||
liquibase.command.password={{ .Values.dbCredentials.password }}
|
||||
liquibase.command.username={{ .Values.dbCredentials.userName }}
|
||||
driver=org.postgresql.Driver
|
||||
liquibase.command.url=jdbc:postgresql://{{ $.Values.dbCredentials.host }}:{{ $.Values.dbCredentials.port }}/{{ $.Values.dbCredentials.name }}
|
||||
62
ci/gw2-tools/templates/_helpers.tpl
Normal file
62
ci/gw2-tools/templates/_helpers.tpl
Normal file
@@ -0,0 +1,62 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "gw2Tools.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "gw2Tools.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "gw2Tools.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "gw2Tools.labels" -}}
|
||||
helm.sh/chart: {{ include "gw2Tools.chart" . }}
|
||||
{{ include "gw2Tools.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "gw2Tools.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "gw2Tools.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "gw2Tools.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "gw2Tools.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
102
ci/gw2-tools/templates/backend-deployment.yaml
Normal file
102
ci/gw2-tools/templates/backend-deployment.yaml
Normal file
@@ -0,0 +1,102 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: backend
|
||||
labels:
|
||||
app: backend
|
||||
spec:
|
||||
{{- if not .Values.backend.autoscaling.enabled }}
|
||||
replicas: {{ .Values.backend.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app: backend
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.backend.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
app: backend
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "gw2Tools.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.backend.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.backend.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.backend.image.repository }}/{{ .Values.backend.image.image }}:{{ .Values.backend.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.backend.image.pullPolicy }}
|
||||
env:
|
||||
- name: DB_PASS
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: dbPassword
|
||||
- name: DB_HOST
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: dbHost
|
||||
- name: DB_PORT
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: dbPort
|
||||
- name: DB_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: dbUser
|
||||
- name: DB_NAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: dbName
|
||||
{{- range $key, $value := .Values.backend.propertyConfig }}
|
||||
- name: {{ $key | quote }}
|
||||
value: {{ $value | quote}}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.backend.service.port }}
|
||||
protocol: TCP
|
||||
{{- if .Values.backend.debug.enabled }}
|
||||
- name: debug
|
||||
containerPort: {{ .Values.backend.debug.port }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health-check
|
||||
port: {{ .Values.backend.service.port }}
|
||||
initialDelaySeconds: {{ $.Values.backend.readinessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ $.Values.backend.readinessProbe.periodSeconds }}
|
||||
failureThreshold: {{ $.Values.backend.readinessProbe.failureThreshold }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health-check
|
||||
port: {{ .Values.backend.service.port }}
|
||||
initialDelaySeconds: {{ $.Values.backend.livenessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ $.Values.backend.livenessProbe.periodSeconds }}
|
||||
failureThreshold: {{ $.Values.backend.livenessProbe.failureThreshold }}
|
||||
resources:
|
||||
{{- toYaml .Values.backend.resources | nindent 12 }}
|
||||
{{- with .Values.backend.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.backend.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.backend.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
28
ci/gw2-tools/templates/backend-hpa.yaml
Normal file
28
ci/gw2-tools/templates/backend-hpa.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
{{- if .Values.backend.autoscaling.enabled }}
|
||||
apiVersion: autoscaling/v2beta1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: backend
|
||||
labels:
|
||||
{{- include "gw2Tools.labels" . | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: backend
|
||||
minReplicas: {{ .Values.backend.autoscaling.minReplicas }}
|
||||
maxReplicas: {{ .Values.backend.autoscaling.maxReplicas }}
|
||||
metrics:
|
||||
{{- if .Values.backend.autoscaling.targetCPUUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
targetAverageUtilization: {{ .Values.backend.autoscaling.targetCPUUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- if .Values.backend.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
targetAverageUtilization: {{ .Values.backend.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
15
ci/gw2-tools/templates/backend-service.yaml
Normal file
15
ci/gw2-tools/templates/backend-service.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Values.backend.service.name }}
|
||||
labels:
|
||||
{{- include "gw2Tools.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.backend.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.backend.service.port }}
|
||||
targetPort: {{ .Values.backend.service.port }}
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: backend
|
||||
38
ci/gw2-tools/templates/cache-reload-job.yaml
Normal file
38
ci/gw2-tools/templates/cache-reload-job.yaml
Normal file
@@ -0,0 +1,38 @@
|
||||
{{- if .Values.cacheJob.enabled -}}
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: cache-job
|
||||
spec:
|
||||
schedule: {{ .Values.cacheJob.cronExpression | quote }}
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: item-cache
|
||||
image: {{ .Values.cacheJob.image.repository }}{{ .Values.cacheJob.image.image }}:{{ .Values.cacheJob.image.tag }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- curl -X POST "${BACKEND_HOST}:${BACKEND_PORT}/item-cache"
|
||||
env:
|
||||
- name: BACKEND_HOST
|
||||
value: "{{ .Values.backend.service.name }}.{{ .Release.Namespace }}.svc.cluster.local"
|
||||
- name: BACKEND_PORT
|
||||
value: "{{ .Values.backend.service.port }}"
|
||||
- name: currency-cache
|
||||
image: {{ .Values.cacheJob.image.repository }}{{ .Values.cacheJob.image.image }}:{{ .Values.cacheJob.image.tag }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- curl -X POST "${BACKEND_HOST}:${BACKEND_PORT}/currency-cache"
|
||||
env:
|
||||
- name: BACKEND_HOST
|
||||
value: "{{ .Values.backend.service.name }}.{{ .Release.Namespace }}.svc.cluster.local"
|
||||
- name: BACKEND_PORT
|
||||
value: "{{ .Values.backend.service.port }}"
|
||||
restartPolicy: Never
|
||||
{{- end }}
|
||||
44
ci/gw2-tools/templates/db-config-deployment-job.yaml
Normal file
44
ci/gw2-tools/templates/db-config-deployment-job.yaml
Normal file
@@ -0,0 +1,44 @@
|
||||
{{- if .Values.dbDeployment.enabled -}}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: db-config-deployment-job
|
||||
annotations:
|
||||
"helm.sh/hook": pre-upgrade,pre-install
|
||||
"helm.sh/hook-weight": "-5"
|
||||
"helm.sh/hook-delete-policy": hook-succeeded
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: db-config-deployment-job
|
||||
image: "{{ $.Values.dbDeployment.image.repository }}/{{ $.Values.dbDeployment.image.image }}:{{ $.Values.dbDeployment.image.tag | default .Chart.AppVersion}}"
|
||||
imagePullPolicy: {{ $.Values.dbDeployment.image.pullPolicy }}
|
||||
args:
|
||||
- "--changelog-file=changeLog.xml"
|
||||
- "--defaultsFile=/liquibase/config/liquibase.properties"
|
||||
- "update"
|
||||
volumeMounts:
|
||||
- mountPath: "/liquibase/config/"
|
||||
name: liquibase-config
|
||||
readOnly: true
|
||||
restartPolicy: Never
|
||||
volumes:
|
||||
- name: liquibase-config
|
||||
secret:
|
||||
secretName: liquibase-config
|
||||
backoffLimit: 4
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: liquibase-config
|
||||
data:
|
||||
liquibase.properties: {{ (tpl (.Files.Get "configuration/db/liquibase.properties") . ) | b64enc }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
13
ci/gw2-tools/templates/db-credentials.yaml
Normal file
13
ci/gw2-tools/templates/db-credentials.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: db-credentials
|
||||
annotations:
|
||||
"helm.sh/hook": pre-upgrade,pre-install
|
||||
"helm.sh/hook-weight": "-6"
|
||||
data:
|
||||
dbPassword: {{ $.Values.dbCredentials.password | b64enc }} # b64enc is needed, because a stringData secret field cannot hold numeric values
|
||||
dbUser: {{ $.Values.dbCredentials.userName | b64enc }}
|
||||
dbHost: {{ $.Values.dbCredentials.host | b64enc }}
|
||||
dbPort: {{ $.Values.dbCredentials.port | b64enc }}
|
||||
dbName: {{ $.Values.dbCredentials.name | b64enc }}
|
||||
72
ci/gw2-tools/templates/frontend-deployment.yaml
Normal file
72
ci/gw2-tools/templates/frontend-deployment.yaml
Normal file
@@ -0,0 +1,72 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: frontend
|
||||
labels:
|
||||
app: frontend
|
||||
spec:
|
||||
{{- if not .Values.frontend.autoscaling.enabled }}
|
||||
replicas: {{ .Values.frontend.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app: frontend
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.frontend.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
app: frontend
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "gw2Tools.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.frontend.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.frontend.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.frontend.image.repository }}/{{ .Values.frontend.image.image }}:{{ .Values.frontend.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.frontend.image.pullPolicy }}
|
||||
env:
|
||||
- name: BACKEND_HOST
|
||||
value: "{{ .Values.backend.service.name }}.{{ .Release.Namespace }}.svc.cluster.local"
|
||||
- name: BACKEND_PORT
|
||||
value: "{{ .Values.backend.service.port }}"
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.frontend.service.port }}
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: {{ .Values.frontend.service.port }}
|
||||
initialDelaySeconds: {{ $.Values.frontend.livenessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ $.Values.frontend.livenessProbe.periodSeconds }}
|
||||
failureThreshold: {{ $.Values.frontend.livenessProbe.failureThreshold }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: {{ .Values.frontend.service.port }}
|
||||
initialDelaySeconds: {{ $.Values.frontend.readinessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ $.Values.frontend.readinessProbe.periodSeconds }}
|
||||
failureThreshold: {{ $.Values.frontend.readinessProbe.failureThreshold }}
|
||||
resources:
|
||||
{{- toYaml .Values.frontend.resources | nindent 12 }}
|
||||
{{- with .Values.frontend.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.frontend.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.frontend.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
56
ci/gw2-tools/templates/frontend-ingress.yaml
Normal file
56
ci/gw2-tools/templates/frontend-ingress.yaml
Normal file
@@ -0,0 +1,56 @@
|
||||
{{- if .Values.frontend.ingress.enabled -}}
|
||||
{{- $fullName := include "gw2Tools.fullname" . -}}
|
||||
{{- $svcPort := .Values.frontend.service.port -}}
|
||||
{{- $servicePort := .Values.frontend.service.port -}}
|
||||
{{- $serviceName := .Values.frontend.service.name -}}
|
||||
{{- $ingressPath := .Values.frontend.ingress.path -}}
|
||||
{{- $ingressPathType := .Values.frontend.ingress.pathType -}}
|
||||
{{- $extraPaths := .Values.frontend.ingress.extraPaths -}}
|
||||
{{- if and .Values.frontend.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.frontend.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.frontend.ingress.annotations "kubernetes.io/ingress.class" .Values.frontend.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: frontend-ingress
|
||||
labels:
|
||||
{{- include "gw2Tools.labels" . | nindent 4 }}
|
||||
{{- with .Values.frontend.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.frontend.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.frontend.ingress.className }}
|
||||
{{- end }}
|
||||
{{- with .Values.frontend.ingress.tls }}
|
||||
tls:
|
||||
{{- tpl (toYaml .) $ | nindent 4 }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- if .Values.frontend.ingress.hosts }}
|
||||
{{- range .Values.frontend.ingress.hosts }}
|
||||
- host: {{ tpl . $ }}
|
||||
http:
|
||||
paths:
|
||||
{{- with $extraPaths }}
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
- path: {{ $ingressPath }}
|
||||
pathType: {{ $ingressPathType }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ $serviceName }}
|
||||
port:
|
||||
number: {{ $servicePort }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
15
ci/gw2-tools/templates/frontend-service.yaml
Normal file
15
ci/gw2-tools/templates/frontend-service.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Values.frontend.service.name }}
|
||||
labels:
|
||||
{{- include "gw2Tools.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.frontend.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.frontend.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: frontend
|
||||
12
ci/gw2-tools/templates/serviceaccount.yaml
Normal file
12
ci/gw2-tools/templates/serviceaccount.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "gw2Tools.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "gw2Tools.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
175
ci/gw2-tools/values.yaml
Normal file
175
ci/gw2-tools/values.yaml
Normal file
@@ -0,0 +1,175 @@
|
||||
# Default values for gw2-tools.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
backend:
|
||||
image:
|
||||
repository: harbor.sheldan.dev/gw2
|
||||
pullPolicy: Always
|
||||
image: gw2-tools-backend
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: 0.0.1
|
||||
debug:
|
||||
enabled: true
|
||||
port: 5005
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8080
|
||||
name: backend-service
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
resources:
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
# fsGroup: 2000
|
||||
|
||||
securityContext: {}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# readOnlyRootFilesystem: true
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
annotations: {}
|
||||
labels: {}
|
||||
path: /
|
||||
|
||||
pathType: Prefix
|
||||
|
||||
hosts:
|
||||
extraPaths: []
|
||||
tls: []
|
||||
|
||||
replicaCount: 1
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 100
|
||||
targetCPUUtilizationPercentage: 80
|
||||
# targetMemoryUtilizationPercentage: 80
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 5
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 5
|
||||
failureThreshold: 3
|
||||
|
||||
propertyConfig:
|
||||
hikariPoolSize: 3
|
||||
|
||||
dbDeployment:
|
||||
enabled: true
|
||||
image:
|
||||
repository: harbor.sheldan.dev/gw2
|
||||
image: gw2-tools-database
|
||||
tag: 0.0.1
|
||||
pullPolicy: Always
|
||||
|
||||
cacheJob:
|
||||
enabled: true
|
||||
image:
|
||||
repository:
|
||||
pullPolicy: Always
|
||||
image: curlimages/curl
|
||||
tag: 8.5.0
|
||||
cronExpression: "@weekly"
|
||||
|
||||
|
||||
dbCredentials:
|
||||
password:
|
||||
userName:
|
||||
host:
|
||||
port:
|
||||
name:
|
||||
db:
|
||||
schemaName: gw2
|
||||
|
||||
frontend:
|
||||
image:
|
||||
repository: harbor.sheldan.dev/gw2
|
||||
pullPolicy: IfNotPresent
|
||||
image: gw2-tools-frontend
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: 0.0.1
|
||||
port: 8080
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8080
|
||||
name: frontend
|
||||
nodeSelector: {}
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 5
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 5
|
||||
failureThreshold: 3
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
resources:
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
# fsGroup: 2000
|
||||
|
||||
securityContext: {}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# readOnlyRootFilesystem: true
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
annotations: {}
|
||||
labels: {}
|
||||
path: /
|
||||
|
||||
pathType: Prefix
|
||||
|
||||
hosts:
|
||||
extraPaths: []
|
||||
tls: []
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 100
|
||||
targetCPUUtilizationPercentage: 80
|
||||
# targetMemoryUtilizationPercentage: 80
|
||||
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
|
||||
serviceAccount:
|
||||
# Specifies whether a service account should be created
|
||||
create: true
|
||||
# Annotations to add to the service account
|
||||
annotations: {}
|
||||
# The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
|
||||
|
||||
17
docker-compose.yaml
Normal file
17
docker-compose.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
version: "3.7"
|
||||
|
||||
services:
|
||||
gw2-tools-backend:
|
||||
build:
|
||||
context: gw2-tools-backend/packaging/src/main/docker
|
||||
image: ${REGISTRY_PREFIX}gw2-tools-backend:${VERSION:-latest}
|
||||
gw2-tools-frontend:
|
||||
build:
|
||||
context: gw2-tools-frontend
|
||||
dockerfile: docker/Dockerfile
|
||||
image: ${REGISTRY_PREFIX}gw2-tools-frontend:${VERSION:-latest}
|
||||
database:
|
||||
build:
|
||||
context: gw2-tools-backend/database/src/main
|
||||
dockerfile: docker/Dockerfile
|
||||
image: ${REGISTRY_PREFIX}gw2-tools-database:${VERSION:-latest}
|
||||
62
gw2-tools-backend/database/pom.xml
Normal file
62
gw2-tools-backend/database/pom.xml
Normal file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>gw2-tools</artifactId>
|
||||
<version>0.0.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>database</artifactId>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
2
gw2-tools-backend/database/src/main/docker/Dockerfile
Normal file
2
gw2-tools-backend/database/src/main/docker/Dockerfile
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM liquibase/liquibase:4.25.1-alpine
|
||||
ADD resources/changeLog/ /liquibase/
|
||||
@@ -0,0 +1,27 @@
|
||||
package dev.sheldan.gw2.tools.entity
|
||||
|
||||
import jakarta.persistence.*
|
||||
|
||||
@Entity(name = "currency")
|
||||
class Currency(@Column(name="name", nullable = false)
|
||||
val name: String,
|
||||
|
||||
@Column(name="description")
|
||||
val description: String,
|
||||
|
||||
@Column(name="icon_url", nullable = false)
|
||||
val iconUrl: String,
|
||||
|
||||
@OneToMany(
|
||||
fetch = FetchType.LAZY,
|
||||
cascade = [CascadeType.PERSIST, CascadeType.MERGE],
|
||||
mappedBy = "currency"
|
||||
)
|
||||
private var openings: List<OpeningCurrency>? = null,
|
||||
|
||||
@Id
|
||||
@Column(name="id", nullable = false)
|
||||
val id: Int) {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package dev.sheldan.gw2.tools.entity
|
||||
|
||||
import jakarta.persistence.*
|
||||
|
||||
@Entity(name = "item")
|
||||
class Item(@Column(name="name", nullable = false)
|
||||
val name: String,
|
||||
|
||||
@Column(name="description")
|
||||
val description: String,
|
||||
|
||||
@Column(name="icon_url", nullable = false)
|
||||
val iconUrl: String,
|
||||
|
||||
@Column(name="type", nullable = false)
|
||||
val type: String,
|
||||
|
||||
@Column(name="rarity", nullable = false)
|
||||
val rarity: String,
|
||||
|
||||
@OneToMany(cascade = [CascadeType.MERGE, CascadeType.PERSIST], orphanRemoval = true, fetch = FetchType.LAZY, mappedBy = "item")
|
||||
var submissionTemplates: List<SubmissionTemplate>? = null,
|
||||
|
||||
@OneToMany(
|
||||
fetch = FetchType.LAZY,
|
||||
cascade = [CascadeType.PERSIST, CascadeType.MERGE],
|
||||
mappedBy = "item"
|
||||
)
|
||||
private var openings: List<OpeningItem>? = null,
|
||||
|
||||
@Id
|
||||
@Column(name="id", nullable = false)
|
||||
val id: Int) {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package dev.sheldan.gw2.tools.entity
|
||||
|
||||
import jakarta.persistence.*
|
||||
import java.time.Instant
|
||||
|
||||
@Entity(name = "opening")
|
||||
class Opening(
|
||||
@ManyToOne(fetch = FetchType.LAZY, optional = false)
|
||||
@JoinColumn(name = "user_id", referencedColumnName = "id")
|
||||
val user: User,
|
||||
@OneToMany(cascade = [CascadeType.MERGE, CascadeType.PERSIST], orphanRemoval = true, fetch = FetchType.LAZY, mappedBy = "opening")
|
||||
var currencies: List<OpeningCurrency>? = null,
|
||||
@OneToMany(cascade = [CascadeType.MERGE, CascadeType.PERSIST], orphanRemoval = true, fetch = FetchType.LAZY, mappedBy = "opening")
|
||||
var items: List<OpeningItem>? = null,
|
||||
@Column(name = "description")
|
||||
var description: String?=null,
|
||||
@Column(name = "created", insertable = false, updatable = false)
|
||||
var creationDate: Instant?=null,
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
val id: Int?=null
|
||||
) {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.gw2.tools.entity
|
||||
|
||||
import jakarta.persistence.*
|
||||
|
||||
@Entity(name = "opening_currency")
|
||||
class OpeningCurrency(
|
||||
@ManyToOne(cascade = [CascadeType.PERSIST, CascadeType.MERGE])
|
||||
@JoinColumn(name = "currency_id", nullable = false)
|
||||
val currency: Currency,
|
||||
@ManyToOne(cascade = [CascadeType.PERSIST, CascadeType.MERGE])
|
||||
@JoinColumn(name = "opening_id", nullable = false)
|
||||
val opening: Opening,
|
||||
@Column(name = "amount")
|
||||
val amount: Int,
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
val id: Int?=null
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.gw2.tools.entity
|
||||
|
||||
import jakarta.persistence.*
|
||||
|
||||
@Entity(name = "opening_item")
|
||||
class OpeningItem(
|
||||
@ManyToOne(cascade = [CascadeType.PERSIST, CascadeType.MERGE])
|
||||
@JoinColumn(name = "item_id", nullable = false)
|
||||
val item: Item,
|
||||
@ManyToOne(cascade = [CascadeType.PERSIST, CascadeType.MERGE])
|
||||
@JoinColumn(name = "opening_id", nullable = false)
|
||||
val opening: Opening,
|
||||
@Column(name = "count")
|
||||
val count: Int,
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
val id: Int?=null
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.gw2.tools.entity
|
||||
|
||||
import jakarta.persistence.*
|
||||
|
||||
@Entity(name = "submission_template")
|
||||
class SubmissionTemplate(
|
||||
@ManyToOne(cascade = [CascadeType.PERSIST, CascadeType.MERGE])
|
||||
@JoinColumn(name = "item_id", nullable = false)
|
||||
val item: Item,
|
||||
@Column(name = "template_text")
|
||||
val templateText: String,
|
||||
@Column(name = "name")
|
||||
val name: String,
|
||||
@Column(name = "description")
|
||||
val description: String,
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
val id: Int?=null
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.gw2.tools.entity
|
||||
|
||||
import jakarta.persistence.Column
|
||||
import jakarta.persistence.Entity
|
||||
import jakarta.persistence.Id
|
||||
|
||||
@Entity(name = "gw2_user")
|
||||
class User( @Id
|
||||
@Column(name="id", nullable = false)
|
||||
val id: String) {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.sheldan.gw2.tools.repo
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.Currency
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
|
||||
interface CurrencyRepository : CrudRepository<Currency, Int> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.sheldan.gw2.tools.repo
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.Item
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
|
||||
interface ItemRepository : CrudRepository<Item, Int> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.sheldan.gw2.tools.repo
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.Opening
|
||||
import dev.sheldan.gw2.tools.entity.User
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
|
||||
interface OpeningRepository : CrudRepository<Opening, Int> {
|
||||
fun getAllByUser(user: User): List<Opening>
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.sheldan.gw2.tools.repo
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.Item
|
||||
import dev.sheldan.gw2.tools.entity.SubmissionTemplate
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
|
||||
interface SubmissionTemplateRepository : CrudRepository<SubmissionTemplate, Int> {
|
||||
fun getSubmissionTemplateByItem(item: Item): List<SubmissionTemplate>
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.sheldan.gw2.tools.repo
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.User
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
|
||||
interface UserRepository : CrudRepository<User, String> {
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package dev.sheldan.gw2.tools.service
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.Currency
|
||||
import dev.sheldan.gw2.tools.repo.CurrencyRepository
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class CurrencyManagement(val currencyRepository: CurrencyRepository) {
|
||||
fun getCurrencies(currencyIds: List<Int>): List<Currency> {
|
||||
return currencyRepository.findAllById(currencyIds).toList()
|
||||
}
|
||||
|
||||
fun getCurrenciesAsMap(currencyIds: List<Int>): Map<Int, Currency> {
|
||||
return getCurrencies(currencyIds).associateBy { it.id }
|
||||
}
|
||||
|
||||
fun getCurrencies() : List<Currency> {
|
||||
return currencyRepository.findAll().toList()
|
||||
}
|
||||
|
||||
fun createAndSaveCurrency(id: Int, name: String, description: String, iconUrl: String): Currency {
|
||||
val currency = createCurrency(id, name, description, iconUrl)
|
||||
return currencyRepository.save(currency)
|
||||
}
|
||||
|
||||
fun createCurrency(id: Int, name: String, description: String, iconUrl: String): Currency {
|
||||
return Currency(name, description, iconUrl, null, id)
|
||||
}
|
||||
|
||||
fun saveCurrency(currency: Currency): Currency {
|
||||
return currencyRepository.save(currency)
|
||||
}
|
||||
|
||||
fun saveCurrencies(currencies: List<Currency>) {
|
||||
currencyRepository.saveAll(currencies)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package dev.sheldan.gw2.tools.service
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.Item
|
||||
import dev.sheldan.gw2.tools.repo.ItemRepository
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class ItemManagement(val itemRepository: ItemRepository) {
|
||||
fun getItems(itemIds: List<Int>) : List<Item> {
|
||||
return itemRepository.findAllById(itemIds).toList()
|
||||
}
|
||||
|
||||
fun getItem(itemId: Int) : Item? {
|
||||
return itemRepository.findByIdOrNull(itemId)
|
||||
}
|
||||
|
||||
fun getItemsAsMap(itemIds: List<Int>) : Map<Int, Item> {
|
||||
return getItems(itemIds).associateBy { it.id }
|
||||
}
|
||||
|
||||
fun getItems() : List<Item> {
|
||||
return itemRepository.findAll().toList()
|
||||
}
|
||||
|
||||
fun createItem(id: Int, name: String, description: String, iconUrl: String, type: String, rarity: String): Item {
|
||||
return Item(name, description, iconUrl, type, rarity, null, null, id)
|
||||
}
|
||||
|
||||
fun createAndSaveItem(id: Int, name: String, description: String, iconUrl: String, type: String, rarity: String): Item {
|
||||
val item = createItem(id, name, description, iconUrl, type, rarity)
|
||||
return saveItem(item)
|
||||
}
|
||||
|
||||
fun saveItems(items: List<Item>) {
|
||||
itemRepository.saveAll(items)
|
||||
}
|
||||
|
||||
fun saveItem(item: Item): Item {
|
||||
return itemRepository.save(item)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package dev.sheldan.gw2.tools.service
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.*
|
||||
import dev.sheldan.gw2.tools.entity.Currency
|
||||
import dev.sheldan.gw2.tools.repo.OpeningRepository
|
||||
import org.springframework.stereotype.Component
|
||||
import java.util.*
|
||||
|
||||
@Component
|
||||
class OpeningManagement(
|
||||
val openingRepository: OpeningRepository
|
||||
) {
|
||||
fun createOpening(user: User, items: Map<Item, Int>, currencies: Map<Currency, Int>, description: String?){
|
||||
val opening = Opening(user, description = description)
|
||||
val openingItems: List<OpeningItem> = items.map { OpeningItem(it.key, opening, it.value) }
|
||||
val openingCurrencies: List<OpeningCurrency> = currencies.map { OpeningCurrency(it.key, opening, it.value) }
|
||||
opening.currencies = openingCurrencies
|
||||
opening.items = openingItems
|
||||
openingRepository.save(opening)
|
||||
}
|
||||
|
||||
fun getOpeningsByUser(user: User): List<Opening> {
|
||||
return openingRepository.getAllByUser(user)
|
||||
}
|
||||
|
||||
fun getAllOpenings(): List<Opening> {
|
||||
return openingRepository.findAll().toList()
|
||||
}
|
||||
|
||||
fun getOpening(id: Int): Optional<Opening> {
|
||||
return openingRepository.findById(id)
|
||||
}
|
||||
|
||||
fun deleteOpening(opening: Opening) {
|
||||
openingRepository.delete(opening)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package dev.sheldan.gw2.tools.service
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.Item
|
||||
import dev.sheldan.gw2.tools.entity.SubmissionTemplate
|
||||
import dev.sheldan.gw2.tools.repo.SubmissionTemplateRepository
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class SubmissionTemplateManagement(
|
||||
val submissionTemplateRepository: SubmissionTemplateRepository
|
||||
) {
|
||||
|
||||
fun getSubmissionTemplatesForItem(item: Item): List<SubmissionTemplate> {
|
||||
return submissionTemplateRepository.getSubmissionTemplateByItem(item)
|
||||
}
|
||||
|
||||
fun getAllSubmissionTemplates(): List<SubmissionTemplate> {
|
||||
return submissionTemplateRepository.findAll().toList()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package dev.sheldan.gw2.tools.service
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.User
|
||||
import dev.sheldan.gw2.tools.repo.UserRepository
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
import org.springframework.stereotype.Component
|
||||
import java.security.MessageDigest
|
||||
|
||||
@Component
|
||||
class UserManagement(val userRepository: UserRepository) {
|
||||
fun getUser(id: String): User? {
|
||||
return userRepository.findByIdOrNull(id)
|
||||
}
|
||||
|
||||
fun getOrCreateUser(token: String): User {
|
||||
val userId = createUserId(token)
|
||||
val possibleUser = getUser(userId)
|
||||
return possibleUser ?: createUser(userId)
|
||||
}
|
||||
|
||||
fun createUserWithId(id: String): User {
|
||||
val userObj = User(id)
|
||||
return userRepository.save(userObj)
|
||||
}
|
||||
|
||||
fun createUser(token: String): User {
|
||||
val hashed = createUserId(token)
|
||||
val userObj = User(hashed)
|
||||
return userRepository.save(userObj)
|
||||
}
|
||||
|
||||
private fun createUserId(token: String): String {
|
||||
val md = MessageDigest.getInstance("SHA-256")
|
||||
val digest = md.digest(token.toByteArray())
|
||||
val hashed = digest.fold("") { str, it -> str + "%02x".format(it) }
|
||||
return hashed
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.25.xsd">
|
||||
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.25.xsd">
|
||||
|
||||
<changeSet author="Sheldan" id="currency-table">
|
||||
<createTable tableName="currency">
|
||||
<column name="id" type="INTEGER">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
<column name="name" type="VARCHAR(64)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="description" type="VARCHAR(255)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="icon_url" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS currency_update_trigger ON currency;
|
||||
CREATE TRIGGER currency_update_trigger BEFORE UPDATE ON currency FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS currency_insert_trigger ON currency;
|
||||
CREATE TRIGGER currency_insert_trigger BEFORE INSERT ON currency FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.25.xsd">
|
||||
|
||||
<changeSet author="Sheldan" id="item-table">
|
||||
<createTable tableName="item">
|
||||
<column name="id" type="INTEGER">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
<column name="name" type="VARCHAR(128)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="description" type="VARCHAR(1024)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="icon_url" type="VARCHAR(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="type" type="VARCHAR(64)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="rarity" type="VARCHAR(32)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
<sql>
|
||||
ALTER TABLE item ADD CONSTRAINT check_item_rarity CHECK (rarity IN ('JUNK', 'BASIC', 'FINE', 'MASTERWORK', 'RARE', 'EXOTIC', 'ASCENDED', 'LEGENDARY'));
|
||||
ALTER TABLE item ADD CONSTRAINT check_item_type CHECK (type IN ('CONTAINER', 'ARMOR', 'BACK', 'BAG', 'CONSUMABLE', 'CRAFTING_MATERIAL', 'GATHERING', 'GIZMO', 'JADE_TECH_MODULE', 'KEY', 'MINI_PET', 'POWER_CORE', 'TOOL', 'TRAIT', 'TRINKET', 'TROPHY', 'UPGRADE_COMPONENT', 'WEAPON', 'RELIC'));
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS item_update_trigger ON item;
|
||||
CREATE TRIGGER item_update_trigger BEFORE UPDATE ON item FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS item_insert_trigger ON item;
|
||||
CREATE TRIGGER item_insert_trigger BEFORE INSERT ON item FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.25.xsd">
|
||||
|
||||
<changeSet author="Sheldan" id="opening-table">
|
||||
<createTable tableName="opening">
|
||||
<column autoIncrement="true" name="id" type="BIGINT">
|
||||
<constraints nullable="false" primaryKey="true" primaryKeyName="pk_opening"/>
|
||||
</column>
|
||||
<column name="user_id" type="VARCHAR(255)">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="description" type="VARCHAR(1024)"/>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
<addForeignKeyConstraint baseColumnNames="user_id" baseTableName="opening" constraintName="fk_opening_user" deferrable="false"
|
||||
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id"
|
||||
referencedTableName="gw2_user" validate="true"/>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS opening_update_trigger ON opening;
|
||||
CREATE TRIGGER opening_update_trigger BEFORE UPDATE ON opening FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS opening_insert_trigger ON opening;
|
||||
CREATE TRIGGER opening_insert_trigger BEFORE INSERT ON opening FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
<changeSet author="Sheldan" id="opening_currency-table">
|
||||
<createTable tableName="opening_currency">
|
||||
<column autoIncrement="true" name="id" type="BIGINT">
|
||||
<constraints nullable="false" primaryKey="true" primaryKeyName="pk_opening_currency"/>
|
||||
</column>
|
||||
<column name="opening_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="currency_id" type="INT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="amount" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<addForeignKeyConstraint baseColumnNames="opening_id" baseTableName="opening_currency"
|
||||
constraintName="fk_opening_currency_opening" deferrable="false"
|
||||
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
|
||||
referencedColumnNames="id" referencedTableName="opening"
|
||||
validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="currency_id" baseTableName="opening_currency"
|
||||
constraintName="fk_opening_currency_currency" deferrable="false"
|
||||
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id"
|
||||
referencedTableName="currency" validate="true"/>
|
||||
</changeSet>
|
||||
<changeSet author="Sheldan" id="opening_item-table">
|
||||
<createTable tableName="opening_item">
|
||||
<column autoIncrement="true" name="id" type="BIGINT">
|
||||
<constraints nullable="false" primaryKey="true" primaryKeyName="pk_opening_item"/>
|
||||
</column>
|
||||
<column name="opening_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="item_id" type="INT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="count" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<addForeignKeyConstraint baseColumnNames="opening_id" baseTableName="opening_item"
|
||||
constraintName="fk_opening_item_opening" deferrable="false"
|
||||
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
|
||||
referencedColumnNames="id" referencedTableName="opening"
|
||||
validate="true"/>
|
||||
<addForeignKeyConstraint baseColumnNames="item_id" baseTableName="opening_item"
|
||||
constraintName="fk_opening_item_item" deferrable="false"
|
||||
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id"
|
||||
referencedTableName="item" validate="true"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,8 @@
|
||||
CREATE OR REPLACE FUNCTION insert_trigger_procedure() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
NEW.created := CURRENT_TIMESTAMP;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
@@ -0,0 +1,8 @@
|
||||
CREATE OR REPLACE FUNCTION update_trigger_procedure() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
NEW.updated := CURRENT_TIMESTAMP;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.25.xsd">
|
||||
|
||||
<changeSet author="Sheldan" id="submission_template-table">
|
||||
<createTable tableName="submission_template">
|
||||
<column autoIncrement="true" name="id" type="BIGINT">
|
||||
<constraints nullable="false" primaryKey="true" primaryKeyName="pk_submission_template"/>
|
||||
</column>
|
||||
<column name="item_id" type="INTEGER">
|
||||
<constraints nullable="false" />
|
||||
</column>
|
||||
<column name="description" type="VARCHAR(1024)"/>
|
||||
<column name="template_text" type="VARCHAR(2048)"/>
|
||||
<column name="name" type="VARCHAR(128)"/>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
<addForeignKeyConstraint baseColumnNames="item_id" baseTableName="submission_template" constraintName="fk_submission_template_item" deferrable="false"
|
||||
initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id"
|
||||
referencedTableName="item" validate="true"/>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS submission_template_update_trigger ON submission_template;
|
||||
CREATE TRIGGER submission_template_update_trigger BEFORE UPDATE ON submission_template FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS submission_template_insert_trigger ON submission_template;
|
||||
CREATE TRIGGER submission_template_insert_trigger BEFORE INSERT ON submission_template FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.25.xsd">
|
||||
<include file="trigger_functions.xml" relativeToChangelogFile="true"/>
|
||||
<include file="item.xml" relativeToChangelogFile="true"/>
|
||||
<include file="currency.xml" relativeToChangelogFile="true"/>
|
||||
<include file="user.xml" relativeToChangelogFile="true"/>
|
||||
<include file="opening.xml" relativeToChangelogFile="true"/>
|
||||
<include file="submission_template.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.25.xsd">
|
||||
<changeSet author="Sheldan" id="insert_trigger" dbms="postgresql">
|
||||
<sqlFile encoding="utf8" path="sql/insert_trigger.sql"
|
||||
relativeToChangelogFile="true"
|
||||
splitStatements="false"/>
|
||||
</changeSet>
|
||||
<changeSet author="Sheldan" id="update_trigger" dbms="postgresql">
|
||||
<sqlFile encoding="utf8" path="sql/update_trigger.sql"
|
||||
relativeToChangelogFile="true"
|
||||
splitStatements="false"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.25.xsd">
|
||||
|
||||
<changeSet author="Sheldan" id="user-table">
|
||||
<createTable tableName="gw2_user">
|
||||
<column name="id" type="VARCHAR(255)">
|
||||
<constraints nullable="false" primaryKey="true"/>
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS gw2_user_update_trigger ON gw2_user;
|
||||
CREATE TRIGGER gw2_user_update_trigger BEFORE UPDATE ON gw2_user FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS gw2_user_insert_trigger ON gw2_user;
|
||||
CREATE TRIGGER gw2_user_insert_trigger BEFORE INSERT ON gw2_user FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.25.xsd">
|
||||
<include file="0.0.1/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
10
gw2-tools-backend/executable/Dockerfile
Normal file
10
gw2-tools-backend/executable/Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM amazoncorretto:21.0.1-alpine3.18
|
||||
RUN apk add entr
|
||||
|
||||
WORKDIR /app
|
||||
ADD BOOT-INF/lib/ /app/lib
|
||||
ADD snapshots/ /app/lib
|
||||
ADD META-INF /app/META-INF
|
||||
ADD BOOT-INF/classes /app
|
||||
|
||||
ENTRYPOINT java -cp .:./lib/* dev.sheldan.gw2.tools.ToolApplicationKt
|
||||
127
gw2-tools-backend/executable/pom.xml
Normal file
127
gw2-tools-backend/executable/pom.xml
Normal file
@@ -0,0 +1,127 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>gw2-tools</artifactId>
|
||||
<version>0.0.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>executable</artifactId>
|
||||
|
||||
<properties>
|
||||
<main.class>dev.sheldan.gw2.tools.ToolApplicationKt</main.class>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<finalName>gw2-tools</finalName>
|
||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>${maven-jar-plugin.version}</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<mainClass>${main.class}</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>${maven-assembly-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals> <goal>single</goal> </goals>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>${main.class}</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>repackage</id>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<classifier>exec</classifier>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>rest-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.gw2.tools
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.runApplication
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
|
||||
|
||||
@SpringBootApplication(exclude = [org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration::class])
|
||||
@EnableJpaRepositories(basePackages = ["dev.sheldan.gw2"])
|
||||
class ToolApplication
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
runApplication<ToolApplication>(*args)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
management.endpoints.web.exposure.include=mappings
|
||||
|
||||
security.basic.enabled=false
|
||||
management.security.enabled=false
|
||||
|
||||
|
||||
spring.datasource.url=jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME}
|
||||
spring.datasource.username= ${DB_USER}
|
||||
spring.datasource.password= ${DB_PASS}
|
||||
spring.datasource.hikari.maximum-pool-size=${hikariPoolSize}
|
||||
spring.jpa.hibernate.default_schema=gw2
|
||||
spring.jpa.properties.hibernate.default_schema=gw2
|
||||
spring.quartz.jdbc.initialize-schema=never
|
||||
management.metrics.tags.application=GW2-Tools
|
||||
management.endpoint.health.probes.enabled=true
|
||||
management.health.livenessState.enabled=true
|
||||
management.health.readinessState.enabled=true
|
||||
spring.application.name=GW2-Tools
|
||||
11
gw2-tools-backend/executable/src/main/resources/logback.xml
Normal file
11
gw2-tools-backend/executable/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] [%-5level] [%logger{36}]: %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
71
gw2-tools-backend/gw2-api-client/pom.xml
Normal file
71
gw2-tools-backend/gw2-api-client/pom.xml
Normal file
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>gw2-tools</artifactId>
|
||||
<version>0.0.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>gw2-api-client</artifactId>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.kryszak</groupId>
|
||||
<artifactId>gwatlin</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>database</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.config
|
||||
|
||||
interface ApiKey {
|
||||
fun getApiKey(): String
|
||||
fun setApiKey(key: String)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package dev.sheldan.gw2.tools.config
|
||||
|
||||
import io.github.kryszak.gwatlin.api.account.GWAccountClient
|
||||
import io.github.kryszak.gwatlin.api.characters.GWCharactersClient
|
||||
import io.github.kryszak.gwatlin.api.items.GWItemsClient
|
||||
import io.github.kryszak.gwatlin.api.miscellaneous.GWMiscellaneousClient
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.context.annotation.ScopedProxyMode
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
|
||||
@Configuration
|
||||
class BeanConfig(val apiKey: ApiKey) {
|
||||
|
||||
@Bean
|
||||
@RequestScope(proxyMode = ScopedProxyMode.DEFAULT)
|
||||
fun gwCharacterClient(): GWCharactersClient {
|
||||
return GWCharactersClient(apiKey.getApiKey())
|
||||
}
|
||||
|
||||
@Bean
|
||||
@RequestScope(proxyMode = ScopedProxyMode.DEFAULT)
|
||||
fun getAccountClient(): GWAccountClient {
|
||||
return GWAccountClient(apiKey.getApiKey())
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun getMiscellaneousClient(): GWMiscellaneousClient {
|
||||
return GWMiscellaneousClient()
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun gwItemClient(): GWItemsClient {
|
||||
return GWItemsClient()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package dev.sheldan.gw2.tools.loader
|
||||
|
||||
import dev.sheldan.gw2.tools.models.*
|
||||
import dev.sheldan.gw2.tools.service.ItemManagement
|
||||
import io.github.kryszak.gwatlin.api.account.GWAccountClient
|
||||
import io.github.kryszak.gwatlin.api.characters.GWCharactersClient
|
||||
import io.github.kryszak.gwatlin.api.miscellaneous.GWMiscellaneousClient
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
|
||||
@Component
|
||||
@RequestScope
|
||||
class AccountLoader(
|
||||
val charClient: GWCharactersClient,
|
||||
val accountClient: GWAccountClient,
|
||||
val miscellaneousClient: GWMiscellaneousClient,
|
||||
val itemManagement: ItemManagement
|
||||
) {
|
||||
fun getCharacters(): List<String>? {
|
||||
return charClient.getCharacters()
|
||||
}
|
||||
|
||||
fun getWallet(): AccountWalletView {
|
||||
val wallet = accountClient.getWallet()
|
||||
val currencies = miscellaneousClient.getCurrencies().associateBy { it.id }
|
||||
val enrichedCurrencies = wallet.mapNotNull { walletCurrency ->
|
||||
val currency = currencies[walletCurrency.id]
|
||||
currency?.let {
|
||||
EnrichedCurrency(walletCurrency.id, walletCurrency.value, it.name, it.description, it.icon)
|
||||
}
|
||||
}
|
||||
return AccountWalletView(enrichedCurrencies)
|
||||
}
|
||||
|
||||
fun getBank(): AccountVaultView {
|
||||
val bank = accountClient.getAccountVault()
|
||||
val itemIds = mutableSetOf<Int>()
|
||||
val items = bank.filterNotNull().mapNotNull {
|
||||
itemIds.add(it.id)
|
||||
EnrichedItem(it.id, it.count, it.boundTo)
|
||||
}
|
||||
val itemStats = itemManagement.getItemsAsMap(itemIds.toList())
|
||||
items.forEach { item ->
|
||||
itemStats[item.id]?.let {
|
||||
item.setValuesFromDbItem(it)
|
||||
}
|
||||
}
|
||||
return AccountVaultView(items)
|
||||
}
|
||||
|
||||
fun getMaterials(): AccountMaterialView{
|
||||
val materials = accountClient.getMaterials()
|
||||
val itemIds = mutableSetOf<Int>()
|
||||
val items = materials
|
||||
.filter { it.count > 0 }
|
||||
.map {
|
||||
|
||||
itemIds.add(it.id)
|
||||
EnrichedItem(it.id, it.count)
|
||||
}
|
||||
val actualMaterials = itemManagement.getItemsAsMap(itemIds.toList())
|
||||
items.forEach { item ->
|
||||
actualMaterials[item.id]?.let {
|
||||
item.setValuesFromDbItem(it)
|
||||
}
|
||||
}
|
||||
return AccountMaterialView(items)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.gw2.tools.loader
|
||||
|
||||
import dev.sheldan.gw2.tools.models.EnrichedCurrency
|
||||
import io.github.kryszak.gwatlin.api.miscellaneous.GWMiscellaneousClient
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class CurrencyLoader(
|
||||
var miscellaneousClient: GWMiscellaneousClient,
|
||||
) {
|
||||
fun getAllCurrencies(): List<EnrichedCurrency> {
|
||||
return miscellaneousClient.getCurrencies().map { EnrichedCurrency(it.id, 0, it.name, it.description, it.icon) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package dev.sheldan.gw2.tools.loader
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.Item
|
||||
import dev.sheldan.gw2.tools.models.*
|
||||
import dev.sheldan.gw2.tools.service.ItemManagement
|
||||
import io.github.kryszak.gwatlin.api.account.GWAccountClient
|
||||
import io.github.kryszak.gwatlin.api.account.model.InventoryItem
|
||||
import io.github.kryszak.gwatlin.api.characters.GWCharactersClient
|
||||
import io.github.kryszak.gwatlin.api.characters.model.character.inventory.Bag
|
||||
import io.github.kryszak.gwatlin.api.characters.model.character.inventory.InventorySlot
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
|
||||
@Component
|
||||
@RequestScope
|
||||
class InventoryLoader(
|
||||
val charClient: GWCharactersClient,
|
||||
val accountClient: GWAccountClient,
|
||||
val itemManagement: ItemManagement
|
||||
) {
|
||||
|
||||
fun getInventory(characterName: String): List<Bag?>? {
|
||||
return charClient.getInventory(characterName)
|
||||
}
|
||||
|
||||
fun getFullCharacterInventory(characterName: String): CharacterInventory {
|
||||
val itemIds = mutableSetOf<Int>()
|
||||
val characterInventory = getCharacterInventory(characterName, itemIds)
|
||||
val itemStats = getFullItemInfos(itemIds)
|
||||
enrichCharacterInventory(characterInventory, itemStats)
|
||||
return characterInventory
|
||||
}
|
||||
|
||||
private fun getCharacterInventory(characterName: String, itemIds: MutableSet<Int>): CharacterInventory {
|
||||
val characterInventory = getInventory(characterName)
|
||||
val convertedBags = mutableListOf<InventoryBag>()
|
||||
characterInventory?.let {
|
||||
for (bag in characterInventory.filterNotNull()) {
|
||||
convertedBags.addLast(convertApiBagToCharacterInventory(bag, itemIds))
|
||||
}
|
||||
}
|
||||
return CharacterInventory(characterName, convertedBags)
|
||||
}
|
||||
|
||||
fun getAccountInventory(): AccountInventoryView {
|
||||
val characters = charClient.getCharacters()
|
||||
val itemIds = mutableSetOf<Int>()
|
||||
val inventories = mutableListOf<CharacterInventory>()
|
||||
for (characterName in characters) {
|
||||
inventories.addLast(getCharacterInventory(characterName, itemIds))
|
||||
}
|
||||
|
||||
val itemStats = getFullItemInfos(itemIds)
|
||||
inventories.forEach { enrichCharacterInventory(it, itemStats) }
|
||||
return AccountInventoryView(inventories)
|
||||
}
|
||||
|
||||
private fun enrichCharacterInventory(characterInventory: CharacterInventory, itemStats: Map<Int, Item>) {
|
||||
return characterInventory.bags.forEach { bag ->
|
||||
bag.items.forEach { item ->
|
||||
itemStats[item.id]?.let {
|
||||
item.setValuesFromDbItem(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertApiBagToCharacterInventory(bag: Bag, itemIds: MutableSet<Int>): InventoryBag {
|
||||
val items = bag.inventory.filterNotNull().map { convertInventorySlot(it, itemIds) }
|
||||
return InventoryBag(bag.id, bag.size, items)
|
||||
}
|
||||
|
||||
private fun convertInventorySlot(slot: InventorySlot, itemIds: MutableSet<Int>): EnrichedItem {
|
||||
itemIds.add(slot.id)
|
||||
return EnrichedItem(slot.id, slot.count, slot.boundTo)
|
||||
}
|
||||
|
||||
private fun convertInventoryItem(item: InventoryItem, itemIds: MutableSet<Int>): EnrichedItem {
|
||||
itemIds.add(item.id)
|
||||
return EnrichedItem(item.id, item.count, item.binding)
|
||||
}
|
||||
|
||||
fun getSharedInventory(): AccountInventory {
|
||||
val itemIds = mutableSetOf<Int>()
|
||||
val sharedInventorySlots = accountClient.getInventory().filterNotNull()
|
||||
val sharedItems = sharedInventorySlots.map { convertInventoryItem(it, itemIds) }
|
||||
val fullItemInfo = getFullItemInfos(itemIds)
|
||||
sharedItems.forEach { item ->
|
||||
fullItemInfo[item.id]?.let {
|
||||
item.setValuesFromDbItem(it)
|
||||
}
|
||||
}
|
||||
return AccountInventory(sharedItems)
|
||||
}
|
||||
|
||||
private fun getFullItemInfos(itemIds: MutableSet<Int>) = itemManagement.getItemsAsMap(itemIds.toList())
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.gw2.tools.loader
|
||||
|
||||
import dev.sheldan.gw2.tools.models.EnrichedItem
|
||||
import io.github.kryszak.gwatlin.api.items.GWItemsClient
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class ItemLoader(
|
||||
val itemClient: GWItemsClient
|
||||
) {
|
||||
fun getAllItems(): List<EnrichedItem> {
|
||||
return itemClient.getItemIds().chunked(200)
|
||||
.flatMap { (itemClient.getItems(it)) }
|
||||
.map {
|
||||
val item = EnrichedItem(it.id, 1)
|
||||
item.setValuesFromItem(it)
|
||||
item
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
class AccountInventory(
|
||||
val slots: List<EnrichedItem>
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
data class AccountInventoryView(
|
||||
val inventories: List<CharacterInventory>
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
class AccountMaterialView(
|
||||
val slots: List<EnrichedItem>
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
class AccountVaultView(
|
||||
val slots: List<EnrichedItem>
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
class AccountWalletView(
|
||||
val currencies: List<EnrichedCurrency>
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
data class CharacterInventory(
|
||||
val name: String,
|
||||
val bags: List<InventoryBag>
|
||||
)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
class EnrichedCurrency(
|
||||
val id: Int,
|
||||
var amount: Int,
|
||||
val name: String,
|
||||
val description: String,
|
||||
val iconUrl: String
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
import io.github.kryszak.gwatlin.api.items.model.item.Item
|
||||
|
||||
data class EnrichedItem(
|
||||
val id: Int,
|
||||
var count: Int,
|
||||
val boundTo: String? = null,
|
||||
|
||||
var iconUrl: String? = null,
|
||||
var name: String? = null,
|
||||
var description: String? = null,
|
||||
var type: Gw2TItemType? = null,
|
||||
var level: Int? = null,
|
||||
var rarity: Gw2TItemRarity? = null
|
||||
) {
|
||||
fun setValuesFromItem(item: Item) {
|
||||
this.name = item.name
|
||||
this.level = item.level
|
||||
this.description = item.description
|
||||
this.type = Gw2TItemType.convertFromAPI(item.type)
|
||||
this.rarity = Gw2TItemRarity.convertFromAPI(item.rarity)
|
||||
this.iconUrl = item.icon.ifBlank { "https://render.guildwars2.com/file/4BC52199DBDEEF5D4D90736B582DDA0F092B0DE4/434780.png" } // default icon if nothing is shown
|
||||
}
|
||||
|
||||
fun setValuesFromDbItem(item: dev.sheldan.gw2.tools.entity.Item) {
|
||||
this.name = item.name
|
||||
this.description = item.description
|
||||
this.type = Gw2TItemType.valueOf(item.type)
|
||||
this.rarity = Gw2TItemRarity.valueOf(item.rarity)
|
||||
this.iconUrl = item.iconUrl
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
import io.github.kryszak.gwatlin.api.items.model.item.ItemRarity
|
||||
|
||||
enum class Gw2TItemRarity {
|
||||
JUNK,
|
||||
BASIC,
|
||||
FINE,
|
||||
MASTERWORK,
|
||||
RARE,
|
||||
EXOTIC,
|
||||
ASCENDED,
|
||||
LEGENDARY;
|
||||
|
||||
companion object {
|
||||
fun convertFromAPI(rarity: ItemRarity): Gw2TItemRarity = when (rarity) {
|
||||
ItemRarity.FINE -> FINE
|
||||
ItemRarity.MASTERWORK -> MASTERWORK
|
||||
ItemRarity.RARE -> RARE
|
||||
ItemRarity.EXOTIC -> EXOTIC
|
||||
ItemRarity.JUNK -> JUNK
|
||||
ItemRarity.BASIC -> BASIC
|
||||
ItemRarity.ASCENDED -> ASCENDED
|
||||
ItemRarity.LEGENDARY -> LEGENDARY
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
import io.github.kryszak.gwatlin.api.items.model.item.ItemType
|
||||
|
||||
enum class Gw2TItemType {
|
||||
CONTAINER,
|
||||
ARMOR,
|
||||
BACK,
|
||||
BAG,
|
||||
CONSUMABLE,
|
||||
CRAFTING_MATERIAL,
|
||||
GATHERING,
|
||||
GIZMO,
|
||||
JADE_TECH_MODULE,
|
||||
KEY,
|
||||
MINI_PET,
|
||||
POWER_CORE,
|
||||
TOOL,
|
||||
TRAIT,
|
||||
TRINKET,
|
||||
TROPHY,
|
||||
UPGRADE_COMPONENT,
|
||||
WEAPON,
|
||||
RELIC;
|
||||
|
||||
companion object {
|
||||
fun convertFromAPI(type: ItemType): Gw2TItemType = when (type) {
|
||||
ItemType.CONTAINER -> CONTAINER
|
||||
ItemType.ARMOR -> ARMOR
|
||||
ItemType.BACK -> BACK
|
||||
ItemType.BAG -> BAG
|
||||
ItemType.CONSUMABLE -> CONSUMABLE
|
||||
ItemType.CRAFTING_MATERIAL -> CRAFTING_MATERIAL
|
||||
ItemType.GATHERING -> GATHERING
|
||||
ItemType.GIZMO -> GIZMO
|
||||
ItemType.JADE_TECH_MODULE -> JADE_TECH_MODULE
|
||||
ItemType.KEY -> KEY
|
||||
ItemType.MINI_PET -> MINI_PET
|
||||
ItemType.POWER_CORE -> POWER_CORE
|
||||
ItemType.TOOL -> TOOL
|
||||
ItemType.TRAIT -> TRAIT
|
||||
ItemType.TRINKET -> TRINKET
|
||||
ItemType.TROPHY -> TROPHY
|
||||
ItemType.UPGRADE_COMPONENT -> UPGRADE_COMPONENT
|
||||
ItemType.WEAPON -> WEAPON
|
||||
ItemType.RELIC -> RELIC
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
data class InventoryBag(
|
||||
val id: Int,
|
||||
val size: Int,
|
||||
val items: List<EnrichedItem>
|
||||
) {
|
||||
}
|
||||
308
gw2-tools-backend/mvnw
vendored
Executable file
308
gw2-tools-backend/mvnw
vendored
Executable file
@@ -0,0 +1,308 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Apache Maven Wrapper startup batch script, version 3.2.0
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /usr/local/etc/mavenrc ] ; then
|
||||
. /usr/local/etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "$(uname)" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
|
||||
else
|
||||
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=$(java-config --jre-home)
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="$(which javac)"
|
||||
if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=$(which readlink)
|
||||
if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="$(dirname "\"$javaExecutable\"")"
|
||||
javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
|
||||
else
|
||||
javaExecutable="$(readlink -f "\"$javaExecutable\"")"
|
||||
fi
|
||||
javaHome="$(dirname "\"$javaExecutable\"")"
|
||||
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=$(cd "$wdir/.." || exit 1; pwd)
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
printf '%s' "$(cd "$basedir" || exit 1; pwd)"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
# Remove \r in case we run on Windows within Git Bash
|
||||
# and check out the repository with auto CRLF management
|
||||
# enabled. Otherwise, we may read lines that are delimited with
|
||||
# \r\n and produce $'-Xarg\r' rather than -Xarg due to word
|
||||
# splitting rules.
|
||||
tr -s '\r\n' ' ' < "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
log() {
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
printf '%s\n' "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
|
||||
log "$MAVEN_PROJECTBASEDIR"
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if [ -r "$wrapperJarPath" ]; then
|
||||
log "Found $wrapperJarPath"
|
||||
else
|
||||
log "Couldn't find $wrapperJarPath, downloading it ..."
|
||||
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||
else
|
||||
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||
fi
|
||||
while IFS="=" read -r key value; do
|
||||
# Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
|
||||
safeValue=$(echo "$value" | tr -d '\r')
|
||||
case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
|
||||
esac
|
||||
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
log "Downloading from: $wrapperUrl"
|
||||
|
||||
if $cygwin; then
|
||||
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
|
||||
fi
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
log "Found wget ... using wget"
|
||||
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||
else
|
||||
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||
fi
|
||||
elif command -v curl > /dev/null; then
|
||||
log "Found curl ... using curl"
|
||||
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
|
||||
else
|
||||
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
|
||||
fi
|
||||
else
|
||||
log "Falling back to using Java to download"
|
||||
javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaSource=$(cygpath --path --windows "$javaSource")
|
||||
javaClass=$(cygpath --path --windows "$javaClass")
|
||||
fi
|
||||
if [ -e "$javaSource" ]; then
|
||||
if [ ! -e "$javaClass" ]; then
|
||||
log " - Compiling MavenWrapperDownloader.java ..."
|
||||
("$JAVA_HOME/bin/javac" "$javaSource")
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
log " - Running MavenWrapperDownloader.java ..."
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
# If specified, validate the SHA-256 sum of the Maven wrapper jar file
|
||||
wrapperSha256Sum=""
|
||||
while IFS="=" read -r key value; do
|
||||
case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
|
||||
esac
|
||||
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ -n "$wrapperSha256Sum" ]; then
|
||||
wrapperSha256Result=false
|
||||
if command -v sha256sum > /dev/null; then
|
||||
if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
|
||||
wrapperSha256Result=true
|
||||
fi
|
||||
elif command -v shasum > /dev/null; then
|
||||
if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
|
||||
wrapperSha256Result=true
|
||||
fi
|
||||
else
|
||||
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
|
||||
echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
|
||||
exit 1
|
||||
fi
|
||||
if [ $wrapperSha256Result = false ]; then
|
||||
echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
|
||||
echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
|
||||
echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
# shellcheck disable=SC2086 # safe args
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
$MAVEN_DEBUG_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
||||
205
gw2-tools-backend/mvnw.cmd
vendored
Normal file
205
gw2-tools-backend/mvnw.cmd
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Apache Maven Wrapper startup batch script, version 3.2.0
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
|
||||
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||
|
||||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %WRAPPER_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
|
||||
SET WRAPPER_SHA_256_SUM=""
|
||||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
|
||||
)
|
||||
IF NOT %WRAPPER_SHA_256_SUM%=="" (
|
||||
powershell -Command "&{"^
|
||||
"$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
|
||||
"If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
|
||||
" Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
|
||||
" Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
|
||||
" Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
|
||||
" exit 1;"^
|
||||
"}"^
|
||||
"}"
|
||||
if ERRORLEVEL 1 goto error
|
||||
)
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% ^
|
||||
%JVM_CONFIG_MAVEN_PROPS% ^
|
||||
%MAVEN_OPTS% ^
|
||||
%MAVEN_DEBUG_OPTS% ^
|
||||
-classpath %WRAPPER_JAR% ^
|
||||
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
|
||||
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
|
||||
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%"=="on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
|
||||
|
||||
cmd /C exit /B %ERROR_CODE%
|
||||
50
gw2-tools-backend/packaging/pom.xml
Normal file
50
gw2-tools-backend/packaging/pom.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>gw2-tools</artifactId>
|
||||
<version>0.0.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>packaging</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<properties>
|
||||
<file.basedir>${project.basedir}/src/main/docker/</file.basedir>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>copy</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactItems>
|
||||
|
||||
<!-- backend jar -->
|
||||
<artifactItem>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>executable</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>exec</classifier>
|
||||
<type>jar</type>
|
||||
<overWrite>true</overWrite>
|
||||
<outputDirectory>${file.basedir}/tools</outputDirectory>
|
||||
<destFileName>app.jar</destFileName>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
8
gw2-tools-backend/packaging/src/main/docker/Dockerfile
Normal file
8
gw2-tools-backend/packaging/src/main/docker/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
||||
FROM amazoncorretto:21.0.1-alpine3.18
|
||||
MAINTAINER Sheldan
|
||||
VOLUME /tmp
|
||||
ADD config/* /config/
|
||||
ADD wrapper/*.sh /
|
||||
RUN chmod +x /start.sh
|
||||
ADD tools/app.jar /app.jar
|
||||
CMD ["/start.sh"]
|
||||
@@ -0,0 +1 @@
|
||||
logging.config=config/logback.xml
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="true" scanPeriod="30 seconds">
|
||||
<property name="LOG_PATH" value="logs"/>
|
||||
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>
|
||||
%d{dd-MM-yyyy HH:mm:ss.SSS} %magenta([%thread]) %highlight(%-5level) %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="logFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
|
||||
<file>${LOG_PATH}/log.log</file>
|
||||
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<Pattern>
|
||||
%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</Pattern>
|
||||
</encoder>
|
||||
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>
|
||||
${LOG_PATH}/archived/log_%d{dd-MM-yyyy}.log
|
||||
</fileNamePattern>
|
||||
<maxHistory>10</maxHistory>
|
||||
<totalSizeCap>1GB</totalSizeCap>
|
||||
</rollingPolicy>
|
||||
|
||||
</appender>
|
||||
|
||||
<logger name="dev.sheldan.gw2" level="INFO"/>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="logFileAppender"/>
|
||||
<appender-ref ref="stdout"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
DEBUG_PARAMS=""
|
||||
if [ "x$REMOTE_DEBUG" = 'xtrue' ]; then
|
||||
DEBUG_PARAMS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
|
||||
echo "Starting with remote debugging on port 5005"
|
||||
fi;
|
||||
java ${DEBUG_PARAMS} -jar app.jar
|
||||
176
gw2-tools-backend/pom.xml
Normal file
176
gw2-tools-backend/pom.xml
Normal file
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>gw2-tools</artifactId>
|
||||
<version>0.0.9-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>gw2-tools</name>
|
||||
<description>Tools for GW2</description>
|
||||
<modules>
|
||||
<module>executable</module>
|
||||
<module>gw2-api-client</module>
|
||||
<module>rest-api</module>
|
||||
<module>packaging</module>
|
||||
<module>database</module>
|
||||
</modules>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:${project.scm.url}</connection>
|
||||
<developerConnection>scm:git:${project.scm.url}</developerConnection>
|
||||
<url>https://github.com/Sheldan/gw2-tools.git</url>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>github</id>
|
||||
<url>https://maven.pkg.github.com/Sheldan/gw2-tools</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
|
||||
<properties>
|
||||
<java.version>21</java.version>
|
||||
<kotlin.version>1.9.21</kotlin.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<kotlin.code.style>official</kotlin.code.style>
|
||||
<kotlin.compiler.jvmTarget>21</kotlin.compiler.jvmTarget>
|
||||
<maven-surefire-plugin.version>3.2.5</maven-surefire-plugin.version>
|
||||
<maven-failsafe-plugin.version>3.2.5</maven-failsafe-plugin.version>
|
||||
<exec-maven-plugin.version>3.1.1</exec-maven-plugin.version>
|
||||
<junit-jupiter-engine.version>5.10.1</junit-jupiter-engine.version>
|
||||
<maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
|
||||
<maven-assembly-plugin.version>3.6.0</maven-assembly-plugin.version>
|
||||
<kotlin-logging.version>2.0.11</kotlin-logging.version>
|
||||
<gwatlin.version>1.9.5</gwatlin.version>
|
||||
<maven-release-plugin.version>2.5.3</maven-release-plugin.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-reflect</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.session</groupId>
|
||||
<artifactId>spring-session-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
|
||||
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<args>
|
||||
<arg>-Xjsr305=strict</arg>
|
||||
</args>
|
||||
<compilerPlugins>
|
||||
<plugin>spring</plugin>
|
||||
<plugin>jpa</plugin>
|
||||
</compilerPlugins>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-allopen</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-noarg</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>${maven-release-plugin.version}</version>
|
||||
<configuration>
|
||||
<scmCommentPrefix>[RELEASE]</scmCommentPrefix>
|
||||
<tagNameFormat>@{project.version}</tagNameFormat>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test-junit5</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit-jupiter-engine.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.kryszak</groupId>
|
||||
<artifactId>gwatlin</artifactId>
|
||||
<version>${gwatlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.microutils</groupId>
|
||||
<artifactId>kotlin-logging-jvm</artifactId>
|
||||
<version>${kotlin-logging.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
</project>
|
||||
79
gw2-tools-backend/rest-api/pom.xml
Normal file
79
gw2-tools-backend/rest-api/pom.xml
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>gw2-tools</artifactId>
|
||||
<version>0.0.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>rest-api</artifactId>
|
||||
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${maven-failsafe-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>gw2-api-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>database</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.microutils</groupId>
|
||||
<artifactId>kotlin-logging-jvm</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,4 @@
|
||||
package dev.sheldan.gw2.tools
|
||||
|
||||
class ItemNotFoundException(message: String): Throwable(message) {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import dev.sheldan.gw2.tools.loader.AccountLoader
|
||||
import dev.sheldan.gw2.tools.models.AccountMaterialView
|
||||
import dev.sheldan.gw2.tools.models.AccountVaultView
|
||||
import dev.sheldan.gw2.tools.models.AccountWalletView
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
|
||||
@RestController
|
||||
@RequestScope
|
||||
class AccountController(var accountLoader: AccountLoader) {
|
||||
@GetMapping("/characters")
|
||||
fun inventory(): List<String>? {
|
||||
return accountLoader.getCharacters()
|
||||
}
|
||||
|
||||
@GetMapping("/wallet")
|
||||
fun wallet(): AccountWalletView {
|
||||
return accountLoader.getWallet()
|
||||
}
|
||||
|
||||
@GetMapping("/bank")
|
||||
fun bank(): AccountVaultView {
|
||||
return accountLoader.getBank()
|
||||
}
|
||||
|
||||
@GetMapping("/materials")
|
||||
fun materials(): AccountMaterialView {
|
||||
return accountLoader.getMaterials()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import dev.sheldan.gw2.tools.service.CacheService
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
class CurrencyController(val cacheService: CacheService) {
|
||||
|
||||
@PostMapping("/currency-cache")
|
||||
fun updateCurrencyCache() {
|
||||
cacheService.reloadCurrencyCache()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
class Health {
|
||||
@GetMapping("/health-check")
|
||||
fun healCheck(): String {
|
||||
return "yes"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import dev.sheldan.gw2.tools.loader.InventoryLoader
|
||||
import dev.sheldan.gw2.tools.models.AccountInventory
|
||||
import dev.sheldan.gw2.tools.models.AccountInventoryView
|
||||
import dev.sheldan.gw2.tools.models.CharacterInventory
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
|
||||
@RestController
|
||||
@RequestScope
|
||||
class InventoryController(var inventoryLoader: InventoryLoader) {
|
||||
|
||||
@GetMapping("/inventory/{name}")
|
||||
fun characterInventory(@PathVariable("name") characterName: String): CharacterInventory {
|
||||
return inventoryLoader.getFullCharacterInventory(characterName)
|
||||
}
|
||||
|
||||
@GetMapping("/inventory")
|
||||
fun completeCharacterInventory(): AccountInventoryView {
|
||||
return inventoryLoader.getAccountInventory()
|
||||
}
|
||||
|
||||
@GetMapping("/sharedInventory")
|
||||
fun accountInventory(): AccountInventory {
|
||||
return inventoryLoader.getSharedInventory()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import dev.sheldan.gw2.tools.service.CacheService
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
class ItemController(val cacheService: CacheService) {
|
||||
|
||||
@PostMapping("/item-cache")
|
||||
fun updateItemCache() {
|
||||
cacheService.reloadItemCache()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import dev.sheldan.gw2.tools.config.ApiKeyInterceptor
|
||||
import dev.sheldan.gw2.tools.model.ItemRates
|
||||
import dev.sheldan.gw2.tools.model.OpeningRequest
|
||||
import dev.sheldan.gw2.tools.model.OpeningsView
|
||||
import dev.sheldan.gw2.tools.service.OpeningService
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
|
||||
@RestController
|
||||
@RequestScope
|
||||
class OpeningController(val openingService: OpeningService) {
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
@PostMapping("/openings")
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
fun createOpenings(request: HttpServletRequest, @RequestBody openingRequest: OpeningRequest) {
|
||||
val apiKey: String = request.getHeader(ApiKeyInterceptor.API_KEY_HEADER_NAME) ?: throw IllegalArgumentException("API key not provided.")
|
||||
openingService.createOpening(openingRequest, apiKey)
|
||||
}
|
||||
|
||||
@GetMapping("/openings")
|
||||
fun getOpenings(request: HttpServletRequest, @RequestParam("showOwnOnly") ownOnly: String?): OpeningsView {
|
||||
val apiKey: String? = request.getHeader(ApiKeyInterceptor.API_KEY_HEADER_NAME)
|
||||
val showOnOnly = ownOnly.toBoolean()
|
||||
logger.info { "Retrieving openings" }
|
||||
val loadedOpenings = openingService.loadOpenings(apiKey, showOnOnly)
|
||||
logger.info { "Loaded ${loadedOpenings.openings.size} openings" }
|
||||
return loadedOpenings
|
||||
}
|
||||
|
||||
@DeleteMapping("/openings/{id}")
|
||||
fun deleteOpening(request: HttpServletRequest, @PathVariable("id") openingId: Int) {
|
||||
val apiKey: String = request.getHeader(ApiKeyInterceptor.API_KEY_HEADER_NAME) ?: throw IllegalArgumentException("API key not provided.")
|
||||
openingService.deleteOpening(apiKey, openingId)
|
||||
}
|
||||
|
||||
@GetMapping("/itemRates")
|
||||
fun getItemRates(): ItemRates {
|
||||
return openingService.loadItemRates()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package dev.sheldan.gw2.tools.api
|
||||
|
||||
import dev.sheldan.gw2.tools.ItemNotFoundException
|
||||
import dev.sheldan.gw2.tools.service.SubmissionTemplateService
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.*
|
||||
|
||||
@RestController
|
||||
class SubmissionTemplateController(
|
||||
val submissionTemplateService: SubmissionTemplateService
|
||||
) {
|
||||
@GetMapping("/submissionTemplates")
|
||||
@ResponseBody
|
||||
fun getSubmissionTemplatesForItem(@RequestParam("itemId") itemId: Int?): ResponseEntity<Any> {
|
||||
try {
|
||||
val responseObj = itemId?.let { submissionTemplateService.getSubmissionTemplateForItem(itemId) } ?: submissionTemplateService.getSubmissionTemplates()
|
||||
return ResponseEntity(responseObj, HttpStatus.OK)
|
||||
} catch (e: ItemNotFoundException) {
|
||||
return ResponseEntity(e.message, HttpStatus.BAD_REQUEST)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.gw2.tools.config
|
||||
|
||||
open class ApiKeyContainer : ApiKey {
|
||||
var apiKeyValue: String = "";
|
||||
override fun getApiKey(): String {
|
||||
return apiKeyValue
|
||||
}
|
||||
|
||||
override fun setApiKey(key: String) {
|
||||
this.apiKeyValue = key
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.sheldan.gw2.tools.config
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.servlet.http.HttpServletResponse
|
||||
import org.springframework.web.servlet.HandlerInterceptor
|
||||
|
||||
class ApiKeyInterceptor(private val apiKeyContainer: ApiKey) : HandlerInterceptor {
|
||||
|
||||
companion object {
|
||||
const val API_KEY_HEADER_NAME = "api-key"
|
||||
}
|
||||
|
||||
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
|
||||
val apiKey: String? = request.getHeader(API_KEY_HEADER_NAME)
|
||||
apiKey?.let { apiKeyContainer.setApiKey(it) }
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package dev.sheldan.gw2.tools.config
|
||||
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||
|
||||
|
||||
@Configuration
|
||||
class HeaderInterceptorConfig : WebMvcConfigurer {
|
||||
override fun addInterceptors(registry: InterceptorRegistry) {
|
||||
registry.addInterceptor(apiKeyInterceptor())
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun apiKeyInterceptor(): ApiKeyInterceptor {
|
||||
return ApiKeyInterceptor(apiContainer())
|
||||
}
|
||||
|
||||
@Bean
|
||||
@RequestScope
|
||||
fun apiContainer(): ApiKeyContainer {
|
||||
return ApiKeyContainer()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
|
||||
data class DisplayOpeningItem(val itemId: Int, val change: Int, val itemType: OpeningItemType) {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
class ItemDisplay(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val iconUrl: String,
|
||||
val description: String,
|
||||
val rarity: String
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.sheldan.gw2.tools.model
|
||||
|
||||
import dev.sheldan.gw2.tools.models.EnrichedCurrency
|
||||
import dev.sheldan.gw2.tools.models.EnrichedItem
|
||||
|
||||
class ItemRate(val item: EnrichedItem, val receivedItems: List<EnrichedItem>, val receivedCurrencies: List<EnrichedCurrency>) {
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user