diff --git a/.gitea/workflows/demo.yaml b/.gitea/workflows/demo.yaml new file mode 100644 index 0000000..5427e9c --- /dev/null +++ b/.gitea/workflows/demo.yaml @@ -0,0 +1,19 @@ +name: Gitea Actions Demo +run-name: ${{ gitea.actor }} ist testing out Gitea Actions +on: [push] + +jobs: + Explore-Gitea-Actions: + runs-on: inky + steps: + - run: echo "The job was automatically triggered by a ${{ gitea.event_name }} event." + - run: echo "This job is now running on a ${{ runner.os }} server hosted by Gitea!" + - run: echo "The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}." + - name: Check out repository code + uses: actions/checkout@v4 + - run: echo "The ${{ gitea.repository }} repository has been cloned to the runner." + - run: echo "The workflow is now ready to test your code on the runner." + - name: List files in the directory + run: | + ls ${{ gitea.workspace }} + - run: echo "The job's status is ${{ job.status }}." diff --git a/.gitignore b/.gitignore index 391abfa..1931931 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,8 @@ node_modules/ .editorconfig db-password.txt couchdb-password.txt +kontor-robyn/kontor.db +kontor-robyn.bak +kontor-robyn.bak2 +kontor-data/.gradle +kontor-data/build/ diff --git a/compose-postgres.yaml b/compose-postgres.yaml deleted file mode 100644 index 11ec0e0..0000000 --- a/compose-postgres.yaml +++ /dev/null @@ -1,38 +0,0 @@ -services: - postgres: - image: postgres - restart: unless-stopped - environment: - - POSTGRES_DB=kontor - - POSTGRES_USER=kontor - #- POSTGRES_PASSWORD_FILE=/run/secrets/db-password - - POSTGRES_PASSWORD=kontor - healthcheck: - test: ["CMD-SHELL", "pg_isready -U kontor"] - interval: 1s - timeout: 5s - retries: 10 - ports: - - 5432:5432 - networks: - - database - volumes: - - postgres-data:/var/lib/postgresql/data:rw - secrets: - - db-password - adminer: - image: adminer - ports: - - 8090:8080 - networks: - - database - - frontend -volumes: - postgres-data: -secrets: - db-password: - file: db-password.txt -networks: - database: - name: database - external: true diff --git a/deploy-kontor.sh b/deploy-kontor.sh new file mode 100755 index 0000000..d5a018b --- /dev/null +++ b/deploy-kontor.sh @@ -0,0 +1,12 @@ +# Posted by barth, modified by community. See post 'Timeline' for change history +# Retrieved 2026-08-19, License - CC BY-SA 4.0 +NEXUS_URL=https://nexus.thpeetz.de +MAVEN_REPO=maven-snapshots +GROUP_ID=de.thpeetz +ARTIFACT_ID=kontor-spring +VERSION=0.3.0-SNAPSHOT +FILE_EXTENSION=jar + +download_url=$(curl -X GET "${NEXUS_URL}/service/rest/v1/search/assets?repository=${MAVEN_REPO}&maven.groupId=${GROUP_ID}&maven.artifactId=${ARTIFACT_ID}&maven.baseVersion=${VERSION}&maven.extension=${FILE_EXTENSION}" -H "accept: application/json" | jq -rc '.items | .[].downloadUrl' | sort | tail -n 1) +wget $download_url + diff --git a/docker-compose.yml b/docker-compose.yml index 1de4dc6..f075ac7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,62 +1,5 @@ -include: - - ./compose-postgres.yaml services: - activemq: - image: apache/activemq-artemis:latest-alpine - restart: unless-stopped - ports: - - 61616:61616 - - 8161:8161 - - 5672:5672 - networks: - - integration - - frontend - volumes: - - activemq-data:/var/lib/artemis-instance - kontor: - build: - context: ./kontor-spring - dockerfile: Dockerfile - tags: - - kontor:0.2.0-SNAPSHOT - image: kontor:0.2.0-SNAPSHOT - restart: unless-stopped - networks: - - database - - integration - - frontend - ports: - - 8100:8100 - volumes: - - images-data:/data/images - depends_on: - postgres: - condition: service_healthy - kontor-api: - build: - context: ./kontor-api - dockerfile: Dockerfile - tags: - - kontor-api:0.2.0-SNAPSHOT - image: kontor-api:0.2.0-SNAPSHOT - restart: unless-stopped - healthcheck: - test: ["CMD", "curl", "-f", "http://kontor-api:8500/health"] - interval: 10s - timeout: 5s - retries: 3 - networks: - - database - - integration - - frontend - ports: - - 8500:8500 - volumes: - - images-data:/data/images - depends_on: - postgres: - condition: service_healthy kontor-fiber: build: context: ./kontor-fiber diff --git a/go/.env b/go/.env deleted file mode 100644 index 33a4c5f..0000000 --- a/go/.env +++ /dev/null @@ -1,10 +0,0 @@ -APP_NAME="Kontor" -APP_VERSION="v0.1.0" - -# HTTP Response Content-Type Header - Success -HTTP_CONTENT_TYPE="application/vnd.api+json" - -# HTTP Response Content-Type Header - Error -HTTP_PROBLEM="application/problem+json" - -HTTP_PORT=":8086" diff --git a/go/.gitignore b/go/.gitignore deleted file mode 100644 index 0303555..0000000 --- a/go/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -.gradle/ -docs/build/ -bin/ -build/ -cover.out -coverage.html -coverage.xml -.settings/ -.project diff --git a/go/.gitlab-ci.yml b/go/.gitlab-ci.yml deleted file mode 100644 index 1580961..0000000 --- a/go/.gitlab-ci.yml +++ /dev/null @@ -1,116 +0,0 @@ -variables: - GRADLE_OPTS: "-Dorg.gradle.daemon=false" - -before_script: - - source "/home/gitlab-runner/.sdkman/bin/sdkman-init.sh" - - sdk update - - sdk d java 11.0.12-open - -stages: -- environment -- prepare -- build -- test -- analysis -- deploy - -environment: - stage: environment - script: - - echo "PATH=$PATH:/usr/local/go/bin:/home/gitlab-runner/go/bin" >> build.env - artifacts: - reports: - dotenv: build.env - -Prepare Go dependencies: - stage: prepare - script: - - go get -u github.com/spf13/cobra - - go get -u github.com/jstemmer/go-junit-report - - go get -u github.com/inconshreveable/mousetrap - - go get -u github.com/mitchellh/go-homedir - - go get github.com/boumenot/gocover-cobertura - - go get -u gotest.tools/gotestsum - - go get -u github.com/cryptix/wav - - go get -u golang.org/x/lint/golint - dependencies: - - environment - -Create Documentation: - stage: build - script: - - chmod +x docs/gradlew - - cd docs; ./gradlew publish - -Compile Go Application: - stage: build - script: make build - -Test Go Application: - stage: test - script: - - gotestsum --junitfile report.xml --format testname -- -coverprofile=coverage.txt -covermode count ./... - - go vet ./... 2> govet-report.out - - gocover-cobertura < coverage.txt > coverage.xml - - golint ./... > golint-report.out - dependencies: - - environment - artifacts: - when: always - paths: - - coverage.xml - - report.xml - reports: - junit: report.xml - coverage_report: - coverage_format: cobertura - path: coverage.xml - -Code analysis: - stage: analysis - script: - - go test -coverprofile cover.out ./... -json > report.json - - go vet ./... 2> govet-report.out - - golint ./... > golint-report.out - - echo "sonar.projectKey=kontor_kontor-go_AX-cQT62rXuu6JVRvr-z" >> sonar-project.properties - - echo "sonar.sources=." >> sonar-project.properties - - echo "sonar.exclusions=**/*_test.go" >> sonar-project.properties - - echo "sonar.tests=." >> sonar-project.properties - - echo "sonar.test.inclusions=**/*_test.go" >> sonar-project.properties - - echo "sonar.go.tests.reportPaths=report.json" >> sonar-project.properties - - echo "sonar.go.coverage.reportPaths=cover.out" >> sonar-project.properties - - echo "sonar.go.govet.reportPaths=govet-report.out" >> sonar-project.properties - - echo "sonar.go.golint.reportPaths=golint-report.out" >> sonar-project.properties - - /data/sonar-scanner/bin/sonar-scanner -Dsonar.projectVersion=$(git describe --abbrev=0) -Dsonar.host.url=https://sonar.thpeetz.de -Dsonar.login=319616a2761ac3e96a1c7aacc54976bfff4096a9 - dependencies: - - environment - -Deploy To Staging: - stage: deploy - script: - - make build - - ssh kontor /home/kontor/kontor-test_service stop - - rsync -av templates kontor:/home/kontor/staging - - rsync -av bin/kontor kontor:/home/kontor/staging - - ssh kontor /home/kontor/kontor-test_service start - environment: - name: staging - url: https://kontor-test.thpeetz.de - only: - - main - -Deploy to Production: - stage: deploy - script: - - make build - - sudo service kontor stop - - rsync -av templates kontor:/home/kontor/production - - rsync -av bin/kontor kontor:/home/kontor/production - - sudo service kontor start - environment: - name: production - url: https://kontor.thpeetz.de - - only: - - main - when: manual diff --git a/go/Makefile b/go/Makefile deleted file mode 100644 index 7f29013..0000000 --- a/go/Makefile +++ /dev/null @@ -1,73 +0,0 @@ -# Go parameters -GOPATH=$(HOME)/go -#GOBIN=$(shell pwd)/bin -GOBIN=/usr/local/go/bin -GOCMD=$(GOBIN)/go -GOGET=$(GOCMD) get -GOBUILD=$(GOCMD) build -GOCLEAN=$(GOCMD) clean -GOTEST=$(GOCMD) test -GOCOVER=$(GOCMD) tool cover -COBERTURA=$(HOME)/go/bin/gocover-cobertura -GOLINT=$(GOBIN)/golint -GOVET=$(GOCMD) vet - -# Project parameters -GONAME=kontor -GOFILE=cmd/kontor/main.go - -#.PHONY: all deps clean clean-bin clean-doc - -all: deps build - -deps: - $(GOGET) -u -v github.com/jstemmer/go-junit-report - $(GOGET) -u -v github.com/tebeka/go2xunit - $(GOGET) -u -v github.com/t-yuki/gocover-cobertura - $(GOGET) -u -v github.com/spf13/cobra/cobra - $(GOGET) -u -v github.com/inconshreveable/mousetrap - $(GOGET) -u -v github.com/mitchellh/go-homedir - $(GOGET) -u -v github.com/golang/protobuf/proto - $(GOGET) -u -v github.com/gin-gonic/gin - $(GOGET) -u -v github.com/gin-gonic/gin/binding - $(GOGET) -u -v github.com/gin-gonic/gin/render - $(GOGET) -u -v github.com/gin-contrib/sse - $(GOGET) -u -v github.com/mattn/go-isatty - $(GOGET) -u -v github.com/ugorji/go/codec - $(GOGET) -u -v golang.org/x/crypto/bcrypt - $(GOGET) -u -v golang.org/x/crypto/blowfish - G$(GOGET) -u -v gopkg.in/yaml.v2 - $(GOGET) -u -v gopkg.in/mgo.v2 - $(GOGET) -u -v gopkg.in/mgo.v2/bson - -build: bin/$(GONAME) - -bin/$(GONAME): $(GOFILE) - @echo "Building $(GOFILE) to ./bin" - $(GOBUILD) -v -ldflags="-X main.version=$(shell git describe --always --long --dirty)" -o bin/$(GONAME) $(GOFILE) - -install: - @echo using $(GOPATH) - $(GOCMD) install -v -ldflags="-X main.version=$(shell git describe --always --long --dirty)" ./... - -test: - $(GOTEST) -v ./... - $(GOTEST) -coverprofile=cover.out ./... - $(GOCOVER) -html=cover.out -o coverage.html - $(COBERTURA) < cover.out > coverage.xml - $(GOLINT) ./... - $(GOVET) -v ./... - -doc: - cd docs; ./gradlew build - -clean: clean-doc clean-bin - - -clean-doc: - @echo "Cleaning Gradle build" - cd docs; ./gradlew clean - -clean-bin: - @echo "Cleaning Go build" - rm -rf bin/ diff --git a/go/README.md b/go/README.md deleted file mode 100644 index 6814615..0000000 --- a/go/README.md +++ /dev/null @@ -1,4 +0,0 @@ -[![pipeline status](https://gitlab.thpeetz.de/kontor/kontor-go/badges/master/pipeline.svg)](https://gitlab.thpeetz.de/kontor/kontor-go/commits/master) -[![coverage report](https://gitlab.thpeetz.de/kontor/kontor-go/badges/master/coverage.svg)](https://gitlab.thpeetz.de/kontor/kontor-go/commits/master) - -# Kontor diff --git a/go/cmd/kontor/main.go b/go/cmd/kontor/main.go deleted file mode 100644 index c2dbeeb..0000000 --- a/go/cmd/kontor/main.go +++ /dev/null @@ -1,36 +0,0 @@ -package main - -import ( - "database/sql" - "log" - "time" - - _ "github.com/go-sql-driver/mysql" -) - -func main() { - connectionString := "kontor:kontor@tcp(127.0.0.1:3306)/kontor?parseTime=true" - db, err := sql.Open("mysql", connectionString) - if err != nil { - log.Printf("setup database error: %v", err) - return - } - db.SetConnMaxLifetime(time.Minute * 3) - db.SetMaxOpenConns(10) - db.SetMaxIdleConns(10) - log.Println("Database connected") - - rows, err := db.Query("SELECT id, created_date, last_modified_date, version, url, title, review FROM media_file") - if err != nil { - log.Fatal((err.Error())) - } - defer rows.Close() - var rec MediaFile - for rows.Next() { - err = rows.Scan(&rec.ID, &rec.CreatedDate, &rec.LastModifiedDate, &rec.Version, &rec.Url, &rec.Title, &rec.Review) - if err != nil { - log.Fatal(err.Error()) - } - log.Println(rec, string(rec.Url), string(rec.Title)) - } -} diff --git a/go/cmd/kontor/model.go b/go/cmd/kontor/model.go deleted file mode 100644 index b7634c5..0000000 --- a/go/cmd/kontor/model.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "time" - - "github.com/google/uuid" -) - -type AbstractEntity struct { - ID uuid.UUID `gorm:"type:uuid;primary_key" json:"id"` - Version uint `json:"version"` - CreatedDate time.Time `json:"createdDate"` - LastModifiedDate time.Time `json:"lastModifiedDate"` -} - -type MediaFile struct { - AbstractEntity - Url []byte `json:"url"` - Review []uint8 `json:"review"` - ShouldDownload []uint8 `json:"shouldDownload"` - Title []byte `json:"title"` - CloudLink string `json:"cloudLink"` - FileName string `json:"fileName"` - Path string `json:"path"` -} diff --git a/go/cmd/root.go b/go/cmd/root.go deleted file mode 100644 index 9a1c5e2..0000000 --- a/go/cmd/root.go +++ /dev/null @@ -1,89 +0,0 @@ -package cmd - -import ( - "fmt" - "log" - "os" - - "gitlab.thpeetz.de/kontor/kontor-go/pkg/properties" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/setup" - - "github.com/gin-gonic/gin" - "github.com/spf13/cobra" -) - -var ( - // Verbose defines the parameter verbose. - Verbose bool - // Version defines the version of the web application. - Version string - // Debug defines the debug parameter. - Debug bool - // Port defines the parameter port. - Port int - // TemplatesDir defines the root directory of template files. - TemplatesDir string - router *gin.Engine -) - -var rootCmd = &cobra.Command{ - Use: "kontor", - Short: "kontor", - Long: `kontor`, - Run: func(cmd *cobra.Command, args []string) { - // Set Gin to production mode - if Debug { - gin.SetMode(gin.DebugMode) - } else { - gin.SetMode(gin.ReleaseMode) - } - log.SetOutput(gin.DefaultWriter) - - // Set the router as the default one provided by Gin - router = gin.Default() - - // Process the templates at the start so that they don't have to be loaded - // from the disk again. This makes serving HTML pages very fast. - templatesDir := fmt.Sprintf("%s/**/*", TemplatesDir) - log.Printf("load template files from %v", templatesDir) - router.LoadHTMLGlob(templatesDir) - - // Use Middleware logger - router.Use(gin.Logger()) - - // Initialize the routes - setup.InitializeRoutes(router) - - // Clean up SetSessionStatus - setup.CleanupSessions() - - // Check if at least one user configured - setup.CheckUserList() - - // Check if data for TradeYourSportsCards is available - setup.CheckTradeYourSportsCardsData() - - //properties.SetVersion(Version) - - // Start serving the application - server := fmt.Sprintf("127.0.0.1:%d", Port) - router.Run(server) - }, -} - -// Execute parses the commandline and calls Execute on rootCmd. -func Execute(version string) { - rootCmd.Version = version - properties.SetVersion(version) - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } -} - -func init() { - rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output") - rootCmd.PersistentFlags().BoolVarP(&Debug, "debug", "d", false, "debug modus") - rootCmd.PersistentFlags().IntVarP(&Port, "port", "p", 8500, "port number") - rootCmd.PersistentFlags().StringVarP(&TemplatesDir, "templates", "t", "templates", "path for template files") -} diff --git a/go/cmd/server.go b/go/cmd/server.go deleted file mode 100644 index 3b7ebd0..0000000 --- a/go/cmd/server.go +++ /dev/null @@ -1,32 +0,0 @@ -package main - -import ( - "github.com/joho/godotenv" - application "gitlab.com/tpeetz-kontor/kontor-go/pkg/infrastructure/app" - "gitlab.com/tpeetz-kontor/kontor-go/pkg/infrastructure/kernel" -) - -// init is invoked before main() -func init() { - // loads values from .env into the system - if err := godotenv.Load(); err != nil { - panic("No .env file found") - } -} - -func main() { - // Create our application - app := kernel.Boot() - - // Build our services - //ping.BuildPingService(app) - - // Run our Application in a coroutine - go func() { - app.Run() - }() - - // Wait for termination signals and shut down gracefully - application.WaitForShutdown(app) - -} diff --git a/go/comics.xml b/go/comics.xml deleted file mode 100644 index 730fdeb..0000000 --- a/go/comics.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/go/docs/build.gradle b/go/docs/build.gradle deleted file mode 100644 index 9f27a44..0000000 --- a/go/docs/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -plugins { - alias(versionsLibs.plugins.asciidoctorConvention) -} - -wrapper { - gradleVersion = "7.5" -} diff --git a/go/docs/gradle.properties b/go/docs/gradle.properties deleted file mode 100644 index aeb4e86..0000000 --- a/go/docs/gradle.properties +++ /dev/null @@ -1,2 +0,0 @@ -description='Documentation for application kontor-go' -version=1.0.0-SNAPSHOT diff --git a/go/docs/gradle/wrapper/gradle-wrapper.jar b/go/docs/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e583..0000000 Binary files a/go/docs/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/go/docs/gradle/wrapper/gradle-wrapper.properties b/go/docs/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 8049c68..0000000 --- a/go/docs/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/go/docs/gradlew b/go/docs/gradlew deleted file mode 100755 index a69d9cb..0000000 --- a/go/docs/gradlew +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed 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. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -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 - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/go/docs/gradlew.bat b/go/docs/gradlew.bat deleted file mode 100644 index 53a6b23..0000000 --- a/go/docs/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem 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, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/go/docs/settings.gradle b/go/docs/settings.gradle deleted file mode 100644 index b956775..0000000 --- a/go/docs/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name='kontor-go' diff --git a/go/docs/src/docs/asciidoc/kontor-go.adoc b/go/docs/src/docs/asciidoc/kontor-go.adoc deleted file mode 100644 index 5334cfb..0000000 --- a/go/docs/src/docs/asciidoc/kontor-go.adoc +++ /dev/null @@ -1,31 +0,0 @@ -= Projektbeschreibung Kontor -:author: Thomas Peetz -:email: -:doctype: article -:toc: left -:sectnums: - -== Einführung - -=== Zweck - -== Anforderungen - -== Implementierung - -=== Datenmodell - -== Betrieb - -[bibliography] -== Referenzen - -- [[[1]]] Thomas Peetz, Betriebshandbuch IBTP - -[index] -== Index - -== Tabellenverzeichnis - -[glossary] -== Glossar diff --git a/go/go.mod b/go/go.mod deleted file mode 100644 index cc805de..0000000 --- a/go/go.mod +++ /dev/null @@ -1,28 +0,0 @@ -module gitlab.com/tpeetz-kontor/kontor-go - -go 1.22.2 - -require github.com/joho/godotenv v1.5.1 - -require ( - github.com/felixge/httpsnoop v1.0.3 // indirect - go.uber.org/multierr v1.10.0 // indirect -) - -require ( - filippo.io/edwards25519 v1.1.0 // indirect - github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect - github.com/go-sql-driver/mysql v1.8.1 // indirect - github.com/google/uuid v1.6.0 - github.com/gorilla/handlers v1.5.2 - github.com/gorilla/mux v1.8.1 - github.com/jinzhu/gorm v1.9.16 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.5 // indirect - github.com/satori/go.uuid v1.2.0 // indirect - go.uber.org/zap v1.27.0 - golang.org/x/text v0.19.0 // indirect - golang.org/x/tools v0.21.1-0.20240531212143-b6235391adb3 // indirect - gorm.io/driver/mysql v1.5.7 // indirect - gorm.io/gorm v1.25.12 // indirect -) diff --git a/go/go.sum b/go/go.sum deleted file mode 100644 index 3d35401..0000000 --- a/go/go.sum +++ /dev/null @@ -1,62 +0,0 @@ -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs= -github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= -github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= -github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= -github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= -github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= -github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= -github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= -github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= -github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/tools v0.21.1-0.20240531212143-b6235391adb3 h1:SHq4Rl+B7WvyM4XODon1LXtP7gcG49+7Jubt1gWWswY= -golang.org/x/tools v0.21.1-0.20240531212143-b6235391adb3/go.mod h1:bqv7PJ/TtlrzgJKhOAGdDUkUltQapRik/UEHubLVBWo= -gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= -gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= -gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= -gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8= -gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= -honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I= -honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs= diff --git a/go/kontor-ansible.yml b/go/kontor-ansible.yml deleted file mode 100644 index 2e19328..0000000 --- a/go/kontor-ansible.yml +++ /dev/null @@ -1,58 +0,0 @@ ---- -# file: kontor-ansible.yml -- hosts: localhost - remote_user: root - tasks: - - name: create group kontor - group: - name: kontor - state: present - - - name: create user kontor - user: - name: kontor - home: /home/kontor - shell: /bin/bash - state: present - # generate_ssh_key: yes - # ssh_key_bits: 4096 - # ssh_key_file: .ssh/id_rsa - - - name: create log directory - file: - path: /var/log/kontor - state: directory - owner: kontor - group: kontor - mode: 0775 - recurse: true - - - name: create run directory - file: - path: /var/run/kontor - state: directory - owner: kontor - group: kontor - mode: 0775 - recurse: true - - - name: create directory - file: - path: /home/kontor/production - state: directory - owner: kontor - group: kontor - mode: 0775 - recurse: false - - - name: copy binary - copy: - src: bin/kontor - dest: /home/kontor/production/kontor - mode: 0775 - - - name: copy templates - copy: - src: templates - dest: /home/kontor/production/kontor/templates - mode: 0775 diff --git a/go/pkg/admin/routes.go b/go/pkg/admin/routes.go deleted file mode 100644 index a4845cf..0000000 --- a/go/pkg/admin/routes.go +++ /dev/null @@ -1,23 +0,0 @@ -package admin - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/auth" - - "github.com/gin-gonic/gin" -) - -// GetRoutes sets the routes for the administrative data urls. -func GetRoutes(router *gin.Engine) { - adminRoutes := router.Group("/admin") - { - adminRoutes.GET("/", auth.EnsureLoggedIn(), auth.EnsureAdminStatus(), showAdminIndex) - adminRoutes.GET("/user", auth.EnsureLoggedIn(), auth.EnsureAdminStatus(), showUserIndex) - adminRoutes.POST("/user", auth.EnsureLoggedIn(), auth.EnsureAdminStatus(), showUserIndex) - adminRoutes.GET("/user/view/:userid", auth.EnsureLoggedIn(), auth.EnsureAdminStatus(), showUserDetails) - adminRoutes.POST("/user/view", auth.EnsureLoggedIn(), auth.EnsureAdminStatus(), validateUserCreation) - adminRoutes.GET("/user/create", auth.EnsureLoggedIn(), auth.EnsureAdminStatus(), showUserCreation) - adminRoutes.POST("/user/create", auth.EnsureLoggedIn(), auth.EnsureAdminStatus(), validateUserCreation) - adminRoutes.GET("/data", auth.EnsureLoggedIn(), auth.EnsureAdminStatus(), showDataUpload) - adminRoutes.POST("/data", auth.EnsureLoggedIn(), auth.EnsureAdminStatus(), validateDataUpload) - } -} diff --git a/go/pkg/admin/user.go b/go/pkg/admin/user.go deleted file mode 100644 index 8d94a06..0000000 --- a/go/pkg/admin/user.go +++ /dev/null @@ -1,18 +0,0 @@ -package admin - -import ( - "gopkg.in/mgo.v2/bson" -) - -// User defines the data model for application users with id,email, user name, -// first and family name, password and admin status. -type User struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Email string `json:"email" bson:"email,omitempty"` - Username string `json:"username" bson:"username,omitempty"` - Firstname string `json:"firstname" bson:"firstname,omitempty"` - Lastname string `json:"lastname" bson:"lastname,omitempty"` - Password string `json:"password" bson:"password,omitempty"` - IsAdmin bool `json:"is_admin" bson:"is_admin,omitempty"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/admin/user_dao.go b/go/pkg/admin/user_dao.go deleted file mode 100644 index 3f77fbd..0000000 --- a/go/pkg/admin/user_dao.go +++ /dev/null @@ -1,123 +0,0 @@ -package admin - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "log" - - "github.com/gin-gonic/gin" - - "golang.org/x/crypto/bcrypt" - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// UserDAO extends the type BaseDAO. -type UserDAO struct { - Db dao.BaseDAO -} - -const ( - // USERCOLLECTION defines the collection name for storing application user data. - USERCOLLECTION = "user" - // USERMODEL defines the name of the user data model. - USERMODEL = "kontor.admin.user" -) - -// HashPassword returns the encrypted password from password string. -func HashPassword(password string) (string, error) { - bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) - return string(bytes), err -} - -// CheckPasswordHash returns if password correlates with pasword hash. -func CheckPasswordHash(password, hash string) bool { - err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) - return err == nil -} - -// FindAll retrieves the list of users from the database. -func (m *UserDAO) FindAll() ([]User, error) { - m.Db.Connect() - var users []User - err := m.Db.MongoDb.C(USERCOLLECTION).Find(bson.M{"model": USERMODEL}).All(&users) - return users, err -} - -// FindByID returns a user with given id or returns the error. -func (m *UserDAO) FindByID(id string) (User, error) { - m.Db.Connect() - var user User - err := m.Db.MongoDb.C(USERCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&user) - return user, err -} - -// FindByUsername returns a user with given name or returns the error. -func (m *UserDAO) FindByUsername(username string) (User, error) { - m.Db.Connect() - var user User - err := m.Db.MongoDb.C(USERCOLLECTION).Find(bson.M{"username": username, "model": USERMODEL}).One(&user) - return user, err -} - -// Insert a user into database. -func (m *UserDAO) Insert(user User) error { - m.Db.Connect() - user.Model = USERMODEL - err := m.Db.MongoDb.C(USERCOLLECTION).Insert(&user) - return err -} - -// Upsert a user into database. -func (m *UserDAO) Upsert(user User) (*mgo.ChangeInfo, error) { - m.Db.Connect() - user.Model = USERMODEL - info, err := m.Db.MongoDb.C(USERCOLLECTION).Upsert(bson.M{"username": user.Username}, &user) - return info, err -} - -// Update an existing user. -func (m *UserDAO) Update(user User) error { - m.Db.Connect() - err := m.Db.MongoDb.C(USERCOLLECTION).UpdateId(user.ID, &user) - return err -} - -// Delete an existing user. -func (m *UserDAO) Delete(user User) error { - m.Db.Connect() - err := m.Db.MongoDb.C(USERCOLLECTION).Remove(&user) - return err -} - -// IsUserValid checks if the username and password combination is valid -func (m *UserDAO) IsUserValid(username, password string) bool { - if gin.IsDebugging() { - log.Printf("UserDAO.IsUserValid(%s)", username) - } - user, err := m.FindByUsername(username) - if gin.IsDebugging() { - log.Printf("UserDAO.IsUserValid: %v, %v", user, err) - } - if &user == nil || err != nil { - return false - } - return CheckPasswordHash(password, user.Password) -} - -// IsUserAdmin checks if user identified by name has admin rights. -func (m *UserDAO) IsUserAdmin(username string) bool { - user, err := m.FindByUsername(username) - if &user == nil || err != nil { - return false - } - return user.IsAdmin -} - -// IsUsernameAvailable checks if the supplied username is available. -func (m *UserDAO) IsUsernameAvailable(username string) bool { - user, err := m.FindByUsername(username) - if &user == nil || err != nil { - return true - } - return false -} diff --git a/go/pkg/admin/user_test.go b/go/pkg/admin/user_test.go deleted file mode 100644 index 0668ae2..0000000 --- a/go/pkg/admin/user_test.go +++ /dev/null @@ -1,105 +0,0 @@ -package admin - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var userModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Email", "string"}, - {"Username", "string"}, - {"Firstname", "string"}, - {"Lastname", "string"}, - {"Password", "string"}, - {"IsAdmin", "bool"}, - {"Model", "string"}, -} - -func TestUserModel(t *testing.T) { - m := User{} - if reflect.TypeOf(m).NumField() != len(userModelTestTable) { - t.Fail() - } - for index, testData := range userModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListUsers(t *testing.T) { - var userDao = UserDAO{Db: dao.TestDb} - users, err := userDao.FindAll() - if err != nil { - t.Fail() - } - if users != nil { - t.Fail() - } -} - -func TestInsertUser(t *testing.T) { - var ( - userDao = UserDAO{Db: dao.TestDb} - user = User{} - users []User - ) - user.ID = bson.NewObjectId() - user.Username = "test" - err := userDao.Insert(user) - if err != nil { - t.Fail() - } - users, err = userDao.FindAll() - if err != nil { - t.Fail() - } - if len(users) != 1 { - t.Fail() - } -} - -func TestUpsertUser(t *testing.T) { - var ( - userDao = UserDAO{Db: dao.TestDb} - user = User{} - ) - user.ID = bson.NewObjectId() - user.Username = "test2" - userDao.Upsert(user) - users, err := userDao.FindAll() - if err != nil { - t.Fail() - } - if len(users) != 2 { - t.Fail() - } -} - -func TestDeleteUser(t *testing.T) { - var ( - userDao = UserDAO{Db: dao.TestDb} - ) - users, err := userDao.FindAll() - if err != nil { - t.Fail() - } - for _, user := range users { - userDao.Delete(user) - } - users, err = userDao.FindAll() - if err != nil { - t.Fail() - } - if len(users) != 0 { - t.Fail() - } -} diff --git a/go/pkg/admin/views.go b/go/pkg/admin/views.go deleted file mode 100644 index f1b62cc..0000000 --- a/go/pkg/admin/views.go +++ /dev/null @@ -1,242 +0,0 @@ -package admin - -import ( - "io/ioutil" - "log" - "net/http" - "path/filepath" - "strconv" - - "gitlab.thpeetz.de/kontor/kontor-go/pkg/auth" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/comics" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/util" - - "github.com/gin-gonic/gin" - "github.com/smallfish/simpleyaml" -) - -const ( - // KontorUserAdministrationTitle defines the text of the page title - KontorUserAdministrationTitle = "Kontor User Administration" - // DataUploadTemplate defines the name of the template file for the data upload - DataUploadTemplate = "kontor/data-upload.html" -) - -// ShowLoginPage renders login page. -func ShowLoginPage(c *gin.Context) { - // Call the render function with the name of the template to render - util.Render(c, gin.H{"title": "Login"}, "login.html") -} - -// PerformLogin reads data from login form and validates input. -func PerformLogin(c *gin.Context) { - // Obtain the POSTed username and password values - username := c.PostForm("username") - password := c.PostForm("password") - - var userDao = UserDAO{Db: dao.KontorDb} - - // Check if the username/password combination is valid - if userDao.IsUserValid(username, password) { - sessionInterface, _ := c.Get("session") - sessionID := sessionInterface.(string) - user, _ := userDao.FindByUsername(username) - sessionDao := auth.SessionDAO{Db: dao.KontorDb} - session, _ := sessionDao.FindByID(sessionID) - session.Username = username - session.IsAdmin = user.IsAdmin - sessionDao.Update(session) - util.Render(c, gin.H{"title": "Successful Login", "InfoMessage": "Login successfull"}, "kontor/index.html") - } else { - // If the username/password combination is invalid, - // show the error message on the login page - c.HTML(http.StatusBadRequest, "login.html", gin.H{ - "ErrorTitle": "Login Failed", - "ErrorMessage": "Invalid credentials provided"}) - } -} - -// Logout invalidates session. -func Logout(c *gin.Context) { - sessionInterface, _ := c.Get("session") - sessionID := sessionInterface.(string) - c.SetCookie("session", sessionID, -1, "", "", false, true) - - // Redirect to the home page - c.Redirect(http.StatusTemporaryRedirect, "/") -} - -func showAdminIndex(c *gin.Context) { - // Call the render function with the name of the template to render - util.Render(c, gin.H{"title": "Kontor", "payload": nil}, "kontor/admin.html") -} - -func showUserIndex(c *gin.Context) { - var dao = UserDAO{Db: dao.KontorDb} - if users, err := dao.FindAll(); err == nil && users != nil { - util.Render(c, gin.H{"title": KontorUserAdministrationTitle, "payload": users}, "kontor/users.html") - } else { - util.Render(c, gin.H{"title": KontorUserAdministrationTitle, "payload": users, "ErrorMessage": err}, "kontor/users.html") - } -} - -func showUserDetails(c *gin.Context) { - userID := c.Param("userid") - var userDao = UserDAO{Db: dao.KontorDb} - if user, err := userDao.FindByID(userID); err == nil && &user != nil { - util.Render(c, gin.H{"title": KontorUserAdministrationTitle, "payload": user, "action": util.SaveAction}, "kontor/user-detail.html") - } else { - c.AbortWithError(http.StatusNotFound, err) - } -} - -func showUserCreation(c *gin.Context) { - var user = User{} - util.Render(c, gin.H{"title": KontorUserAdministrationTitle, "payload": user, "action": util.AddAction}, "kontor/user-detail.html") -} - -func validateUserCreation(c *gin.Context) { - // Obtain the POSTed username and password values - username := c.PostForm("username") - firstname := c.PostForm("firstname") - lastname := c.PostForm("lastname") - password := c.PostForm("password") - adminFormVar := c.PostForm("admin") - action := c.PostForm("action") - userid := c.PostForm("userid") - isAdmin, _ := strconv.ParseBool(adminFormVar) - - var err error - var dao = UserDAO{Db: dao.KontorDb} - var user = User{} - - switch action { - case util.AddAction: - user.Username = username - user.Firstname = firstname - user.Lastname = lastname - user.IsAdmin = isAdmin - user.Password, _ = HashPassword(password) - _, err = dao.Upsert(user) - case util.SaveAction: - user, _ = dao.FindByID(userid) - user.Username = username - user.Firstname = firstname - user.Lastname = lastname - user.IsAdmin = isAdmin - user.Password, _ = HashPassword(password) - err = dao.Update(user) - case util.DeleteAction: - user, _ = dao.FindByID(userid) - err = dao.Delete(user) - } - if err == nil { - c.Redirect(http.StatusTemporaryRedirect, "/admin/user") - } else { - c.HTML(http.StatusBadRequest, "kontor/create-user.html", gin.H{ - "ErrorTitle": "User Creation Failed", - "ErrorMessage": err.Error()}) - } -} - -func showDataUpload(c *gin.Context) { - // Call the render function with the name of the template to render - //util.Render(c, gin.H{"title": "Kontor", "payload": nil}, "kontor/admin.html") - util.Render(c, gin.H{"title": "Kontor Data Upload", "payload": nil}, DataUploadTemplate) -} - -func validateDataUpload(c *gin.Context) { - // Call the render function with the name of the template to render - //util.Render(c, gin.H{"title": "Kontor", "payload": nil}, "kontor/admin.html") - datafile, err := c.FormFile("datafile") - if err != nil { - c.HTML(http.StatusBadRequest, DataUploadTemplate, gin.H{ - "ErrorTitle": "Data Upload Failed", - "ErrorMessage": err.Error()}) - return - } - log.Printf("Data File: %v", datafile.Filename) - filename := filepath.Base(datafile.Filename) - if err := c.SaveUploadedFile(datafile, filename); err != nil { - c.HTML(http.StatusBadRequest, DataUploadTemplate, gin.H{ - "ErrorTitle": "Data Upload Failed", - "ErrorMessage": err.Error()}) - return - } - source, err := ioutil.ReadFile(filename) - if err != nil { - panic(err) - } - yaml, err := simpleyaml.NewYaml(source) - if err != nil { - panic(err) - } - if yaml.IsArray() { - size, err := yaml.GetArraySize() - if err != nil { - panic(err) - } - log.Printf("Found %d entries.\n", size) - var publisherDao comics.PublisherDAO - publisherDao.Db = dao.KontorDb - var artistDao comics.ArtistDAO - artistDao.Db = dao.KontorDb - var comicDao comics.ComicDAO - comicDao.Db = dao.KontorDb - publisherMap := make(map[int]string) - for index := 0; index < size; index++ { - entry := yaml.GetIndex(index) - if entry.IsMap() { - model, err := entry.Get("model").String() - if err != nil { - panic(err) - } - pk, _ := entry.Get("pk").Int() - switch model { - case "comics.publisher": - name, err := entry.Get("fields").Get("name").String() - if err != nil { - panic(err) - } - log.Printf(" %v %v %v\n", pk, model, name) - publisherMap[pk] = name - publisher := comics.Publisher{} - publisher.Name = name - info, _ := publisherDao.Upsert(publisher) - log.Printf("Publisher records changed: %d", info.Updated) - case "comics.artist": - name, err := entry.Get("fields").Get("name").String() - if err != nil { - panic(err) - } - log.Printf(" %v %v %v\n", pk, model, name) - artist := comics.Artist{} - artist.Name = name - info, _ := artistDao.Upsert(artist) - log.Printf("Artist records changed: %d", info.Updated) - case "comics.comic": - title, err := entry.Get("fields").Get("title").String() - if err != nil { - panic(err) - } - publisherID, err := entry.Get("fields").Get("publisher").Int() - publisher, err := publisherDao.FindByName(publisherMap[publisherID]) - completed, err := entry.Get("fields").Get("completed").Bool() - if err != nil { - log.Printf("Error occured: %v", err) - } - log.Printf(" %v %v %v %v\n", pk, model, title, completed) - comic := comics.Comic{} - comic.Title = title - comic.Completed = completed - comic.Publisher = publisher.ID - info, _ := comicDao.Upsert(comic) - log.Printf("Comic records changed: %d", info.Updated) - } - //fmt.Printf("Entry %d: %v\n", index, entry) - } - } - } - util.Render(c, gin.H{"title": "Kontor Data Upload", "payload": nil}, DataUploadTemplate) -} diff --git a/go/pkg/application/registry/comic/registry.go b/go/pkg/application/registry/comic/registry.go deleted file mode 100644 index 7fb2f95..0000000 --- a/go/pkg/application/registry/comic/registry.go +++ /dev/null @@ -1,19 +0,0 @@ -package comic - -import ( - "net/http" - - "gitlab.com/tpeetz-kontor/kontor-go/cmd/pkg/context/comic/routing" - "gitlab.com/tpeetz-kontor/kontor-go/cmd/pkg/infrastructure/app" -) - -func BuildComicService(app *app.Application) { - // Create our Handler - handler := routing.NewHandler(app) - - // Create a sub router for this service - router := app.Router.Methods(http.MethodGet).Subrouter() - - // Register our service routes - router.HandleFunc("/comics/comic", handler.ComicList).Name("comics:comicList") -} diff --git a/go/pkg/auth/middleware.go b/go/pkg/auth/middleware.go deleted file mode 100644 index a26a93d..0000000 --- a/go/pkg/auth/middleware.go +++ /dev/null @@ -1,87 +0,0 @@ -package auth - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/properties" - "log" - "net/http" - - "github.com/gin-gonic/gin" - "gopkg.in/mgo.v2/bson" -) - -var sessionDao = SessionDAO{Db: dao.KontorDb} - -// EnsureLoggedIn ensures that a request will be aborted with an error -// if the user is not logged in -func EnsureLoggedIn() gin.HandlerFunc { - return func(c *gin.Context) { - // If there's an error or if the token is empty - // the user is not logged in - sessionInterface, _ := c.Get("session") - sessionID := sessionInterface.(string) - if session, err := sessionDao.GetSession(sessionID); err != nil || session.Username == "" { - c.Redirect(http.StatusTemporaryRedirect, "/") - //c.AbortWithStatus(http.StatusUnauthorized) - } - } -} - -// EnsureAdminStatus ensures that a request will be aborted with an error -// if the user is not logged in -func EnsureAdminStatus() gin.HandlerFunc { - return func(c *gin.Context) { - // If there's an error or if the token is empty - // the user is not logged in - sessionInterface, _ := c.Get("session") - sessionID := sessionInterface.(string) - if session, err := sessionDao.GetSession(sessionID); err != nil || !session.IsAdmin { - c.Redirect(http.StatusTemporaryRedirect, "/") - //c.AbortWithStatus(http.StatusUnauthorized) - } - } -} - -// EnsureNotLoggedIn ensures that a request will be aborted with an error -// if the user is already logged in -func EnsureNotLoggedIn() gin.HandlerFunc { - return func(c *gin.Context) { - // If there's no error or if the token is not empty - // the user is already logged in - sessionInterface, _ := c.Get("session") - sessionID := sessionInterface.(string) - if session, err := sessionDao.GetSession(sessionID); err != nil || session.Username != "" { - c.Redirect(http.StatusTemporaryRedirect, "/") - //c.AbortWithStatus(http.StatusUnauthorized) - } - } -} - -// SetSessionStatus reads sessionId from cookie if available or create new session object -// and sets cookie accordingly. -func SetSessionStatus() gin.HandlerFunc { - return func(c *gin.Context) { - if sessionID, err := c.Cookie("session"); err == nil || sessionID != "" { - c.Set("session", sessionID) - } else { - session, _ := sessionDao.GetSession(bson.NewObjectId().Hex()) - sessionID := session.ID.Hex() - c.Set("session", sessionID) - c.SetCookie("session", sessionID, 3600, "", "", false, true) - } - } -} - -// SetSessionData populates session information with username, admin status of user and -// application version. -func SetSessionData(c *gin.Context, data gin.H) { - sessionInterface, _ := c.Get("session") - sessionID := sessionInterface.(string) - session, _ := sessionDao.GetSession(sessionID) - if gin.IsDebugging() { - log.Printf("setSessionData(%v): %v", sessionID, session) - } - data["is_logged_in"] = (session.Username != "") - data["is_admin"] = session.IsAdmin - data["version"] = properties.Version -} diff --git a/go/pkg/auth/session.go b/go/pkg/auth/session.go deleted file mode 100644 index dccf9fb..0000000 --- a/go/pkg/auth/session.go +++ /dev/null @@ -1,11 +0,0 @@ -package auth - -import "gopkg.in/mgo.v2/bson" - -// Session defines the data model for sessions with id,user name and admin status. -type Session struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Username string `json:"username" bson:"username,omitempty"` - IsAdmin bool `json:"is_admin" bson:"is_admin,omitempty"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/auth/session_dao.go b/go/pkg/auth/session_dao.go deleted file mode 100644 index 70f7adc..0000000 --- a/go/pkg/auth/session_dao.go +++ /dev/null @@ -1,78 +0,0 @@ -package auth - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// SessionDAO extends the type BaseDAO. -type SessionDAO struct { - Db dao.BaseDAO -} - -const ( - // SESSIONCOLLECTION defines the collection name for storing session data. - SESSIONCOLLECTION = "session" - // SESSIONMODEL defines the name of the session data model. - SESSIONMODEL = "kontor.admin.session" -) - -// FindAll retrieves the list of sessions from the database. -func (m *SessionDAO) FindAll() ([]Session, error) { - m.Db.Connect() - var sessions []Session - err := m.Db.MongoDb.C(SESSIONCOLLECTION).Find(bson.M{"model": SESSIONMODEL}).All(&sessions) - return sessions, err -} - -// FindByID returns a session with given id or returns the error. -func (m *SessionDAO) FindByID(id string) (Session, error) { - m.Db.Connect() - var session Session - err := m.Db.MongoDb.C(SESSIONCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&session) - return session, err -} - -// Insert a session into database. -func (m *SessionDAO) Insert(session Session) error { - m.Db.Connect() - session.Model = SESSIONMODEL - err := m.Db.MongoDb.C(SESSIONCOLLECTION).Insert(&session) - //log.PrintDebug("Insert: %v, %v\n", session, err) - return err -} - -// Upsert a session into database. -func (m *SessionDAO) Upsert(session Session) (*mgo.ChangeInfo, error) { - m.Db.Connect() - session.Model = SESSIONMODEL - info, err := m.Db.MongoDb.C(SESSIONCOLLECTION).Upsert(bson.M{"_id": session.ID}, &session) - return info, err -} - -// Update an existing session. -func (m *SessionDAO) Update(session Session) error { - m.Db.Connect() - err := m.Db.MongoDb.C(SESSIONCOLLECTION).UpdateId(session.ID, &session) - return err -} - -// Delete an existing session. -func (m *SessionDAO) Delete(session Session) error { - m.Db.Connect() - err := m.Db.MongoDb.C(SESSIONCOLLECTION).Remove(&session) - return err -} - -// GetSession get a session by given id or create a new one, if nothing was found. -func (m *SessionDAO) GetSession(id string) (*Session, error) { - m.Db.Connect() - session, err := m.FindByID(id) - if err != nil { - session = Session{ID: bson.ObjectIdHex(id), Username: "", IsAdmin: false} - m.Insert(session) - } - return &session, nil -} diff --git a/go/pkg/auth/session_test.go b/go/pkg/auth/session_test.go deleted file mode 100644 index a6769b8..0000000 --- a/go/pkg/auth/session_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package auth - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var sessionModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Username", "string"}, - {"IsAdmin", "bool"}, - {"Model", "string"}, -} - -func TestSessionModel(t *testing.T) { - m := Session{} - if reflect.TypeOf(m).NumField() != len(sessionModelTestTable) { - t.Fail() - } - for index, testData := range sessionModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListSessions(t *testing.T) { - var ( - sessionDao = SessionDAO{Db: dao.TestDb} - ) - sessions, err := sessionDao.FindAll() - if err != nil { - t.Fail() - } - if sessions != nil { - t.Fail() - } -} - -func TestInsertSession(t *testing.T) { - var ( - sessionDao = SessionDAO{Db: dao.TestDb} - session = Session{} - sessions []Session - ) - session.ID = bson.NewObjectId() - session.Username = "test" - err := sessionDao.Insert(session) - if err != nil { - t.Fail() - } - sessions, err = sessionDao.FindAll() - if err != nil { - t.Fail() - } - if len(sessions) != 1 { - t.Fail() - } -} - -func TestUpsertSession(t *testing.T) { - var ( - sessionDao = SessionDAO{Db: dao.TestDb} - session = Session{} - ) - session.ID = bson.NewObjectId() - session.Username = "test2" - sessionDao.Upsert(session) - sessions, err := sessionDao.FindAll() - if err != nil { - t.Fail() - } - if len(sessions) != 2 { - t.Fail() - } -} - -func TestDeleteSession(t *testing.T) { - var ( - sessionDao = SessionDAO{Db: dao.TestDb} - ) - sessions, err := sessionDao.FindAll() - if err != nil { - t.Fail() - } - for _, session := range sessions { - sessionDao.Delete(session) - } - sessions, err = sessionDao.FindAll() - if err != nil { - t.Fail() - } - if len(sessions) != 0 { - t.Fail() - } -} diff --git a/go/pkg/comics/artist.go b/go/pkg/comics/artist.go deleted file mode 100644 index 8afd80a..0000000 --- a/go/pkg/comics/artist.go +++ /dev/null @@ -1,12 +0,0 @@ -package comics - -import ( - "gopkg.in/mgo.v2/bson" -) - -// Artist defines the data model for comic artists with id and name. -type Artist struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Name string `json:"name" bson:"name"` - Model string `json:"model" bson:"model"` -} diff --git a/go/pkg/comics/artist_dao.go b/go/pkg/comics/artist_dao.go deleted file mode 100644 index b177c2b..0000000 --- a/go/pkg/comics/artist_dao.go +++ /dev/null @@ -1,78 +0,0 @@ -package comics - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "log" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// ArtistDAO extends the type BaseDAO. -type ArtistDAO struct { - Db dao.BaseDAO -} - -const ( - // ARTISTCOLLECTION defines the collection name for storing comic artists. - ARTISTCOLLECTION = "artist" - // ARTISTMODEL defines the name of the artist data model. - ARTISTMODEL = "kontor.comics.artist" -) - -// FindAll retrieves the list of artists from the database. -func (m *ArtistDAO) FindAll() ([]Artist, error) { - m.Db.Connect() - var artists []Artist - err := m.Db.MongoDb.C(ARTISTCOLLECTION).Find(bson.M{"model": ARTISTMODEL}).All(&artists) - return artists, err -} - -// FindByID returns an artists with given id or returns the error. -func (m *ArtistDAO) FindByID(id string) (Artist, error) { - m.Db.Connect() - var artist Artist - err := m.Db.MongoDb.C(ARTISTCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&artist) - return artist, err -} - -// FindByName returns an artists with given name or returns the error. -func (m *ArtistDAO) FindByName(name string) (Artist, error) { - m.Db.Connect() - var artist Artist - err := m.Db.MongoDb.C(ARTISTCOLLECTION).Find(bson.M{"name": name, "model": ARTISTMODEL}).One(&artist) - return artist, err -} - -// Insert an artist into database. -func (m *ArtistDAO) Insert(artist Artist) error { - m.Db.Connect() - artist.Model = ARTISTMODEL - err := m.Db.MongoDb.C(ARTISTCOLLECTION).Insert(&artist) - return err -} - -// Upsert an artist into database. -func (m *ArtistDAO) Upsert(artist Artist) (*mgo.ChangeInfo, error) { - m.Db.Connect() - artist.Model = ARTISTMODEL - info, err := m.Db.MongoDb.C(ARTISTCOLLECTION).Upsert(bson.M{"name": artist.Name}, &artist) - return info, err -} - -// Delete an existing artist. -func (m *ArtistDAO) Delete(artist Artist) error { - m.Db.Connect() - err := m.Db.MongoDb.C(ARTISTCOLLECTION).Remove(&artist) - if err != nil { - log.Printf("ArtistDao.Delete: %v", err) - } - return err -} - -// Update an existing artist. -func (m *ArtistDAO) Update(artist Artist) error { - m.Db.Connect() - err := m.Db.MongoDb.C(ARTISTCOLLECTION).UpdateId(artist.ID, &artist) - return err -} diff --git a/go/pkg/comics/artist_test.go b/go/pkg/comics/artist_test.go deleted file mode 100644 index 96e23ca..0000000 --- a/go/pkg/comics/artist_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package comics - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var artistModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Name", "string"}, - {"Model", "string"}, -} - -func TestArtistModel(t *testing.T) { - m := Artist{} - if reflect.TypeOf(m).NumField() != len(artistModelTestTable) { - t.Fail() - } - for index, testData := range artistModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListArtists(t *testing.T) { - var ( - artistDao = ArtistDAO{Db: dao.TestDb} - ) - artists, err := artistDao.FindAll() - if err != nil { - t.Fail() - } - if artists != nil { - t.Fail() - } -} - -func TestInsertArtist(t *testing.T) { - var ( - artistDao = ArtistDAO{Db: dao.TestDb} - artist = Artist{} - artists []Artist - ) - artist.ID = bson.NewObjectId() - artist.Name = "Turner, Michael" - err := artistDao.Insert(artist) - if err != nil { - t.Fail() - } - artists, _ = artistDao.FindAll() - if len(artists) != 1 { - t.Fail() - } -} - -func TestUpsertArtist(t *testing.T) { - var ( - artistDao = ArtistDAO{Db: dao.TestDb} - artist = Artist{} - ) - artist.ID = bson.NewObjectId() - artist.Name = "Marz, Ron" - _, err := artistDao.Upsert(artist) - if err != nil { - t.Fail() - } - artists, _ := artistDao.FindAll() - if len(artists) != 2 { - t.Fail() - } -} - -func TestDeleteArtist(t *testing.T) { - var ( - artistDao = ArtistDAO{Db: dao.TestDb} - ) - artists, err := artistDao.FindAll() - if err != nil { - t.Fail() - } - for _, artist := range artists { - artistDao.Delete(artist) - } - artists, _ = artistDao.FindAll() - if len(artists) != 0 { - t.Fail() - } -} diff --git a/go/pkg/comics/artist_views.go b/go/pkg/comics/artist_views.go deleted file mode 100644 index c685f1b..0000000 --- a/go/pkg/comics/artist_views.go +++ /dev/null @@ -1,23 +0,0 @@ -package comics - -import ( - "net/http" - - "github.com/gin-gonic/gin" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/util" -) - -const ( - // ArtistPublisherTemplate defines name of template file for comics publishers - ArtistPublisherTemplate = "comics/publishers.html" -) - -func showArtistList(c *gin.Context) { - var dao = ArtistDAO{Db: dao.KontorDb} - if artists, err := dao.FindAll(); err == nil { - util.Render(c, gin.H{"title": "Comic Artists", "payload": artists}, "artists.html") - } else { - c.AbortWithError(http.StatusNotFound, err) - } -} diff --git a/go/pkg/comics/comic.go b/go/pkg/comics/comic.go deleted file mode 100644 index 7332d65..0000000 --- a/go/pkg/comics/comic.go +++ /dev/null @@ -1,15 +0,0 @@ -package comics - -import ( - "gopkg.in/mgo.v2/bson" -) - -// Comic defines the data model for comic issues with id, title, publisher, order and completion status. -type Comic struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Title string `json:"title" bson:"title"` - Publisher bson.ObjectId `json:"publisher" bson:"publisher,omitempty"` - CurrentOrder bool `json:"current_order" bson:"current_order"` - Completed bool `json:"completed" bson:"completed"` - Model string `json:"model" bson:"model"` -} diff --git a/go/pkg/comics/comic_dao.go b/go/pkg/comics/comic_dao.go deleted file mode 100644 index c9f9b02..0000000 --- a/go/pkg/comics/comic_dao.go +++ /dev/null @@ -1,75 +0,0 @@ -package comics - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// ComicDAO extends the type BaseDAO. -type ComicDAO struct { - Db dao.BaseDAO -} - -const ( - // COMICCOLLECTION defines the collection name for storing comics. - COMICCOLLECTION = "comic" - // COMICMODEL defines the name of the comic data model. - COMICMODEL = "kontor.comics.comic" -) - -// FindAll retrieves the list of comisc from the database. -func (m *ComicDAO) FindAll() ([]Comic, error) { - m.Db.Connect() - var comics []Comic - err := m.Db.MongoDb.C(COMICCOLLECTION).Find(bson.M{"model": COMICMODEL}).All(&comics) - return comics, err -} - -// FindByID returns an comic with given id or returns the error. -func (m *ComicDAO) FindByID(id string) (Comic, error) { - m.Db.Connect() - var comic Comic - err := m.Db.MongoDb.C(COMICCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&comic) - return comic, err -} - -// FindByName returns an comic with given name or returns the error. -func (m *ComicDAO) FindByName(name string) (Comic, error) { - m.Db.Connect() - var comic Comic - err := m.Db.MongoDb.C(COMICCOLLECTION).Find(bson.M{"name": name, "model": COMICMODEL}).One(&comic) - return comic, err -} - -// Insert a comic into database. -func (m *ComicDAO) Insert(comic Comic) error { - m.Db.Connect() - comic.Model = COMICMODEL - err := m.Db.MongoDb.C(COMICCOLLECTION).Insert(&comic) - //util.PrintDebug("ComicDAO.Insert: %v", comic) - return err -} - -// Upsert a comic into database. -func (m *ComicDAO) Upsert(comic Comic) (*mgo.ChangeInfo, error) { - m.Db.Connect() - comic.Model = COMICMODEL - info, err := m.Db.MongoDb.C(COMICCOLLECTION).Upsert(bson.M{"title": comic.Title}, &comic) - return info, err -} - -// Delete an existing comic. -func (m *ComicDAO) Delete(comic Comic) error { - m.Db.Connect() - err := m.Db.MongoDb.C(COMICCOLLECTION).Remove(&comic) - return err -} - -// Update an existing movie -func (m *ComicDAO) Update(comic Comic) error { - m.Db.Connect() - err := m.Db.MongoDb.C(COMICCOLLECTION).UpdateId(comic.ID, &comic) - return err -} diff --git a/go/pkg/comics/comic_test.go b/go/pkg/comics/comic_test.go deleted file mode 100644 index baea792..0000000 --- a/go/pkg/comics/comic_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package comics - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var comicModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Title", "string"}, - {"Publisher", "string"}, - {"CurrentOrder", "bool"}, - {"Completed", "bool"}, - {"Model", "string"}, -} - -func TestComicModel(t *testing.T) { - m := Comic{} - if reflect.TypeOf(m).NumField() != len(comicModelTestTable) { - t.Fail() - } - for index, testData := range comicModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListComics(t *testing.T) { - var ( - comicDao = ComicDAO{Db: dao.TestDb} - ) - comics, err := comicDao.FindAll() - if err != nil { - t.Fail() - } - if len(comics) != 0 { - t.Fail() - } -} - -func TestInsertComic(t *testing.T) { - var ( - comicDao = ComicDAO{Db: dao.TestDb} - comic = Comic{} - comics []Comic - ) - comic.ID = bson.NewObjectId() - comic.Title = "Simpsons" - comicDao.Insert(comic) - comics, _ = comicDao.FindAll() - if len(comics) != 1 { - t.Fail() - } -} -func TestUpsertComic(t *testing.T) { - var ( - comicDao = ComicDAO{Db: dao.TestDb} - comic = Comic{} - ) - comic.ID = bson.NewObjectId() - comic.Title = "1602" - comicDao.Upsert(comic) - comics, _ := comicDao.FindAll() - if len(comics) != 2 { - t.Fail() - } -} -func TestDeleteComic(t *testing.T) { - var ( - comicDao = ComicDAO{Db: dao.TestDb} - ) - comics, _ := comicDao.FindAll() - for _, comic := range comics { - comicDao.Delete(comic) - } - comics, _ = comicDao.FindAll() - if len(comics) != 0 { - t.Fail() - } -} diff --git a/go/pkg/comics/publisher.go b/go/pkg/comics/publisher.go deleted file mode 100644 index 7bef875..0000000 --- a/go/pkg/comics/publisher.go +++ /dev/null @@ -1,12 +0,0 @@ -package comics - -import ( - "gopkg.in/mgo.v2/bson" -) - -// Publisher defines the data model for comic publishers with id and name. -type Publisher struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Name string `json:"name" bson:"name"` - Model string `json:"model" bson:"model"` -} diff --git a/go/pkg/comics/publisher_dao.go b/go/pkg/comics/publisher_dao.go deleted file mode 100644 index f12cf22..0000000 --- a/go/pkg/comics/publisher_dao.go +++ /dev/null @@ -1,75 +0,0 @@ -package comics - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// PublisherDAO extends the type BaseDAO. -type PublisherDAO struct { - Db dao.BaseDAO -} - -const ( - // PUBLISHERCOLLECTION defines the collection name for storing publishers. - PUBLISHERCOLLECTION = "publisher" - // PUBLISHERMODEL defines the name of the publisher data model. - PUBLISHERMODEL = "kontor.comics.publisher" -) - -// FindAll retrieves the list of publishers from the database. -func (m *PublisherDAO) FindAll() ([]Publisher, error) { - m.Db.Connect() - var publishers []Publisher - err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).Find(bson.M{"model": PUBLISHERMODEL}).All(&publishers) - return publishers, err -} - -// FindByID returns an publisher with given id or returns the error. -func (m *PublisherDAO) FindByID(id string) (Publisher, error) { - m.Db.Connect() - var publisher Publisher - err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&publisher) - return publisher, err -} - -// FindByName returns an comic with given name or returns the error. -func (m *PublisherDAO) FindByName(name string) (Publisher, error) { - m.Db.Connect() - var publisher Publisher - err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).Find(bson.M{"name": name, "model": PUBLISHERMODEL}).One(&publisher) - return publisher, err -} - -// Insert a publisher into database. -func (m *PublisherDAO) Insert(publisher Publisher) error { - m.Db.Connect() - publisher.Model = PUBLISHERMODEL - err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).Insert(&publisher) - //util.PrintDebug("PublisherDAO.Insert: %v", publisher) - return err -} - -// Upsert a publisher into database. -func (m *PublisherDAO) Upsert(publisher Publisher) (*mgo.ChangeInfo, error) { - m.Db.Connect() - publisher.Model = PUBLISHERMODEL - info, err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).Upsert(bson.M{"name": publisher.Name}, &publisher) - return info, err -} - -// Delete an existing publisher. -func (m *PublisherDAO) Delete(publisher Publisher) error { - m.Db.Connect() - err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).Remove(&publisher) - return err -} - -// Update an existing publisher. -func (m *PublisherDAO) Update(publisher Publisher) error { - m.Db.Connect() - err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).UpdateId(publisher.ID, &publisher) - return err -} diff --git a/go/pkg/comics/publisher_test.go b/go/pkg/comics/publisher_test.go deleted file mode 100644 index 289c2cf..0000000 --- a/go/pkg/comics/publisher_test.go +++ /dev/null @@ -1,87 +0,0 @@ -package comics - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var publisherModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Name", "string"}, - {"Model", "string"}, -} - -func TestPublisherModel(t *testing.T) { - m := Publisher{} - if reflect.TypeOf(m).NumField() != len(publisherModelTestTable) { - t.Fail() - } - for index, testData := range publisherModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListPublishers(t *testing.T) { - var ( - publisherDao = PublisherDAO{Db: dao.TestDb} - ) - publishers, err := publisherDao.FindAll() - if err != nil { - t.Fail() - } - if len(publishers) != 0 { - t.Fail() - } -} - -func TestInsertPublisher(t *testing.T) { - var ( - publisherDao = PublisherDAO{Db: dao.TestDb} - publisher = Publisher{} - publishers []Publisher - ) - publisher.ID = bson.NewObjectId() - publisher.Name = "CrossGen" - publisherDao.Insert(publisher) - publishers, _ = publisherDao.FindAll() - if len(publishers) != 1 { - t.Fail() - } -} - -func TestUpsertPublisher(t *testing.T) { - var ( - publisherDao = PublisherDAO{Db: dao.TestDb} - publisher = Publisher{} - ) - publisher.ID = bson.NewObjectId() - publisher.Name = "Marvel" - publisherDao.Upsert(publisher) - publishers, _ := publisherDao.FindAll() - if len(publishers) != 2 { - t.Fail() - } -} - -func TestDeletePublisher(t *testing.T) { - var ( - publisherDao = PublisherDAO{Db: dao.TestDb} - ) - publishers, _ := publisherDao.FindAll() - for _, publisher := range publishers { - publisherDao.Delete(publisher) - } - publishers, _ = publisherDao.FindAll() - if len(publishers) != 0 { - t.Fail() - } -} diff --git a/go/pkg/comics/publisher_views.go b/go/pkg/comics/publisher_views.go deleted file mode 100644 index e6acfc9..0000000 --- a/go/pkg/comics/publisher_views.go +++ /dev/null @@ -1,70 +0,0 @@ -package comics - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/util" - "net/http" - - "github.com/gin-gonic/gin" -) - -const ( - // ComicsPublisherTemplate defines name of template file for comics publishers - ComicsPublisherTemplate = "comics/publishers.html" - // ComicsPublisherDetailsTemplate defines name of template file for comics publishers - ComicsPublisherDetailsTemplate = "comics/publisher.html" -) - -func showPublisherList(c *gin.Context) { - var dao = PublisherDAO{Db: dao.KontorDb} - if publishers, err := dao.FindAll(); err == nil { - util.Render(c, gin.H{"title": "Comics Publisher List", "payload": publishers}, ComicsPublisherTemplate) - } else { - c.AbortWithError(http.StatusNotFound, err) - } -} - -func showPublisherDetails(c *gin.Context) { - var dao = PublisherDAO{Db: dao.KontorDb} - publisherid := c.Param("publisher_id") - if publisher, err := dao.FindByID(publisherid); err == nil { - util.Render(c, gin.H{"title": "Comics Publisher", "payload": publisher, "action": util.SaveAction}, ComicsPublisherDetailsTemplate) - } else { - c.AbortWithError(http.StatusNotFound, err) - } -} - -func showPublisherCreation(c *gin.Context) { - var publisher = Publisher{} - util.Render(c, gin.H{"title": "Comics Publisher Creation", "payload": publisher, "action": util.AddAction}, ComicsPublisherTemplate) -} - -func validatePublisherDetails(c *gin.Context) { - name := c.PostForm("name") - action := c.PostForm("action") - publisherid := c.PostForm("publisherid") - - var err error - var dao = PublisherDAO{Db: dao.KontorDb} - var publisher = Publisher{} - - switch action { - case util.AddAction: - publisher.Name = name - _, err = dao.Upsert(publisher) - case util.SaveAction: - publisher, _ = dao.FindByID(publisherid) - publisher.Name = name - err = dao.Update(publisher) - case util.DeleteAction: - publisher, _ = dao.FindByID(publisherid) - err = dao.Delete(publisher) - } - if err == nil { - c.Redirect(http.StatusTemporaryRedirect, "/comics/publisher") - } else { - c.HTML(http.StatusBadRequest, "comics/publisher.html", gin.H{ - "ErrorTitle": "Publisher Creation Failed", - "ErrorMessage": err.Error()}) - } -} diff --git a/go/pkg/comics/routes.go b/go/pkg/comics/routes.go deleted file mode 100644 index 784704e..0000000 --- a/go/pkg/comics/routes.go +++ /dev/null @@ -1,28 +0,0 @@ -package comics - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/auth" - - "github.com/gin-gonic/gin" -) - -// GetRoutes returns all routes for comic related data. -func GetRoutes(router *gin.Engine) { - comicRoutes := router.Group("/comics") - { - comicRoutes.GET("/", auth.EnsureLoggedIn(), showComicList) - comicRoutes.GET("/artist", auth.EnsureLoggedIn(), showArtistList) - comicRoutes.GET("/artist/view/:artist_id", auth.EnsureLoggedIn(), showArtistList) - comicRoutes.GET("/artist/create", auth.EnsureLoggedIn(), showArtistList) - comicRoutes.POST("/artist/create", auth.EnsureLoggedIn(), showArtistList) - comicRoutes.GET("/comic", auth.EnsureLoggedIn(), showComicList) - comicRoutes.GET("/comic/view/:comic_id", auth.EnsureLoggedIn(), showComic) - comicRoutes.GET("/comic/create", auth.EnsureLoggedIn(), showComicList) - comicRoutes.POST("/comic/create", auth.EnsureLoggedIn(), showComicList) - comicRoutes.GET("/publisher", auth.EnsureLoggedIn(), showPublisherList) - comicRoutes.POST("/publisher", auth.EnsureLoggedIn(), showPublisherList) - comicRoutes.GET("/publisher/view/:publisher_id", auth.EnsureLoggedIn(), showPublisherDetails) - comicRoutes.POST("/publisher/validate", auth.EnsureLoggedIn(), validatePublisherDetails) - comicRoutes.GET("/publisher/create", auth.EnsureLoggedIn(), showPublisherCreation) - } -} diff --git a/go/pkg/comics/views.go b/go/pkg/comics/views.go deleted file mode 100644 index f1e9592..0000000 --- a/go/pkg/comics/views.go +++ /dev/null @@ -1,28 +0,0 @@ -package comics - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/util" - "net/http" - - "github.com/gin-gonic/gin" -) - -func showComicList(c *gin.Context) { - var dao = ComicDAO{Db: dao.KontorDb} - if comics, err := dao.FindAll(); err == nil { - util.Render(c, gin.H{"title": "Comics", "payload": comics}, "comics.html") - } else { - c.AbortWithError(http.StatusNotFound, err) - } -} - -func showComic(c *gin.Context) { - var dao = ComicDAO{Db: dao.KontorDb} - comicID := c.Param("comic_id") - if comic, err := dao.FindByID(comicID); err == nil { - util.Render(c, gin.H{"title": "Comic Details", "payload": comic, "action": util.SaveAction}, "comic.html") - } else { - c.AbortWithError(http.StatusNotFound, err) - } -} diff --git a/go/pkg/context/comic/responses/comic.go b/go/pkg/context/comic/responses/comic.go deleted file mode 100644 index a8b6c06..0000000 --- a/go/pkg/context/comic/responses/comic.go +++ /dev/null @@ -1,15 +0,0 @@ -package responses - -// Response is the Ping Response -type Response struct { - Message string `json:"message"` -} - -type ComicList struct { - Comics []Comic `json:"comics"` -} - -type Comic struct { - ID string `json:"id"` - Title string `json:"title"` -} diff --git a/go/pkg/context/comic/routing/endpoints.go b/go/pkg/context/comic/routing/endpoints.go deleted file mode 100644 index abe4187..0000000 --- a/go/pkg/context/comic/routing/endpoints.go +++ /dev/null @@ -1,33 +0,0 @@ -package routing - -import ( - "net/http" - - "gitlab.com/tpeetz-kontor/kontor-go/cmd/pkg/context/comic/responses" - "gitlab.com/tpeetz-kontor/kontor-go/cmd/pkg/infrastructure/app" - responseFactory "gitlab.com/tpeetz-kontor/kontor-go/cmd/pkg/infrastructure/response" -) - -// Handler is the http.Handler for this request -type Handler struct { - app *app.Application -} - -// NewHandler will create a new Handler to handle this request -func NewHandler(app *app.Application) *Handler { - return &Handler{app} -} - -// Handle will handle the incoming request -func (handler *Handler) ComicList(response http.ResponseWriter, request *http.Request) { - handler.app.Logger.Info("Ping Handler Dispatched.") - - responseFactory.Send( - response, - http.StatusOK, - &responses.ComicList{ - Comics: []responses.Comic{{ID: "123", Title: "Comic1"}, {ID: "123", Title: "Comic1"}}, - }, - handler.app.Config.HTTP.Content, - ) -} diff --git a/go/pkg/dao/database.go b/go/pkg/dao/database.go deleted file mode 100644 index 1a0f4c1..0000000 --- a/go/pkg/dao/database.go +++ /dev/null @@ -1,31 +0,0 @@ -package dao - -import ( - "log" - - mgo "gopkg.in/mgo.v2" -) - -// BaseDAO definess the connection parameters to a MongoDB instance. -type BaseDAO struct { - Server string - Database string - MongoDb *mgo.Database -} - -var ( - // KontorDb has the database connection to the productive MongoDB instance. - KontorDb = BaseDAO{Server: "localhost", Database: "kontor"} - // TestDb has the database connection to the test MongoDB instance. - TestDb = BaseDAO{Server: "localhost", Database: "kontor_test"} -) - -// Connect instantiates the database session. -func (m *BaseDAO) Connect() { - session, err := mgo.Dial(m.Server) - if err != nil { - //util.PrintDebug("Connect: %v", err) - log.Fatal(err) - } - m.MongoDb = session.DB(m.Database) -} diff --git a/go/pkg/dao/database_test.go b/go/pkg/dao/database_test.go deleted file mode 100644 index 52a204c..0000000 --- a/go/pkg/dao/database_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package dao - -import ( - "reflect" - "testing" -) - - -var baseDaoTestTable = []struct { - name string - typeName string -}{ - {"Server", "string"}, - {"Database", "string"}, - {"MongoDb", "ptr"}, -} - -func TestCheckBaseDao(t *testing.T) { - d := BaseDAO{} - for index, testData := range baseDaoTestTable { - givenType := reflect.TypeOf(d).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestConnectDb(t *testing.T) { - d := BaseDAO{} - d.Connect() - if d.MongoDb == nil { - t.Fail() - } -} - -func TestDatabasesConfig(t *testing.T) { - kontorDb := KontorDb - if kontorDb.Server != "localhost" { - t.Fail() - } - if kontorDb.Database != "kontor" { - t.Fail() - } - testDb := TestDb - if testDb.Server != "localhost" { - t.Fail() - } - if testDb.Database != "kontor_test" { - t.Fail() - } -} diff --git a/go/pkg/infrastructure/app/factory.go b/go/pkg/infrastructure/app/factory.go deleted file mode 100644 index 3bc8ce7..0000000 --- a/go/pkg/infrastructure/app/factory.go +++ /dev/null @@ -1,50 +0,0 @@ -package app - -import ( - "context" - "fmt" - "net/http" - "os" - "os/signal" - "syscall" - "time" - - "github.com/gorilla/mux" - "gitlab.com/tpeetz-kontor/kontor-go/pkg/infrastructure/config" - "go.uber.org/zap" -) - -// Application is our general purpose Application struct -type Application struct { - Server *http.Server - Router *mux.Router - Logger *zap.Logger - Config *config.Config -} - -// Run will run the Application server -func (app *Application) Run() { - app.Logger.Info("App started...") - err := app.Server.ListenAndServe() - - if err != nil { - fmt.Println(err) - } -} - -// WaitForShutdown is a graceful way to handle server shutdown events -func WaitForShutdown(application *Application) { - // Create a channel to listen for OS signals - interruptChan := make(chan os.Signal, 1) - signal.Notify(interruptChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - - // Block until we receive a signal to our channel - <-interruptChan - - application.Logger.Info("Received shutdown signal, gracefully terminating") - - ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) - defer cancel() - application.Server.Shutdown(ctx) - os.Exit(0) -} diff --git a/go/pkg/infrastructure/config/factory.go b/go/pkg/infrastructure/config/factory.go deleted file mode 100644 index ec411f8..0000000 --- a/go/pkg/infrastructure/config/factory.go +++ /dev/null @@ -1,48 +0,0 @@ -package config - -import "os" - -// AppConfig is the Application configuration struct -type AppConfig struct { - Name string - Version string - Token string -} - -// HTTPConfig is the Application HTTP configuration -type HTTPConfig struct { - Content string - Problem string - Port string -} - -// Config is the Configuration struct -type Config struct { - App AppConfig - HTTP HTTPConfig -} - -// New returns a new Config Struct -func New() *Config { - return &Config{ - App: AppConfig{ - Name: env("APP_NAME", "Kontor"), - Version: env("APP_VERSION", "v1.0"), - Token: env("APP_TOKEN", ""), - }, - HTTP: HTTPConfig{ - Content: env("HTTP_CONTENT_TYPE", "application/json"), - Problem: env("HTTP_PROBLEM", "application/problem+json"), - Port: env("HTTP_PORT", ":8086"), - }, - } -} - -// env is a simple helper function to read an environment variable or return a default value -func env(key string, defaultValue string) string { - if value, exists := os.LookupEnv(key); exists { - return value - } - - return defaultValue -} diff --git a/go/pkg/infrastructure/kernel/app.go b/go/pkg/infrastructure/kernel/app.go deleted file mode 100644 index 39eb5b7..0000000 --- a/go/pkg/infrastructure/kernel/app.go +++ /dev/null @@ -1,91 +0,0 @@ -package kernel - -import ( - "context" - "net/http" - "time" - - "github.com/google/uuid" - gohandlers "github.com/gorilla/handlers" - "github.com/gorilla/mux" - "gitlab.com/tpeetz-kontor/kontor-go/pkg/infrastructure/app" - "gitlab.com/tpeetz-kontor/kontor-go/pkg/infrastructure/config" - "go.uber.org/zap" -) - -// Boot the Application -func Boot() *app.Application { - // Configuration - config := bootConfig() - - // Router - router := bootRouter() - - // CORS - corsHandler := gohandlers.CORS(gohandlers.AllowedOrigins([]string{"*"})) - - // Logger - logger := bootLogger() - defer logger.Sync() // flushes buffer, if any - - // Create and return and Application - return &app.Application{ - Server: &http.Server{ - Addr: config.HTTP.Port, - Handler: corsHandler(requestIDMiddleware(router)), - IdleTimeout: 120 * time.Second, - ReadTimeout: 1 * time.Second, - WriteTimeout: 1 * time.Second, - }, - Router: router, - Logger: logger, - Config: config, - } -} - -func bootConfig() *config.Config { - return config.New() -} - -func bootRouter() *mux.Router { - return mux.NewRouter() -} - -func bootLogger() *zap.Logger { - logger, logError := zap.NewProduction() - if logError != nil { - panic(logError) - } - - return logger -} - -// ContextKey is used for context.Context value. The value requires a key that is not primitive type. -type ContextKey string - -// ContextKeyRequestID is the ContextKey for RequestID -const ContextKeyRequestID ContextKey = "requestID" - -func requestIDMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - - ctx := r.Context() - - id := uuid.New() - - ctx = context.WithValue(ctx, ContextKeyRequestID, id.String()) - - r = r.WithContext(ctx) - - bootLogger().Debug("Incoming request", - zap.String("method", r.Method), - zap.String("uri", r.RequestURI), - zap.String("addr", r.RemoteAddr), zap.String("id", id.String()), - ) - - next.ServeHTTP(w, r) - - bootLogger().Debug("Finished handling http req. %s", - zap.String("id", id.String())) - }) -} diff --git a/go/pkg/infrastructure/response/response.go b/go/pkg/infrastructure/response/response.go deleted file mode 100644 index f8def4a..0000000 --- a/go/pkg/infrastructure/response/response.go +++ /dev/null @@ -1,20 +0,0 @@ -package response - -import ( - "encoding/json" - "net/http" -) - -// Response is a generic HTTP Response Struct -type Response struct { - Data string `json:"data"` -} - -// Send a HTTP Response -func Send(responseWriter http.ResponseWriter, code int, payload interface{}, contentType string) { - response, _ := json.Marshal(payload) - - responseWriter.Header().Set("Content-Type", contentType) - responseWriter.WriteHeader(code) - responseWriter.Write(response) -} diff --git a/go/pkg/library/author.go b/go/pkg/library/author.go deleted file mode 100644 index 2aafcd7..0000000 --- a/go/pkg/library/author.go +++ /dev/null @@ -1,12 +0,0 @@ -package library - -import ( - "gopkg.in/mgo.v2/bson" -) - -// Author defines the data model for library authors with id and name. -type Author struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Name string `json:"name" bson:"name"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/library/author_dao.go b/go/pkg/library/author_dao.go deleted file mode 100644 index aa5f189..0000000 --- a/go/pkg/library/author_dao.go +++ /dev/null @@ -1,74 +0,0 @@ -package library - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// AuthorDAO extends the type BaseDAO. -type AuthorDAO struct { - Db dao.BaseDAO -} - -const ( - // AUTHORCOLLECTION defines the collection name for storing authors. - AUTHORCOLLECTION = "author" - // AUTHORMODEL defines the name of the author data model. - AUTHORMODEL = "kontor.library.author" -) - -// FindAll retrieves the list of authors from the database. -func (m *AuthorDAO) FindAll() ([]Author, error) { - m.Db.Connect() - var authors []Author - err := m.Db.MongoDb.C(AUTHORCOLLECTION).Find(bson.M{"model": AUTHORMODEL}).All(&authors) - return authors, err -} - -// FindByID returns an author with given id or returns the error. -func (m *AuthorDAO) FindByID(id string) (Author, error) { - m.Db.Connect() - var author Author - err := m.Db.MongoDb.C(AUTHORCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&author) - return author, err -} - -// FindByName returns an author with given name or returns the error. -func (m *AuthorDAO) FindByName(name string) (Author, error) { - m.Db.Connect() - var author Author - err := m.Db.MongoDb.C(AUTHORCOLLECTION).Find(bson.M{"name": name, "model": AUTHORMODEL}).One(&author) - return author, err -} - -// Insert a author into database. -func (m *AuthorDAO) Insert(author Author) error { - m.Db.Connect() - author.Model = AUTHORMODEL - err := m.Db.MongoDb.C(AUTHORCOLLECTION).Insert(&author) - return err -} - -// Upsert a author into database. -func (m *AuthorDAO) Upsert(author Author) (*mgo.ChangeInfo, error) { - m.Db.Connect() - author.Model = AUTHORMODEL - info, err := m.Db.MongoDb.C(AUTHORCOLLECTION).Upsert(bson.M{"name": author.Name}, &author) - return info, err -} - -// Delete an existing author. -func (m *AuthorDAO) Delete(author Author) error { - m.Db.Connect() - err := m.Db.MongoDb.C(AUTHORCOLLECTION).Remove(&author) - return err -} - -// Update an existing author. -func (m *AuthorDAO) Update(author Author) error { - m.Db.Connect() - err := m.Db.MongoDb.C(AUTHORCOLLECTION).UpdateId(author.ID, &author) - return err -} diff --git a/go/pkg/library/author_test.go b/go/pkg/library/author_test.go deleted file mode 100644 index 54a6537..0000000 --- a/go/pkg/library/author_test.go +++ /dev/null @@ -1,99 +0,0 @@ -package library - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var authorModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Name", "string"}, - {"Model", "string"}, -} - -func TestAuthorModel(t *testing.T) { - m := Author{} - if reflect.TypeOf(m).NumField() != len(authorModelTestTable) { - t.Fail() - } - for index, testData := range authorModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListAuthors(t *testing.T) { - var ( - authorDao = AuthorDAO{Db: dao.TestDb} - ) - authors, err := authorDao.FindAll() - if err != nil { - t.Fail() - } - if len(authors) != 0 { - t.Fail() - } -} - -func TestInsertAuthor(t *testing.T) { - var ( - authorDao = AuthorDAO{Db: dao.TestDb} - author = Author{} - authors []Author - ) - author.ID = bson.NewObjectId() - author.Name = "Packt Publishing" - err := authorDao.Insert(author) - if err != nil { - t.Fail() - } - authors, err = authorDao.FindAll() - if len(authors) != 1 { - t.Fail() - } -} - -func TestUpsertAuthor(t *testing.T) { - var ( - authorDao = AuthorDAO{Db: dao.TestDb} - ) - var author = Author{} - author.ID = bson.NewObjectId() - author.Name = "Hansa Verlag" - authorDao.Upsert(author) - authors, err := authorDao.FindAll() - if err != nil { - t.Fail() - } - if len(authors) != 2 { - t.Fail() - } -} - -func TestDeleteAuthor(t *testing.T) { - var ( - authorDao = AuthorDAO{Db: dao.TestDb} - ) - authors, err := authorDao.FindAll() - if err != nil { - t.Fail() - } - for _, author := range authors { - authorDao.Delete(author) - } - authors, err = authorDao.FindAll() - if err != nil { - t.Fail() - } - if len(authors) != 0 { - t.Fail() - } -} diff --git a/go/pkg/library/book.go b/go/pkg/library/book.go deleted file mode 100644 index 855f71c..0000000 --- a/go/pkg/library/book.go +++ /dev/null @@ -1,18 +0,0 @@ -package library - -import ( - "gopkg.in/mgo.v2/bson" -) - -// Book defines the data model for library books with id, title, author, publisher, -// isbn, year and edition. -type Book struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Title string `json:"title" bson:"title"` - Author string `json:"author" bson:"author"` - Publisher bson.ObjectId `json:"publisher" bson:"publisher,omitempty"` - Isbn string `json:"isbn" bson:"isbn,omitempty"` - Year int `json:"year" bson:"year,omitempty"` - Edition string `json:"edition" bson:"edition,omitempty"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/library/book_dao.go b/go/pkg/library/book_dao.go deleted file mode 100644 index ddfea6a..0000000 --- a/go/pkg/library/book_dao.go +++ /dev/null @@ -1,74 +0,0 @@ -package library - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// BookDAO extends the type BaseDAO. -type BookDAO struct { - Db dao.BaseDAO -} - -const ( - // BOOKCOLLECTION defines the collection name for storing books. - BOOKCOLLECTION = "book" - // BOOKMODEL defines the name of the book data model. - BOOKMODEL = "kontor.library.book" -) - -// FindAll retrieves the list of books from the database. -func (m *BookDAO) FindAll() ([]Book, error) { - m.Db.Connect() - var books []Book - err := m.Db.MongoDb.C(BOOKCOLLECTION).Find(bson.M{"model": BOOKMODEL}).All(&books) - return books, err -} - -// FindByID returns an book with given id or returns the error. -func (m *BookDAO) FindByID(id string) (Book, error) { - m.Db.Connect() - var book Book - err := m.Db.MongoDb.C(BOOKCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&book) - return book, err -} - -// FindByTitle returns a book with given title or returns the error. -func (m *BookDAO) FindByTitle(title string) (Book, error) { - m.Db.Connect() - var book Book - err := m.Db.MongoDb.C(BOOKCOLLECTION).Find(bson.M{"title": title, "model": BOOKMODEL}).One(&book) - return book, err -} - -// Insert a book into database. -func (m *BookDAO) Insert(book Book) error { - m.Db.Connect() - book.Model = BOOKMODEL - err := m.Db.MongoDb.C(BOOKCOLLECTION).Insert(&book) - return err -} - -// Upsert a book into database. -func (m *BookDAO) Upsert(book Book) (*mgo.ChangeInfo, error) { - m.Db.Connect() - book.Model = BOOKMODEL - info, err := m.Db.MongoDb.C(BOOKCOLLECTION).Upsert(bson.M{"title": book.Title}, &book) - return info, err -} - -// Delete an existing book. -func (m *BookDAO) Delete(book Book) error { - m.Db.Connect() - err := m.Db.MongoDb.C(BOOKCOLLECTION).Remove(&book) - return err -} - -// Update an existing book. -func (m *BookDAO) Update(book Book) error { - m.Db.Connect() - err := m.Db.MongoDb.C(BOOKCOLLECTION).UpdateId(book.ID, &book) - return err -} diff --git a/go/pkg/library/book_test.go b/go/pkg/library/book_test.go deleted file mode 100644 index 7a4f1f1..0000000 --- a/go/pkg/library/book_test.go +++ /dev/null @@ -1,107 +0,0 @@ -package library - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var bookModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Title", "string"}, - {"Author", "string"}, - {"Publisher", "string"}, - {"Isbn", "string"}, - {"Year", "int"}, - {"Edition", "string"}, - {"Model", "string"}, -} - -func TestBookModel(t *testing.T) { - m := Book{} - if reflect.TypeOf(m).NumField() != len(bookModelTestTable) { - t.Fail() - } - for index, testData := range bookModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListBooks(t *testing.T) { - var ( - bookDao = BookDAO{Db: dao.TestDb} - ) - books, err := bookDao.FindAll() - if err != nil { - t.Fail() - } - if len(books) != 0 { - t.Fail() - } -} - -func TestInsertBook(t *testing.T) { - var ( - bookDao = BookDAO{Db: dao.TestDb} - book = Book{} - books []Book - ) - book.ID = bson.NewObjectId() - book.Title = "Packt Publishing" - err := bookDao.Insert(book) - if err != nil { - t.Fail() - } - books, err = bookDao.FindAll() - if err != nil { - t.Fail() - } - if len(books) != 1 { - t.Fail() - } -} - -func TestUpsertBook(t *testing.T) { - var ( - bookDao = BookDAO{Db: dao.TestDb} - book = Book{} - ) - book.ID = bson.NewObjectId() - book.Title = "Hansa Verlag" - bookDao.Upsert(book) - books, err := bookDao.FindAll() - if err != nil { - t.Fail() - } - if len(books) != 2 { - t.Fail() - } -} - -func TestDeleteBook(t *testing.T) { - var ( - bookDao = BookDAO{Db: dao.TestDb} - ) - books, err := bookDao.FindAll() - if err != nil { - t.Fail() - } - for _, book := range books { - bookDao.Delete(book) - } - books, err = bookDao.FindAll() - if err != nil { - t.Fail() - } - if len(books) != 0 { - t.Fail() - } -} diff --git a/go/pkg/library/publisher.go b/go/pkg/library/publisher.go deleted file mode 100644 index b7eb84d..0000000 --- a/go/pkg/library/publisher.go +++ /dev/null @@ -1,12 +0,0 @@ -package library - -import ( - "gopkg.in/mgo.v2/bson" -) - -// Publisher defines the data model for library publishers with id and name. -type Publisher struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Name string `json:"name" bson:"name"` - Model string `json:"model" bson:"model"` -} diff --git a/go/pkg/library/publisher_dao.go b/go/pkg/library/publisher_dao.go deleted file mode 100644 index 0e48cf5..0000000 --- a/go/pkg/library/publisher_dao.go +++ /dev/null @@ -1,74 +0,0 @@ -package library - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// PublisherDAO extends the type BaseDAO. -type PublisherDAO struct { - Db dao.BaseDAO -} - -const ( - // PUBLISHERCOLLECTION defines the collection name for storing publishers. - PUBLISHERCOLLECTION = "publisher" - // PUBLISHERMODEL defines the name of the publisher data model. - PUBLISHERMODEL = "kontor.library.publisher" -) - -// FindAll retrieves the list of publishers from the database. -func (m *PublisherDAO) FindAll() ([]Publisher, error) { - m.Db.Connect() - var publishers []Publisher - err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).Find(bson.M{"model": PUBLISHERMODEL}).All(&publishers) - return publishers, err -} - -// FindByID returns an publisher with given id or returns the error. -func (m *PublisherDAO) FindByID(id string) (Publisher, error) { - m.Db.Connect() - var publisher Publisher - err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&publisher) - return publisher, err -} - -// FindByName returns an comic with given name or returns the error. -func (m *PublisherDAO) FindByName(name string) (Publisher, error) { - m.Db.Connect() - var publisher Publisher - err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).Find(bson.M{"name": name, "model": PUBLISHERMODEL}).One(&publisher) - return publisher, err -} - -// Insert a publisher into database. -func (m *PublisherDAO) Insert(publisher Publisher) error { - m.Db.Connect() - publisher.Model = PUBLISHERMODEL - err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).Insert(&publisher) - return err -} - -// Upsert a publisher into database. -func (m *PublisherDAO) Upsert(publisher Publisher) (*mgo.ChangeInfo, error) { - m.Db.Connect() - publisher.Model = PUBLISHERMODEL - info, err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).Upsert(bson.M{"name": publisher.Name}, &publisher) - return info, err -} - -// Delete an existing publisher. -func (m *PublisherDAO) Delete(publisher Publisher) error { - m.Db.Connect() - err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).Remove(&publisher) - return err -} - -// Update an existing publisher. -func (m *PublisherDAO) Update(publisher Publisher) error { - m.Db.Connect() - err := m.Db.MongoDb.C(PUBLISHERCOLLECTION).UpdateId(publisher.ID, &publisher) - return err -} diff --git a/go/pkg/library/publisher_test.go b/go/pkg/library/publisher_test.go deleted file mode 100644 index 1c680f3..0000000 --- a/go/pkg/library/publisher_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package library - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var publisherModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Name", "string"}, - {"Model", "string"}, -} - -func TestPublisherModel(t *testing.T) { - m := Publisher{} - if reflect.TypeOf(m).NumField() != len(publisherModelTestTable) { - t.Fail() - } - for index, testData := range publisherModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - - } -} - -func TestListPublishers(t *testing.T) { - var ( - publisherDao = PublisherDAO{Db: dao.TestDb} - ) - publishers, err := publisherDao.FindAll() - if err != nil { - t.Fail() - } - if len(publishers) != 0 { - t.Fail() - } -} - -func TestInsertPublisher(t *testing.T) { - var ( - publisherDao = PublisherDAO{Db: dao.TestDb} - publisher = Publisher{} - publishers []Publisher - ) - publisher.ID = bson.NewObjectId() - publisher.Name = "Packt Publishing" - err := publisherDao.Insert(publisher) - if err != nil { - t.Fail() - } - publishers, err = publisherDao.FindAll() - if err != nil { - t.Fail() - } - if len(publishers) != 1 { - t.Fail() - } -} - -func TestUpsertPublisher(t *testing.T) { - var ( - publisherDao = PublisherDAO{Db: dao.TestDb} - publisher = Publisher{} - ) - publisher.ID = bson.NewObjectId() - publisher.Name = "Hansa Verlag" - publisherDao.Upsert(publisher) - publishers, err := publisherDao.FindAll() - if err != nil { - t.Fail() - } - if len(publishers) != 2 { - t.Fail() - } -} - -func TestDeletePublisher(t *testing.T) { - var ( - publisherDao = PublisherDAO{Db: dao.TestDb} - ) - publishers, err := publisherDao.FindAll() - if err != nil { - t.Fail() - } - for _, publisher := range publishers { - publisherDao.Delete(publisher) - } - publishers, err = publisherDao.FindAll() - if err != nil { - t.Fail() - } - if len(publishers) != 0 { - t.Fail() - } -} diff --git a/go/pkg/library/publisher_views.go b/go/pkg/library/publisher_views.go deleted file mode 100644 index 233169a..0000000 --- a/go/pkg/library/publisher_views.go +++ /dev/null @@ -1,68 +0,0 @@ -package library - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/util" - "net/http" - - "github.com/gin-gonic/gin" -) - -const ( - // LibraryPublisherTemplate defines name of template file for comics publishers - LibraryPublisherTemplate = "library/publishers.html" -) - -func showPublisherList(c *gin.Context) { - var dao = PublisherDAO{Db: dao.KontorDb} - if publishers, err := dao.FindAll(); err == nil { - util.Render(c, gin.H{"title": "Library Publisher List", "payload": publishers}, LibraryPublisherTemplate) - } else { - c.AbortWithError(http.StatusNotFound, err) - } -} - -func showPublisherDetails(c *gin.Context) { - var dao = PublisherDAO{Db: dao.KontorDb} - publisherid := c.Param("publisher_id") - if publisher, err := dao.FindByID(publisherid); err == nil { - util.Render(c, gin.H{"title": "Library Publisher", "payload": publisher, "action": util.SaveAction}, LibraryPublisherTemplate) - } else { - c.AbortWithError(http.StatusNotFound, err) - } -} - -func showPublisherCreation(c *gin.Context) { - var publisher = Publisher{} - util.Render(c, gin.H{"title": "Library Publisher Creation", "payload": publisher, "action": util.AddAction}, LibraryPublisherTemplate) -} - -func validatePublisherDetails(c *gin.Context) { - name := c.PostForm("name") - action := c.PostForm("action") - publisherid := c.PostForm("publisherid") - - var err error - var dao = PublisherDAO{Db: dao.KontorDb} - var publisher = Publisher{} - - switch action { - case util.AddAction: - publisher.Name = name - _, err = dao.Upsert(publisher) - case util.SaveAction: - publisher, _ = dao.FindByID(publisherid) - publisher.Name = name - err = dao.Update(publisher) - case util.DeleteAction: - publisher, _ = dao.FindByID(publisherid) - err = dao.Delete(publisher) - } - if err == nil { - c.Redirect(http.StatusTemporaryRedirect, "/library/publisher") - } else { - c.HTML(http.StatusBadRequest, "library/publisher.html", gin.H{ - "ErrorTitle": "Publisher Creation Failed", - "ErrorMessage": err.Error()}) - } -} diff --git a/go/pkg/library/routes.go b/go/pkg/library/routes.go deleted file mode 100644 index ea93fd5..0000000 --- a/go/pkg/library/routes.go +++ /dev/null @@ -1,22 +0,0 @@ -package library - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/auth" - - "github.com/gin-gonic/gin" -) - -// GetRoutes returns all routes for library related data. -func GetRoutes(router *gin.Engine) { - libraryRoutes := router.Group("/library") - { - libraryRoutes.GET("/", auth.EnsureLoggedIn(), showBookList) - libraryRoutes.GET("/book", auth.EnsureLoggedIn(), showBookList) - libraryRoutes.GET("/author", auth.EnsureLoggedIn(), showAuthorList) - libraryRoutes.GET("/publisher", auth.EnsureLoggedIn(), showPublisherList) - libraryRoutes.POST("/publisher", auth.EnsureLoggedIn(), showPublisherList) - libraryRoutes.GET("/publisher/view/:publisher_id", auth.EnsureLoggedIn(), showPublisherDetails) - libraryRoutes.POST("/publisher/validate", auth.EnsureLoggedIn(), validatePublisherDetails) - libraryRoutes.GET("/publisher/create", auth.EnsureLoggedIn(), showPublisherCreation) - } -} diff --git a/go/pkg/library/views.go b/go/pkg/library/views.go deleted file mode 100644 index 4b4bcc6..0000000 --- a/go/pkg/library/views.go +++ /dev/null @@ -1,24 +0,0 @@ -package library - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/util" - - "github.com/gin-gonic/gin" -) - -func showAuthorList(c *gin.Context) { - var authorDao = AuthorDAO{Db: dao.KontorDb} - if authors, err := authorDao.FindAll(); err == nil { - util.Render(c, gin.H{"title": "Author List", "payload": authors}, "library/authors.html") - } -} - -func showBookList(c *gin.Context) { - var bookDao = BookDAO{Db: dao.KontorDb} - if books, err := bookDao.FindAll(); err == nil { - util.Render(c, gin.H{"title": "Book List", "payload": books}, "library/books.html") - } else { - util.Render(c, gin.H{"title": "Kontor", "payload": nil}, "kontor/index.html") - } -} diff --git a/go/pkg/office/routes.go b/go/pkg/office/routes.go deleted file mode 100644 index 8674071..0000000 --- a/go/pkg/office/routes.go +++ /dev/null @@ -1,13 +0,0 @@ -package office - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/auth" - - "github.com/gin-gonic/gin" -) - -// GetRoutes returns all routes for office related data. -func GetRoutes(router *gin.Engine) { - officeRoutes := router.Group("/office") - officeRoutes.GET("/", auth.EnsureLoggedIn(), showIndexPage) -} diff --git a/go/pkg/office/views.go b/go/pkg/office/views.go deleted file mode 100644 index 2fd1504..0000000 --- a/go/pkg/office/views.go +++ /dev/null @@ -1,11 +0,0 @@ -package office - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/util" - - "github.com/gin-gonic/gin" -) - -func showIndexPage(c *gin.Context) { - util.Render(c, gin.H{"title": "Home Office", "payload": nil}, "office/index.html") -} diff --git a/go/pkg/properties/root.go b/go/pkg/properties/root.go deleted file mode 100644 index c80e136..0000000 --- a/go/pkg/properties/root.go +++ /dev/null @@ -1,25 +0,0 @@ -package properties - -var ( - // Version defines the version of the web application kontor. - Version = "undefined" - // Debug defines the property debug to be used for more verbose output. - Debug = false - // Port defines port number under the web application is reachable. - Port = 8500 -) - -// SetVersion sets Version with given value. -func SetVersion(value string) { - Version = value -} - -// SetDebug sets Debug with given value. -func SetDebug(value bool) { - Debug = value -} - -// SetPort sets Port with given value. -func SetPort(value int) { - Port = value -} diff --git a/go/pkg/setup/data.go b/go/pkg/setup/data.go deleted file mode 100644 index e45e813..0000000 --- a/go/pkg/setup/data.go +++ /dev/null @@ -1,20 +0,0 @@ -package setup - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/tysc" - "log" -) - -// CheckTradeYourSportsCardsData checks if the TYSC releated data is available. -func CheckTradeYourSportsCardsData() { - log.Printf("Check data for TradeYourSportsCards module") - var sport = tysc.SportDAO{Db: dao.KontorDb} - sport.Upsert(tysc.Sport{Name: "Football"}) - football, _ := sport.FindByName("Football") - sport.Upsert(tysc.Sport{Name: "Baseball"}) - sport.Upsert(tysc.Sport{Name: "Basketball"}) - sport.Upsert(tysc.Sport{Name: "Hockey"}) - var position = tysc.PositionDAO{Db: dao.KontorDb} - position.Upsert(tysc.Position{Name: "WR", Description: "Wide Receiver", Sport: football.ID}) -} diff --git a/go/pkg/setup/routes.go b/go/pkg/setup/routes.go deleted file mode 100644 index 3b1a9b6..0000000 --- a/go/pkg/setup/routes.go +++ /dev/null @@ -1,38 +0,0 @@ -package setup - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/admin" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/auth" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/comics" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/library" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/office" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/tradingcards" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/tysc" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/util" - - "github.com/gin-gonic/gin" -) - -// InitializeRoutes setup the routes for Kontor web application. -func InitializeRoutes(router *gin.Engine) { - - // Use the setUserStatus middleware for every route to set a flag - // indicating whether the request was from an authenticated user or not - router.Use(auth.SetSessionStatus()) - - // Handle the index route - router.GET("/", util.ShowIndexPage) - - userRoutes := router.Group("/user") - { - userRoutes.GET("/login", auth.EnsureNotLoggedIn(), admin.ShowLoginPage) - userRoutes.POST("/login", auth.EnsureNotLoggedIn(), admin.PerformLogin) - userRoutes.GET("/logout", auth.EnsureLoggedIn(), admin.Logout) - } - admin.GetRoutes(router) - comics.GetRoutes(router) - library.GetRoutes(router) - office.GetRoutes(router) - tradingcards.GetRoutes(router) - tysc.GetRoutes(router) -} diff --git a/go/pkg/setup/session.go b/go/pkg/setup/session.go deleted file mode 100644 index 5fe184a..0000000 --- a/go/pkg/setup/session.go +++ /dev/null @@ -1,15 +0,0 @@ -package setup - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/auth" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" -) - -// CleanupSessions removes all sessions from database. -func CleanupSessions() { - sessionDao := auth.SessionDAO{Db: dao.KontorDb} - sessions, _ := sessionDao.FindAll() - for _, session := range sessions { - sessionDao.Delete(session) - } -} diff --git a/go/pkg/setup/user.go b/go/pkg/setup/user.go deleted file mode 100644 index 5272ed3..0000000 --- a/go/pkg/setup/user.go +++ /dev/null @@ -1,20 +0,0 @@ -package setup - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/admin" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - "gopkg.in/mgo.v2/bson" -) - -// CheckUserList ensures that at least the admin user is available. -func CheckUserList() { - var userDao = admin.UserDAO{Db: dao.KontorDb} - users, err := userDao.FindAll() - if err == nil && len(users) == 0 { - password, _ := admin.HashPassword("admin") - id := bson.NewObjectId() - user := admin.User{ID: id, Username: "admin", Password: password, Firstname: "Administrator", IsAdmin: true} - userDao.Insert(user) - } -} diff --git a/go/pkg/tradingcards/routes.go b/go/pkg/tradingcards/routes.go deleted file mode 100644 index d5d3aad..0000000 --- a/go/pkg/tradingcards/routes.go +++ /dev/null @@ -1,13 +0,0 @@ -package tradingcards - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/auth" - - "github.com/gin-gonic/gin" -) - -// GetRoutes returns all routes for tradingcards related data. -func GetRoutes(router *gin.Engine) { - tradingCardsRoutes := router.Group("/tradingcards") - tradingCardsRoutes.GET("/", auth.EnsureLoggedIn(), showIndexPage) -} diff --git a/go/pkg/tradingcards/views.go b/go/pkg/tradingcards/views.go deleted file mode 100644 index 1d4f104..0000000 --- a/go/pkg/tradingcards/views.go +++ /dev/null @@ -1,11 +0,0 @@ -package tradingcards - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/util" - - "github.com/gin-gonic/gin" -) - -func showIndexPage(c *gin.Context) { - util.Render(c, gin.H{"title": "Trading Cards", "payload": nil}, "tradingcards/index.html") -} diff --git a/go/pkg/tysc/card.go b/go/pkg/tysc/card.go deleted file mode 100644 index e2555b5..0000000 --- a/go/pkg/tysc/card.go +++ /dev/null @@ -1,20 +0,0 @@ -package tysc - -import ( - "gopkg.in/mgo.v2/bson" -) - -// Card defines the data model for TYSC cards. -type Card struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Player bson.ObjectId `json:"player" bson:"player,omitempty"` - Team bson.ObjectId `json:"team" bson:"team,omitempty"` - Manufacturer bson.ObjectId `json:"manufacturer" bson:"manufacturer,omitempty"` - CardSet bson.ObjectId `json:"cardset" bson:"cardset,omitempty"` - ParallelSet bson.ObjectId `json:"parallelset" bson:"paralelset,omitempty"` - InsertSet bson.ObjectId `json:"insertset" bson:"insertset,omitempty"` - Rookie bool `json:"rookie" bson:"rookie,omitempty"` - Year int `json:"year" bson:"year,omitempty"` - Number int `json:"number" bson:"number,omitempty"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/tysc/card_dao.go b/go/pkg/tysc/card_dao.go deleted file mode 100644 index 8fa4d4b..0000000 --- a/go/pkg/tysc/card_dao.go +++ /dev/null @@ -1,66 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// CardDAO extends the type BaseDAO. -type CardDAO struct { - Db dao.BaseDAO -} - -const ( - // CARDCOLLECTION defines the collection name for storing cards. - CARDCOLLECTION = "card" - // CARDMODEL defines the name of the card data model. - CARDMODEL = "kontor.tysc.card" -) - -// FindAll retrieves the list of cards from the database. -func (m *CardDAO) FindAll() ([]Card, error) { - m.Db.Connect() - var cards []Card - err := m.Db.MongoDb.C(CARDCOLLECTION).Find(bson.M{"model": CARDMODEL}).All(&cards) - return cards, err -} - -// FindByID returns an card with given id or returns the error. -func (m *CardDAO) FindByID(id string) (Card, error) { - m.Db.Connect() - var card Card - err := m.Db.MongoDb.C(CARDCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&card) - return card, err -} - -// Insert a card into database. -func (m *CardDAO) Insert(card Card) error { - m.Db.Connect() - card.Model = CARDMODEL - err := m.Db.MongoDb.C(CARDCOLLECTION).Insert(&card) - return err -} - -// Upsert a card into database. -func (m *CardDAO) Upsert(card Card) (*mgo.ChangeInfo, error) { - m.Db.Connect() - card.Model = CARDMODEL - info, err := m.Db.MongoDb.C(CARDCOLLECTION).Upsert(bson.M{"number": card.Number}, &card) - return info, err -} - -// Update an existing card. -func (m *CardDAO) Update(card Card) error { - m.Db.Connect() - err := m.Db.MongoDb.C(CARDCOLLECTION).UpdateId(card.ID, &card) - return err -} - -// Delete an existing card. -func (m *CardDAO) Delete(card Card) error { - m.Db.Connect() - err := m.Db.MongoDb.C(CARDCOLLECTION).Remove(&card) - return err -} diff --git a/go/pkg/tysc/card_test.go b/go/pkg/tysc/card_test.go deleted file mode 100644 index e5c0afb..0000000 --- a/go/pkg/tysc/card_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var cardModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Player", "string"}, - {"Team", "string"}, - {"Manufacturer", "string"}, - {"CardSet", "string"}, - {"ParallelSet", "string"}, - {"InsertSet", "string"}, - {"Rookie", "bool"}, - {"Year", "int"}, - {"Number", "int"}, - {"Model", "string"}, -} - -func TestCardModel(t *testing.T) { - m := Card{} - if reflect.TypeOf(m).NumField() != len(cardModelTestTable) { - t.Fail() - } - for index, testData := range cardModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListCards(t *testing.T) { - var ( - cardDao = CardDAO{Db: dao.TestDb} - ) - cards, err := cardDao.FindAll() - if err != nil { - t.Fail() - } - if len(cards) != 0 { - t.Fail() - } -} - -func TestInsertCard(t *testing.T) { - var ( - cardDao = CardDAO{Db: dao.TestDb} - card = Card{} - cards []Card - ) - card.ID = bson.NewObjectId() - card.Number = 1 - err := cardDao.Insert(card) - if err != nil { - t.Fail() - } - cards, err = cardDao.FindAll() - if err != nil { - t.Fail() - } - if len(cards) != 1 { - t.Fail() - } -} - -func TestUpsertCard(t *testing.T) { - var ( - cardDao = CardDAO{Db: dao.TestDb} - card = Card{} - ) - card.ID = bson.NewObjectId() - card.Number = 2 - cardDao.Upsert(card) - cards, err := cardDao.FindAll() - if err != nil { - t.Fail() - } - if len(cards) != 2 { - t.Fail() - } -} - -func TestDeleteCard(t *testing.T) { - var ( - cardDao = CardDAO{Db: dao.TestDb} - ) - cards, err := cardDao.FindAll() - if err != nil { - t.Fail() - } - for _, card := range cards { - cardDao.Delete(card) - } - cards, err = cardDao.FindAll() - if err != nil { - t.Fail() - } - if len(cards) != 0 { - t.Fail() - } -} diff --git a/go/pkg/tysc/cardset.go b/go/pkg/tysc/cardset.go deleted file mode 100644 index 6184a11..0000000 --- a/go/pkg/tysc/cardset.go +++ /dev/null @@ -1,13 +0,0 @@ -package tysc - -import ( - "gopkg.in/mgo.v2/bson" -) - -// CardSet defines the data model for TYSC card sets with id, name and manufacturer. -type CardSet struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Name string `json:"name" bson:"name"` - Manufacturer bson.ObjectId `json:"manufacturer" bson:"manufacturer,omitempty"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/tysc/cardset_dao.go b/go/pkg/tysc/cardset_dao.go deleted file mode 100644 index 4158860..0000000 --- a/go/pkg/tysc/cardset_dao.go +++ /dev/null @@ -1,82 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// CardSetDAO extends the type BaseDAO. -type CardSetDAO struct { - Db dao.BaseDAO -} - -const ( - // CARDSETCOLLECTION defines the collection name for storing cards sets. - CARDSETCOLLECTION = "cardSet" - // CARDSETMODEL defines the name of the card set data model. - CARDSETMODEL = "kontor.tysc.cardSet" -) - -// FindAll retrieves the list of card sets from the database. -func (m *CardSetDAO) FindAll() ([]CardSet, error) { - m.Db.Connect() - var cardSets []CardSet - err := m.Db.MongoDb.C(CARDSETCOLLECTION).Find(bson.M{"model": CARDSETMODEL}).All(&cardSets) - return cardSets, err -} - -// FindByID returns a card set with given id or returns the error. -func (m *CardSetDAO) FindByID(id string) (CardSet, error) { - m.Db.Connect() - var cardSet CardSet - err := m.Db.MongoDb.C(CARDSETCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&cardSet) - return cardSet, err -} - -// FindByManufacturer returns a card set with given manufacturer or returns the error. -func (m *CardSetDAO) FindByManufacturer(manufacturer string) ([]CardSet, error) { - m.Db.Connect() - var cardSets []CardSet - err := m.Db.MongoDb.C(CARDSETCOLLECTION).Find(bson.M{"model": CARDSETMODEL, "manufacturer": bson.ObjectIdHex(manufacturer)}).All(&cardSets) - return cardSets, err -} - -// FindByName returns a card set with given name or returns the error. -func (m *CardSetDAO) FindByName(name string) (CardSet, error) { - m.Db.Connect() - var cardSet CardSet - err := m.Db.MongoDb.C(CARDSETCOLLECTION).Find(bson.M{"name": name, "model": CARDSETMODEL}).One(&cardSet) - return cardSet, err -} - -// Insert an card set into database. -func (m *CardSetDAO) Insert(cardSet CardSet) error { - m.Db.Connect() - cardSet.Model = CARDSETMODEL - err := m.Db.MongoDb.C(CARDSETCOLLECTION).Insert(&cardSet) - return err -} - -// Upsert an card set into database. -func (m *CardSetDAO) Upsert(cardSet CardSet) (*mgo.ChangeInfo, error) { - m.Db.Connect() - cardSet.Model = CARDSETMODEL - info, err := m.Db.MongoDb.C(CARDSETCOLLECTION).Upsert(bson.M{"name": cardSet.Name}, &cardSet) - return info, err -} - -// Update an existing card set. -func (m *CardSetDAO) Update(cardSet CardSet) error { - m.Db.Connect() - err := m.Db.MongoDb.C(CARDSETCOLLECTION).UpdateId(cardSet.ID, &cardSet) - return err -} - -// Delete an existing card set. -func (m *CardSetDAO) Delete(cardSet CardSet) error { - m.Db.Connect() - err := m.Db.MongoDb.C(CARDSETCOLLECTION).Remove(&cardSet) - return err -} diff --git a/go/pkg/tysc/cardset_test.go b/go/pkg/tysc/cardset_test.go deleted file mode 100644 index 82d7ebc..0000000 --- a/go/pkg/tysc/cardset_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var cardsetModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Name", "string"}, - {"Manufacturer", "string"}, - {"Model", "string"}, -} - -func TestCardSetModel(t *testing.T) { - m := CardSet{} - if reflect.TypeOf(m).NumField() != len(cardsetModelTestTable) { - t.Fail() - } - for index, testData := range cardsetModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListCardSets(t *testing.T) { - var ( - cardsetDao = CardSetDAO{Db: dao.TestDb} - ) - cardSets, err := cardsetDao.FindAll() - if err != nil { - t.Fail() - } - if len(cardSets) != 0 { - t.Fail() - } -} - -func TestInsertCardSet(t *testing.T) { - var ( - cardsetDao = CardSetDAO{Db: dao.TestDb} - cardSet = CardSet{} - cardSets []CardSet - ) - cardSet.ID = bson.NewObjectId() - cardSet.Name = "test" - err := cardsetDao.Insert(cardSet) - if err != nil { - t.Fail() - } - cardSets, err = cardsetDao.FindAll() - if err != nil { - t.Fail() - } - if len(cardSets) != 1 { - t.Fail() - } -} - -func TestUpsertCardSet(t *testing.T) { - var ( - cardsetDao = CardSetDAO{Db: dao.TestDb} - cardSet = CardSet{} - ) - cardSet.ID = bson.NewObjectId() - cardSet.Name = "test2" - cardsetDao.Upsert(cardSet) - cardSets, err := cardsetDao.FindAll() - if err != nil { - t.Fail() - } - if len(cardSets) != 2 { - t.Fail() - } -} - -func TestDeleteCardSet(t *testing.T) { - var ( - cardsetDao = CardSetDAO{Db: dao.TestDb} - ) - cardSets, err := cardsetDao.FindAll() - if err != nil { - t.Fail() - } - for _, cardSet := range cardSets { - cardsetDao.Delete(cardSet) - } - cardSets, err = cardsetDao.FindAll() - if err != nil { - t.Fail() - } - if len(cardSets) != 0 { - t.Fail() - } -} diff --git a/go/pkg/tysc/insertset.go b/go/pkg/tysc/insertset.go deleted file mode 100644 index 8655d35..0000000 --- a/go/pkg/tysc/insertset.go +++ /dev/null @@ -1,13 +0,0 @@ -package tysc - -import ( - "gopkg.in/mgo.v2/bson" -) - -// InsertSet defines the data model for TYSC inserts sets with id, name and manufacturer. -type InsertSet struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Name string `json:"name" bson:"name"` - Manufacturer bson.ObjectId `json:"manufacturer" bson:"manufacturer,omitempty"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/tysc/insertset_dao.go b/go/pkg/tysc/insertset_dao.go deleted file mode 100644 index dc87ddf..0000000 --- a/go/pkg/tysc/insertset_dao.go +++ /dev/null @@ -1,82 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// InsertSetDAO extends the type BaseDAO. -type InsertSetDAO struct { - Db dao.BaseDAO -} - -const ( - // INSERTSETCOLLECTION defines the collection name for storing insert sets. - INSERTSETCOLLECTION = "insertSet" - // INSERTSETMODEL defines the name of the insert set data model. - INSERTSETMODEL = "kontor.tysc.insertSet" -) - -// FindAll retrieves the list of cards from the database. -func (m *InsertSetDAO) FindAll() ([]InsertSet, error) { - m.Db.Connect() - var insertSets []InsertSet - err := m.Db.MongoDb.C(INSERTSETCOLLECTION).Find(bson.M{"model": INSERTSETMODEL}).All(&insertSets) - return insertSets, err -} - -// FindByID returns an card with given id or returns the error. -func (m *InsertSetDAO) FindByID(id string) (InsertSet, error) { - m.Db.Connect() - var insertSet InsertSet - err := m.Db.MongoDb.C(INSERTSETCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&insertSet) - return insertSet, err -} - -// FindByManufacturer returns a insert set with given manufacturer or returns the error. -func (m *InsertSetDAO) FindByManufacturer(manufacturer string) ([]InsertSet, error) { - m.Db.Connect() - var insertSets []InsertSet - err := m.Db.MongoDb.C(INSERTSETCOLLECTION).Find(bson.M{"model": INSERTSETMODEL, "manufacturer": bson.ObjectIdHex(manufacturer)}).All(&insertSets) - return insertSets, err -} - -// FindByName returns a insert set with given name or returns the error. -func (m *InsertSetDAO) FindByName(name string) (InsertSet, error) { - m.Db.Connect() - var insertSet InsertSet - err := m.Db.MongoDb.C(INSERTSETCOLLECTION).Find(bson.M{"name": name, "model": INSERTSETMODEL}).One(&insertSet) - return insertSet, err -} - -// Insert an insert set into database. -func (m *InsertSetDAO) Insert(insertSet InsertSet) error { - m.Db.Connect() - insertSet.Model = INSERTSETMODEL - err := m.Db.MongoDb.C(INSERTSETCOLLECTION).Insert(&insertSet) - return err -} - -// Upsert an insert set into database. -func (m *InsertSetDAO) Upsert(insertSet InsertSet) (*mgo.ChangeInfo, error) { - m.Db.Connect() - insertSet.Model = INSERTSETMODEL - info, err := m.Db.MongoDb.C(INSERTSETCOLLECTION).Upsert(bson.M{"name": insertSet.Name}, &insertSet) - return info, err -} - -// Update an existing insert set. -func (m *InsertSetDAO) Update(insertSet InsertSet) error { - m.Db.Connect() - err := m.Db.MongoDb.C(INSERTSETCOLLECTION).UpdateId(insertSet.ID, &insertSet) - return err -} - -// Delete an existing insert set. -func (m *InsertSetDAO) Delete(insertSet InsertSet) error { - m.Db.Connect() - err := m.Db.MongoDb.C(INSERTSETCOLLECTION).Remove(&insertSet) - return err -} diff --git a/go/pkg/tysc/insertset_test.go b/go/pkg/tysc/insertset_test.go deleted file mode 100644 index b4d4152..0000000 --- a/go/pkg/tysc/insertset_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var insertsetModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Name", "string"}, - {"Manufacturer", "string"}, - {"Model", "string"}, -} - -func TestInsertSetModel(t *testing.T) { - m := InsertSet{} - if reflect.TypeOf(m).NumField() != len(insertsetModelTestTable) { - t.Fail() - } - for index, testData := range insertsetModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListInsertSets(t *testing.T) { - var ( - insertsetDao = InsertSetDAO{Db: dao.TestDb} - ) - insertSets, err := insertsetDao.FindAll() - if err != nil { - t.Fail() - } - if len(insertSets) != 0 { - t.Fail() - } -} - -func TestInsertInsertSet(t *testing.T) { - var ( - insertsetDao = InsertSetDAO{Db: dao.TestDb} - insertSet = InsertSet{} - insertSets []InsertSet - ) - insertSet.ID = bson.NewObjectId() - insertSet.Name = "test" - err := insertsetDao.Insert(insertSet) - if err != nil { - t.Fail() - } - insertSets, err = insertsetDao.FindAll() - if err != nil { - t.Fail() - } - if len(insertSets) != 1 { - t.Fail() - } -} - -func TestUpsertInsertSet(t *testing.T) { - var ( - insertsetDao = InsertSetDAO{Db: dao.TestDb} - insertSet = InsertSet{} - ) - insertSet.ID = bson.NewObjectId() - insertSet.Name = "test2" - insertsetDao.Upsert(insertSet) - insertSets, err := insertsetDao.FindAll() - if err != nil { - t.Fail() - } - if len(insertSets) != 2 { - t.Fail() - } -} - -func TestDeleteInsertSet(t *testing.T) { - var ( - insertsetDao = InsertSetDAO{Db: dao.TestDb} - ) - insertSets, err := insertsetDao.FindAll() - if err != nil { - t.Fail() - } - for _, insertSet := range insertSets { - insertsetDao.Delete(insertSet) - } - insertSets, err = insertsetDao.FindAll() - if err != nil { - t.Fail() - } - if len(insertSets) != 0 { - t.Fail() - } -} diff --git a/go/pkg/tysc/manufacturer.go b/go/pkg/tysc/manufacturer.go deleted file mode 100644 index e4ccdc0..0000000 --- a/go/pkg/tysc/manufacturer.go +++ /dev/null @@ -1,12 +0,0 @@ -package tysc - -import ( - "gopkg.in/mgo.v2/bson" -) - -// Manufacturer defines the data model for TYSC manufacturers with id, and name. -type Manufacturer struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Name string `json:"name" bson:"name"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/tysc/manufacturer_dao.go b/go/pkg/tysc/manufacturer_dao.go deleted file mode 100644 index b23be11..0000000 --- a/go/pkg/tysc/manufacturer_dao.go +++ /dev/null @@ -1,74 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// ManufacturerDAO extends the type BaseDAO. -type ManufacturerDAO struct { - Db dao.BaseDAO -} - -const ( - // MANUFACTURERCOLLECTION defines the collection name for storing manufacturers. - MANUFACTURERCOLLECTION = "manufacturer" - // MANUFACTURERMODEL defines the name of the manufacturer data model. - MANUFACTURERMODEL = "kontor.tysc.manufacturer" -) - -// FindAll retrieves the list of manufacturers from the database. -func (m *ManufacturerDAO) FindAll() ([]Manufacturer, error) { - m.Db.Connect() - var manufacturers []Manufacturer - err := m.Db.MongoDb.C(MANUFACTURERCOLLECTION).Find(bson.M{"model": MANUFACTURERMODEL}).All(&manufacturers) - return manufacturers, err -} - -// FindByID returns a manufacturer with given id or returns the error. -func (m *ManufacturerDAO) FindByID(id string) (Manufacturer, error) { - m.Db.Connect() - var manufacturer Manufacturer - err := m.Db.MongoDb.C(MANUFACTURERCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&manufacturer) - return manufacturer, err -} - -// FindByName returns a manufacturer with given name or returns the error. -func (m *ManufacturerDAO) FindByName(name string) (Manufacturer, error) { - m.Db.Connect() - var manufacturer Manufacturer - err := m.Db.MongoDb.C(MANUFACTURERCOLLECTION).Find(bson.M{"name": name, "model": MANUFACTURERMODEL}).One(&manufacturer) - return manufacturer, err -} - -// Insert a manufacturer into database. -func (m *ManufacturerDAO) Insert(manufacturer Manufacturer) error { - m.Db.Connect() - manufacturer.Model = MANUFACTURERMODEL - err := m.Db.MongoDb.C(MANUFACTURERCOLLECTION).Insert(&manufacturer) - return err -} - -// Upsert a manufacturer into database. -func (m *ManufacturerDAO) Upsert(manufacturer Manufacturer) (*mgo.ChangeInfo, error) { - m.Db.Connect() - manufacturer.Model = MANUFACTURERMODEL - info, err := m.Db.MongoDb.C(MANUFACTURERCOLLECTION).Upsert(bson.M{"name": manufacturer.Name}, &manufacturer) - return info, err -} - -// Update an existing manufacturer. -func (m *ManufacturerDAO) Update(manufacturer Manufacturer) error { - m.Db.Connect() - err := m.Db.MongoDb.C(MANUFACTURERCOLLECTION).UpdateId(manufacturer.ID, &manufacturer) - return err -} - -// Delete an existing manufacturer. -func (m *ManufacturerDAO) Delete(manufacturer Manufacturer) error { - m.Db.Connect() - err := m.Db.MongoDb.C(MANUFACTURERCOLLECTION).Remove(&manufacturer) - return err -} diff --git a/go/pkg/tysc/manufacturer_test.go b/go/pkg/tysc/manufacturer_test.go deleted file mode 100644 index 9973beb..0000000 --- a/go/pkg/tysc/manufacturer_test.go +++ /dev/null @@ -1,102 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var manufacturerModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Name", "string"}, - {"Model", "string"}, -} - -func TestManufacturerModel(t *testing.T) { - m := Manufacturer{} - if reflect.TypeOf(m).NumField() != len(manufacturerModelTestTable) { - t.Fail() - } - for index, testData := range manufacturerModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListManufacturers(t *testing.T) { - var ( - manufacturerDao = ManufacturerDAO{Db: dao.TestDb} - ) - manufacturers, err := manufacturerDao.FindAll() - if err != nil { - t.Fail() - } - if len(manufacturers) != 0 { - t.Fail() - } -} - -func TestInsertManufacturer(t *testing.T) { - var ( - manufacturerDao = ManufacturerDAO{Db: dao.TestDb} - manufacturer = Manufacturer{} - manufacturers []Manufacturer - ) - manufacturer.ID = bson.NewObjectId() - manufacturer.Name = "test" - err := manufacturerDao.Insert(manufacturer) - if err != nil { - t.Fail() - } - manufacturers, err = manufacturerDao.FindAll() - if err != nil { - t.Fail() - } - if len(manufacturers) != 1 { - t.Fail() - } -} - -func TestUpsertManufacturer(t *testing.T) { - var ( - manufacturerDao = ManufacturerDAO{Db: dao.TestDb} - manufacturer = Manufacturer{} - ) - manufacturer.ID = bson.NewObjectId() - manufacturer.Name = "test2" - manufacturerDao.Upsert(manufacturer) - manufacturers, err := manufacturerDao.FindAll() - if err != nil { - t.Fail() - } - if len(manufacturers) != 2 { - t.Fail() - } -} - -func TestDeleteManufacturer(t *testing.T) { - var ( - manufacturerDao = ManufacturerDAO{Db: dao.TestDb} - ) - manufacturers, err := manufacturerDao.FindAll() - if err != nil { - t.Fail() - } - for _, manufacturer := range manufacturers { - manufacturerDao.Delete(manufacturer) - } - manufacturers, err = manufacturerDao.FindAll() - if err != nil { - t.Fail() - } - if len(manufacturers) != 0 { - t.Fail() - } -} diff --git a/go/pkg/tysc/parallelset.go b/go/pkg/tysc/parallelset.go deleted file mode 100644 index 78a93e2..0000000 --- a/go/pkg/tysc/parallelset.go +++ /dev/null @@ -1,13 +0,0 @@ -package tysc - -import ( - "gopkg.in/mgo.v2/bson" -) - -// ParallelSet defines the data model for TYSC parallel sets with id, name and manufacturer. -type ParallelSet struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Name string `json:"name" bson:"name"` - Manufacturer bson.ObjectId `json:"manufacturer" bson:"manufacturer,omitempty"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/tysc/parallelset_dao.go b/go/pkg/tysc/parallelset_dao.go deleted file mode 100644 index 0cadac3..0000000 --- a/go/pkg/tysc/parallelset_dao.go +++ /dev/null @@ -1,82 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// ParallelSetDAO extends the type BaseDAO. -type ParallelSetDAO struct { - Db dao.BaseDAO -} - -const ( - // PARALLELSETCOLLECTION defines the collection name for storing parallel sets. - PARALLELSETCOLLECTION = "parallelSet" - // PARALLELSETMODEL defines the name of the parallel set data model. - PARALLELSETMODEL = "kontor.tysc.parallelSet" -) - -// FindAll retrieves the list of parallel sets from the database. -func (m *ParallelSetDAO) FindAll() ([]ParallelSet, error) { - m.Db.Connect() - var parallelSets []ParallelSet - err := m.Db.MongoDb.C(PARALLELSETCOLLECTION).Find(bson.M{"model": PARALLELSETMODEL}).All(¶llelSets) - return parallelSets, err -} - -// FindByID returns a parallel set with given id or returns the error. -func (m *ParallelSetDAO) FindByID(id string) (ParallelSet, error) { - m.Db.Connect() - var parallelSet ParallelSet - err := m.Db.MongoDb.C(PARALLELSETCOLLECTION).FindId(bson.ObjectIdHex(id)).One(¶llelSet) - return parallelSet, err -} - -// FindByManufacturer returns a paralle set with given manufacturer or returns the error. -func (m *ParallelSetDAO) FindByManufacturer(manufacturer string) ([]ParallelSet, error) { - m.Db.Connect() - var parallelSets []ParallelSet - err := m.Db.MongoDb.C(PARALLELSETCOLLECTION).Find(bson.M{"model": PARALLELSETMODEL, "manufacturer": bson.ObjectIdHex(manufacturer)}).All(¶llelSets) - return parallelSets, err -} - -// FindByName returns a parallel set with given name or returns the error. -func (m *ParallelSetDAO) FindByName(name string) (ParallelSet, error) { - m.Db.Connect() - var parallelSet ParallelSet - err := m.Db.MongoDb.C(PARALLELSETCOLLECTION).Find(bson.M{"name": name, "model": PARALLELSETMODEL}).One(¶llelSet) - return parallelSet, err -} - -// Insert a parallel set into database. -func (m *ParallelSetDAO) Insert(parallelSet ParallelSet) error { - m.Db.Connect() - parallelSet.Model = PARALLELSETMODEL - err := m.Db.MongoDb.C(PARALLELSETCOLLECTION).Insert(¶llelSet) - return err -} - -// Upsert a parallel set into database. -func (m *ParallelSetDAO) Upsert(parallelSet ParallelSet) (*mgo.ChangeInfo, error) { - m.Db.Connect() - parallelSet.Model = PARALLELSETMODEL - info, err := m.Db.MongoDb.C(PARALLELSETCOLLECTION).Upsert(bson.M{"name": parallelSet.Name}, ¶llelSet) - return info, err -} - -// Update an existing parallel set. -func (m *ParallelSetDAO) Update(parallelSet ParallelSet) error { - m.Db.Connect() - err := m.Db.MongoDb.C(PARALLELSETCOLLECTION).UpdateId(parallelSet.ID, ¶llelSet) - return err -} - -// Delete an existing parallel set. -func (m *ParallelSetDAO) Delete(parallelSet ParallelSet) error { - m.Db.Connect() - err := m.Db.MongoDb.C(PARALLELSETCOLLECTION).Remove(¶llelSet) - return err -} diff --git a/go/pkg/tysc/parallelset_test.go b/go/pkg/tysc/parallelset_test.go deleted file mode 100644 index e0a9c2b..0000000 --- a/go/pkg/tysc/parallelset_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var parallelsetModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Name", "string"}, - {"Manufacturer", "string"}, - {"Model", "string"}, -} - -func TestParallelSetModel(t *testing.T) { - m := ParallelSet{} - if reflect.TypeOf(m).NumField() != len(parallelsetModelTestTable) { - t.Fail() - } - for index, testData := range parallelsetModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListParallelSets(t *testing.T) { - var ( - parallelsetDao = ParallelSetDAO{Db: dao.TestDb} - ) - parallelSets, err := parallelsetDao.FindAll() - if err != nil { - t.Fail() - } - if len(parallelSets) != 0 { - t.Fail() - } -} - -func TestInsertParallelSet(t *testing.T) { - var ( - parallelsetDao = ParallelSetDAO{Db: dao.TestDb} - parallelSet = ParallelSet{} - parallelSets []ParallelSet - ) - parallelSet.ID = bson.NewObjectId() - parallelSet.Name = "test" - err := parallelsetDao.Insert(parallelSet) - if err != nil { - t.Fail() - } - parallelSets, err = parallelsetDao.FindAll() - if err != nil { - t.Fail() - } - if len(parallelSets) != 1 { - t.Fail() - } -} - -func TestUpsertParallelSet(t *testing.T) { - var ( - parallelsetDao = ParallelSetDAO{Db: dao.TestDb} - parallelSet = ParallelSet{} - ) - parallelSet.ID = bson.NewObjectId() - parallelSet.Name = "test2" - parallelsetDao.Upsert(parallelSet) - parallelSets, err := parallelsetDao.FindAll() - if err != nil { - t.Fail() - } - if len(parallelSets) != 2 { - t.Fail() - } -} - -func TestDeleteParallelSet(t *testing.T) { - var ( - parallelsetDao = ParallelSetDAO{Db: dao.TestDb} - ) - parallelSets, err := parallelsetDao.FindAll() - if err != nil { - t.Fail() - } - for _, parallelSet := range parallelSets { - parallelsetDao.Delete(parallelSet) - } - parallelSets, err = parallelsetDao.FindAll() - if err != nil { - t.Fail() - } - if len(parallelSets) != 0 { - t.Fail() - } -} diff --git a/go/pkg/tysc/player.go b/go/pkg/tysc/player.go deleted file mode 100644 index 055efe6..0000000 --- a/go/pkg/tysc/player.go +++ /dev/null @@ -1,13 +0,0 @@ -package tysc - -import ( - "gopkg.in/mgo.v2/bson" -) - -// Player defines the data model for TYSC players with id, first and lastname. -type Player struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Firstname string `json:"firstname" bson:"firstname"` - Lastname string `json:"lastname" bson:"lastname"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/tysc/player_dao.go b/go/pkg/tysc/player_dao.go deleted file mode 100644 index ff60c37..0000000 --- a/go/pkg/tysc/player_dao.go +++ /dev/null @@ -1,74 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// PlayerDAO extends the type BaseDAO. -type PlayerDAO struct { - Db dao.BaseDAO -} - -const ( - // PLAYERCOLLECTION defines the collection name for storing players. - PLAYERCOLLECTION = "player" - // PLAYERMODEL defines the name of the player data model. - PLAYERMODEL = "kontor.tysc.player" -) - -// FindAll retrieves the list of players from the database. -func (m *PlayerDAO) FindAll() ([]Player, error) { - m.Db.Connect() - var players []Player - err := m.Db.MongoDb.C(PLAYERCOLLECTION).Find(bson.M{"model": PLAYERMODEL}).All(&players) - return players, err -} - -// FindByID returns a player with given id or returns the error. -func (m *PlayerDAO) FindByID(id string) (Player, error) { - m.Db.Connect() - var player Player - err := m.Db.MongoDb.C(PLAYERCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&player) - return player, err -} - -// FindByLastName returns a player with given last name or returns the error. -func (m *PlayerDAO) FindByLastName(lastname string) (Player, error) { - m.Db.Connect() - var player Player - err := m.Db.MongoDb.C(PLAYERCOLLECTION).Find(bson.M{"lastname": lastname, "model": PLAYERMODEL}).One(&player) - return player, err -} - -// Insert a player into database. -func (m *PlayerDAO) Insert(player Player) error { - m.Db.Connect() - player.Model = PLAYERMODEL - err := m.Db.MongoDb.C(PLAYERCOLLECTION).Insert(&player) - return err -} - -// Upsert a player into database. -func (m *PlayerDAO) Upsert(player Player) (*mgo.ChangeInfo, error) { - m.Db.Connect() - player.Model = PLAYERMODEL - info, err := m.Db.MongoDb.C(PLAYERCOLLECTION).Upsert(bson.M{"lastname": player.Lastname}, &player) - return info, err -} - -// Update an existing player. -func (m *PlayerDAO) Update(player Player) error { - m.Db.Connect() - err := m.Db.MongoDb.C(PLAYERCOLLECTION).UpdateId(player.ID, &player) - return err -} - -// Delete an existing player. -func (m *PlayerDAO) Delete(player Player) error { - m.Db.Connect() - err := m.Db.MongoDb.C(PLAYERCOLLECTION).Remove(&player) - return err -} diff --git a/go/pkg/tysc/player_test.go b/go/pkg/tysc/player_test.go deleted file mode 100644 index e839ee9..0000000 --- a/go/pkg/tysc/player_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var playerModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Firstname", "string"}, - {"Lastname", "string"}, - {"Model", "string"}, -} - -func TestPlayerModel(t *testing.T) { - m := Player{} - if reflect.TypeOf(m).NumField() != len(playerModelTestTable) { - t.Fail() - } - for index, testData := range playerModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListPlayers(t *testing.T) { - var ( - playerDao = PlayerDAO{Db: dao.TestDb} - ) - players, err := playerDao.FindAll() - if err != nil { - t.Fail() - } - if players != nil { - t.Fail() - } -} - -func TestInsertPlayer(t *testing.T) { - var ( - playerDao = PlayerDAO{Db: dao.TestDb} - player = Player{} - players []Player - ) - player.ID = bson.NewObjectId() - player.Lastname = "test" - err := playerDao.Insert(player) - if err != nil { - t.Fail() - } - players, err = playerDao.FindAll() - if err != nil { - t.Fail() - } - if len(players) != 1 { - t.Fail() - } -} - -func TestUpsertPlayer(t *testing.T) { - var ( - playerDao = PlayerDAO{Db: dao.TestDb} - player = Player{} - ) - player.ID = bson.NewObjectId() - player.Lastname = "test2" - playerDao.Upsert(player) - players, err := playerDao.FindAll() - if err != nil { - t.Fail() - } - if len(players) != 2 { - t.Fail() - } -} - -func TestDeletePlayer(t *testing.T) { - var ( - playerDao = PlayerDAO{Db: dao.TestDb} - ) - players, err := playerDao.FindAll() - if err != nil { - t.Fail() - } - for _, player := range players { - playerDao.Delete(player) - } - players, err = playerDao.FindAll() - if err != nil { - t.Fail() - } - if len(players) != 0 { - t.Fail() - } -} diff --git a/go/pkg/tysc/position.go b/go/pkg/tysc/position.go deleted file mode 100644 index b52703a..0000000 --- a/go/pkg/tysc/position.go +++ /dev/null @@ -1,14 +0,0 @@ -package tysc - -import ( - "gopkg.in/mgo.v2/bson" -) - -// Position defines the data model for TYSC positions with id, name, description and sport. -type Position struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Name string `json:"name" bson:"name"` - Description string `json:"description" bson:"description"` - Sport bson.ObjectId `json:"sport" bson:"sport,omitempty"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/tysc/position_dao.go b/go/pkg/tysc/position_dao.go deleted file mode 100644 index 4166ee0..0000000 --- a/go/pkg/tysc/position_dao.go +++ /dev/null @@ -1,74 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// PositionDAO extends the type BaseDAO. -type PositionDAO struct { - Db dao.BaseDAO -} - -const ( - // POSITIONCOLLECTION defines the collection name for storing positions. - POSITIONCOLLECTION = "position" - // POSITIONMODEL defines the name of the position data model. - POSITIONMODEL = "kontor.tysc.position" -) - -// FindAll retrieves the list of positions from the database. -func (m *PositionDAO) FindAll() ([]Position, error) { - m.Db.Connect() - var positions []Position - err := m.Db.MongoDb.C(POSITIONCOLLECTION).Find(bson.M{"model": POSITIONMODEL}).All(&positions) - return positions, err -} - -// FindByID returns a position with given id or returns the error. -func (m *PositionDAO) FindByID(id string) (Position, error) { - m.Db.Connect() - var position Position - err := m.Db.MongoDb.C(POSITIONCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&position) - return position, err -} - -// FindByName returns a position with given name or returns the error. -func (m *PositionDAO) FindByName(name string) (Position, error) { - m.Db.Connect() - var position Position - err := m.Db.MongoDb.C(POSITIONCOLLECTION).Find(bson.M{"name": name, "model": POSITIONMODEL}).One(&position) - return position, err -} - -// Insert a position into database. -func (m *PositionDAO) Insert(position Position) error { - m.Db.Connect() - position.Model = POSITIONMODEL - err := m.Db.MongoDb.C(POSITIONCOLLECTION).Insert(&position) - return err -} - -// Upsert a position into database. -func (m *PositionDAO) Upsert(position Position) (*mgo.ChangeInfo, error) { - m.Db.Connect() - position.Model = POSITIONMODEL - info, err := m.Db.MongoDb.C(POSITIONCOLLECTION).Upsert(bson.M{"name": position.Name}, &position) - return info, err -} - -// Update an existing position. -func (m *PositionDAO) Update(position Position) error { - m.Db.Connect() - err := m.Db.MongoDb.C(POSITIONCOLLECTION).UpdateId(position.ID, &position) - return err -} - -// Delete an existing position. -func (m *PositionDAO) Delete(position Position) error { - m.Db.Connect() - err := m.Db.MongoDb.C(POSITIONCOLLECTION).Remove(&position) - return err -} diff --git a/go/pkg/tysc/position_test.go b/go/pkg/tysc/position_test.go deleted file mode 100644 index 2b97105..0000000 --- a/go/pkg/tysc/position_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var positionModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Name", "string"}, - {"Description", "string"}, - {"Sport", "string"}, - {"Model", "string"}, -} - -func TestPositionModel(t *testing.T) { - m := Position{} - if reflect.TypeOf(m).NumField() != len(positionModelTestTable) { - t.Fail() - } - for index, testData := range positionModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListPositions(t *testing.T) { - var ( - positionDao = PositionDAO{Db: dao.TestDb} - ) - positions, err := positionDao.FindAll() - if err != nil { - t.Fail() - } - if len(positions) != 0 { - t.Fail() - } -} - -func TestInsertPosition(t *testing.T) { - var ( - positionDao = PositionDAO{Db: dao.TestDb} - position = Position{} - positions []Position - ) - position.ID = bson.NewObjectId() - position.Name = "test" - err := positionDao.Insert(position) - if err != nil { - t.Fail() - } - positions, err = positionDao.FindAll() - if err != nil { - t.Fail() - } - if len(positions) != 1 { - t.Fail() - } -} - -func TestUpsertPosition(t *testing.T) { - var ( - positionDao = PositionDAO{Db: dao.TestDb} - position = Position{} - ) - position.ID = bson.NewObjectId() - position.Name = "test2" - positionDao.Upsert(position) - positions, err := positionDao.FindAll() - if err != nil { - t.Fail() - } - if len(positions) != 2 { - t.Fail() - } -} - -func TestDeletePosition(t *testing.T) { - var ( - positionDao = PositionDAO{Db: dao.TestDb} - ) - positions, err := positionDao.FindAll() - if err != nil { - t.Fail() - } - for _, position := range positions { - positionDao.Delete(position) - } - positions, err = positionDao.FindAll() - if err != nil { - t.Fail() - } - if len(positions) != 0 { - t.Fail() - } -} diff --git a/go/pkg/tysc/routes.go b/go/pkg/tysc/routes.go deleted file mode 100644 index e581db7..0000000 --- a/go/pkg/tysc/routes.go +++ /dev/null @@ -1,22 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/auth" - - "github.com/gin-gonic/gin" -) - -// GetRoutes returns all routes for TYSC related data. -func GetRoutes(router *gin.Engine) { - tyscRoutes := router.Group("/tysc") - tyscRoutes.GET("/", auth.EnsureLoggedIn(), showIndexPage) - tyscRoutes.GET("/sport", auth.EnsureLoggedIn(), showSportList) - tyscRoutes.GET("/position", auth.EnsureLoggedIn(), showIndexPage) - tyscRoutes.GET("/team", auth.EnsureLoggedIn(), showIndexPage) - tyscRoutes.GET("/player", auth.EnsureLoggedIn(), showIndexPage) - tyscRoutes.GET("/manufacturer", auth.EnsureLoggedIn(), showIndexPage) - tyscRoutes.GET("/cardset", auth.EnsureLoggedIn(), showIndexPage) - tyscRoutes.GET("/parallelset", auth.EnsureLoggedIn(), showIndexPage) - tyscRoutes.GET("/insertset", auth.EnsureLoggedIn(), showIndexPage) - tyscRoutes.GET("/card", auth.EnsureLoggedIn(), showIndexPage) -} diff --git a/go/pkg/tysc/sport.go b/go/pkg/tysc/sport.go deleted file mode 100644 index ed5b8ef..0000000 --- a/go/pkg/tysc/sport.go +++ /dev/null @@ -1,12 +0,0 @@ -package tysc - -import ( - "gopkg.in/mgo.v2/bson" -) - -// Sport defines the data model for TYSC sports with id, and name. -type Sport struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Name string `json:"name" bson:"name"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/tysc/sport_dao.go b/go/pkg/tysc/sport_dao.go deleted file mode 100644 index e931f98..0000000 --- a/go/pkg/tysc/sport_dao.go +++ /dev/null @@ -1,74 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// SportDAO extends the type BaseDAO. -type SportDAO struct { - Db dao.BaseDAO -} - -const ( - // SPORTCOLLECTION defines the collection name for storing sports. - SPORTCOLLECTION = "sport" - // SPORTMODEL defines the name of the sport data model. - SPORTMODEL = "kontor.tysc.sport" -) - -// FindAll retrieves the list of sports from the database. -func (m *SportDAO) FindAll() ([]Sport, error) { - m.Db.Connect() - var sports []Sport - err := m.Db.MongoDb.C(SPORTCOLLECTION).Find(bson.M{"model": SPORTMODEL}).All(&sports) - return sports, err -} - -// FindByID returns a sport with given id or returns the error. -func (m *SportDAO) FindByID(id string) (Sport, error) { - m.Db.Connect() - var sport Sport - err := m.Db.MongoDb.C(SPORTCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&sport) - return sport, err -} - -// FindByName returns a sport with given name or returns the error. -func (m *SportDAO) FindByName(name string) (Sport, error) { - m.Db.Connect() - var sport Sport - err := m.Db.MongoDb.C(SPORTCOLLECTION).Find(bson.M{"name": name, "model": SPORTMODEL}).One(&sport) - return sport, err -} - -// Insert a sport into database. -func (m *SportDAO) Insert(sport Sport) error { - m.Db.Connect() - sport.Model = SPORTMODEL - err := m.Db.MongoDb.C(SPORTCOLLECTION).Insert(&sport) - return err -} - -// Upsert a sport into database. -func (m *SportDAO) Upsert(sport Sport) (*mgo.ChangeInfo, error) { - m.Db.Connect() - sport.Model = SPORTMODEL - info, err := m.Db.MongoDb.C(SPORTCOLLECTION).Upsert(bson.M{"name": sport.Name}, &sport) - return info, err -} - -// Update an existing sport. -func (m *SportDAO) Update(sport Sport) error { - m.Db.Connect() - err := m.Db.MongoDb.C(SPORTCOLLECTION).UpdateId(sport.ID, &sport) - return err -} - -// Delete an existing sport. -func (m *SportDAO) Delete(sport Sport) error { - m.Db.Connect() - err := m.Db.MongoDb.C(SPORTCOLLECTION).Remove(&sport) - return err -} diff --git a/go/pkg/tysc/sport_test.go b/go/pkg/tysc/sport_test.go deleted file mode 100644 index 0aaf1c1..0000000 --- a/go/pkg/tysc/sport_test.go +++ /dev/null @@ -1,102 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var sportModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Name", "string"}, - {"Model", "string"}, -} - -func TestSport(t *testing.T) { - m := Sport{} - if reflect.TypeOf(m).NumField() != len(sportModelTestTable) { - t.Fail() - } - for index, testData := range sportModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListSports(t *testing.T) { - var ( - sportDao = SportDAO{Db: dao.TestDb} - ) - sports, err := sportDao.FindAll() - if err != nil { - t.Fail() - } - if len(sports) != 0 { - t.Fail() - } -} - -func TestInsertSport(t *testing.T) { - var ( - sportDao = SportDAO{Db: dao.TestDb} - sport = Sport{} - sports []Sport - ) - sport.ID = bson.NewObjectId() - sport.Name = "test" - err := sportDao.Insert(sport) - if err != nil { - t.Fail() - } - sports, err = sportDao.FindAll() - if err != nil { - t.Fail() - } - if len(sports) != 1 { - t.Fail() - } -} - -func TestUpsertSport(t *testing.T) { - var ( - sportDao = SportDAO{Db: dao.TestDb} - sport = Sport{} - ) - sport.ID = bson.NewObjectId() - sport.Name = "test2" - sportDao.Upsert(sport) - sports, err := sportDao.FindAll() - if err != nil { - t.Fail() - } - if len(sports) != 2 { - t.Fail() - } -} - -func TestDeleteSport(t *testing.T) { - var ( - sportDao = SportDAO{Db: dao.TestDb} - ) - sports, err := sportDao.FindAll() - if err != nil { - t.Fail() - } - for _, sport := range sports { - sportDao.Delete(sport) - } - sports, err = sportDao.FindAll() - if err != nil { - t.Fail() - } - if len(sports) != 0 { - t.Fail() - } -} diff --git a/go/pkg/tysc/team.go b/go/pkg/tysc/team.go deleted file mode 100644 index 167a2e5..0000000 --- a/go/pkg/tysc/team.go +++ /dev/null @@ -1,14 +0,0 @@ -package tysc - -import ( - "gopkg.in/mgo.v2/bson" -) - -// Team defines the data model for TYSC teams with id, name and sport. -type Team struct { - ID bson.ObjectId `json:"_id" bson:"_id,omitempty"` - Name string `json:"name" bson:"name"` - Shortname string `json:"shortname" bson:"shortname"` - Sport bson.ObjectId `json:"sport" bson:"sport,omitempty"` - Model string `json:"model" bson:"model,omitempty"` -} diff --git a/go/pkg/tysc/team_dao.go b/go/pkg/tysc/team_dao.go deleted file mode 100644 index 911763e..0000000 --- a/go/pkg/tysc/team_dao.go +++ /dev/null @@ -1,74 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - - mgo "gopkg.in/mgo.v2" - "gopkg.in/mgo.v2/bson" -) - -// TeamDAO extends the type BaseDAO. -type TeamDAO struct { - Db dao.BaseDAO -} - -const ( - // TEAMCOLLECTION defines the collection name for storing teams. - TEAMCOLLECTION = "team" - // TEAMMODEL defines the name of the team data model. - TEAMMODEL = "kontor.tysc.team" -) - -// FindAll retrieves the list of cards from the database. -func (m *TeamDAO) FindAll() ([]Team, error) { - m.Db.Connect() - var teams []Team - err := m.Db.MongoDb.C(TEAMCOLLECTION).Find(bson.M{"model": TEAMMODEL}).All(&teams) - return teams, err -} - -// FindByID returns a team with given id or returns the error. -func (m *TeamDAO) FindByID(id string) (Team, error) { - m.Db.Connect() - var team Team - err := m.Db.MongoDb.C(TEAMCOLLECTION).FindId(bson.ObjectIdHex(id)).One(&team) - return team, err -} - -// FindByName returns a team with given name or returns the error. -func (m *TeamDAO) FindByName(name string) (Team, error) { - m.Db.Connect() - var team Team - err := m.Db.MongoDb.C(TEAMCOLLECTION).Find(bson.M{"name": name, "model": TEAMMODEL}).One(&team) - return team, err -} - -// Insert a team into database -func (m *TeamDAO) Insert(team Team) error { - m.Db.Connect() - team.Model = TEAMMODEL - err := m.Db.MongoDb.C(TEAMCOLLECTION).Insert(&team) - return err -} - -// Upsert a team into database -func (m *TeamDAO) Upsert(team Team) (*mgo.ChangeInfo, error) { - m.Db.Connect() - team.Model = TEAMMODEL - info, err := m.Db.MongoDb.C(TEAMCOLLECTION).Upsert(bson.M{"name": team.Name}, &team) - return info, err -} - -// Update an existing team. -func (m *TeamDAO) Update(team Team) error { - m.Db.Connect() - err := m.Db.MongoDb.C(TEAMCOLLECTION).UpdateId(team.ID, &team) - return err -} - -// Delete an existing team. -func (m *TeamDAO) Delete(team Team) error { - m.Db.Connect() - err := m.Db.MongoDb.C(TEAMCOLLECTION).Remove(&team) - return err -} diff --git a/go/pkg/tysc/team_test.go b/go/pkg/tysc/team_test.go deleted file mode 100644 index 79dd539..0000000 --- a/go/pkg/tysc/team_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "reflect" - "testing" - - "gopkg.in/mgo.v2/bson" -) - -var teamModelTestTable = []struct { - name string - typeName string -}{ - {"Id", "string"}, - {"Name", "string"}, - {"Shortname", "string"}, - {"Sport", "string"}, - {"Model", "string"}, -} - -func TestTeamModel(t *testing.T) { - m := Team{} - if reflect.TypeOf(m).NumField() != len(teamModelTestTable) { - t.Fail() - } - for index, testData := range teamModelTestTable { - givenType := reflect.TypeOf(m).Field(index).Type.Kind().String() - if givenType != testData.typeName { - t.Fail() - } - } -} - -func TestListTeams(t *testing.T) { - var ( - teamDao = TeamDAO{Db: dao.TestDb} - ) - teams, err := teamDao.FindAll() - if err != nil { - t.Fail() - } - if teams != nil { - t.Fail() - } -} - -func TestInsertTeam(t *testing.T) { - var ( - teamDao = TeamDAO{Db: dao.TestDb} - team = Team{} - teams []Team - ) - team.ID = bson.NewObjectId() - err := teamDao.Insert(team) - if err != nil { - t.Fail() - } - teams, err = teamDao.FindAll() - if err != nil { - t.Fail() - } - if len(teams) != 1 { - t.Fail() - } -} - -func TestUpsertTeam(t *testing.T) { - var ( - teamDao = TeamDAO{Db: dao.TestDb} - team = Team{} - ) - team.ID = bson.NewObjectId() - team.Name = "test2" - teamDao.Upsert(team) - teams, err := teamDao.FindAll() - if err != nil { - t.Fail() - } - if len(teams) != 2 { - t.Fail() - } -} - -func TestDeleteTeam(t *testing.T) { - var ( - teamDao = TeamDAO{Db: dao.TestDb} - ) - teams, err := teamDao.FindAll() - if err != nil { - t.Fail() - } - for _, team := range teams { - teamDao.Delete(team) - } - teams, err = teamDao.FindAll() - if err != nil { - t.Fail() - } - if len(teams) != 0 { - t.Fail() - } -} diff --git a/go/pkg/tysc/views.go b/go/pkg/tysc/views.go deleted file mode 100644 index 0d9f233..0000000 --- a/go/pkg/tysc/views.go +++ /dev/null @@ -1,22 +0,0 @@ -package tysc - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/dao" - "gitlab.thpeetz.de/kontor/kontor-go/pkg/util" - "net/http" - - "github.com/gin-gonic/gin" -) - -func showIndexPage(c *gin.Context) { - util.Render(c, gin.H{"title": "TradeYourSportsCards", "payload": nil}, "tysc/index.html") -} - -func showSportList(c *gin.Context) { - var dao = SportDAO{Db: dao.KontorDb} - if sports, err := dao.FindAll(); err == nil { - util.Render(c, gin.H{"title": "TYSC Sport List", "payload": sports}, "tysc/sports.html") - } else { - c.AbortWithError(http.StatusNotFound, err) - } -} diff --git a/go/pkg/util/render.go b/go/pkg/util/render.go deleted file mode 100644 index b786b4c..0000000 --- a/go/pkg/util/render.go +++ /dev/null @@ -1,39 +0,0 @@ -package util - -import ( - "gitlab.thpeetz.de/kontor/kontor-go/pkg/auth" - "net/http" - - "github.com/gin-gonic/gin" -) - -const ( - // SaveAction defines label of button. - SaveAction = "Save" - // AddAction defines label of button. - AddAction = "Add" - // DeleteAction defines label of button. - DeleteAction = "Delete" -) - -// Render one of HTML, JSON or CSV based on the 'Accept' header of the request -// If the header doesn't specify this, HTML is rendered, provided that -// the template name is present -func Render(c *gin.Context, data gin.H, templateName string) { - auth.SetSessionData(c, data) - switch c.Request.Header.Get("Accept") { - case "application/json": - c.JSON(http.StatusOK, data["payload"]) - case "application/xml": - c.XML(http.StatusOK, data["payload"]) - default: - c.HTML(http.StatusOK, templateName, data) - } -} - -// ShowIndexPage render the index page of Kontor web application. -func ShowIndexPage(c *gin.Context) { - // Call the render function with the name of the template to render - //log.Printf("Context: %v", c) - Render(c, gin.H{"title": "Kontor", "payload": nil}, "kontor/index.html") -} diff --git a/go/sonar-project.properties b/go/sonar-project.properties deleted file mode 100644 index b06f378..0000000 --- a/go/sonar-project.properties +++ /dev/null @@ -1,2 +0,0 @@ -sonar.projectKey=kontor_kontor-go_AX-cQT62rXuu6JVRvr-z -sonar.qualitygate.wait=true diff --git a/go/templates/comics/artists.html b/go/templates/comics/artists.html deleted file mode 100644 index f49ebbc..0000000 --- a/go/templates/comics/artists.html +++ /dev/null @@ -1,24 +0,0 @@ - -{{ template "header.html" .}} -{{ template "comics/menu.html" .}} - - -
- - - - {{range .payload }} - - {{end}} -
Comic Artists
Name
{{.Name}}
-
- Add entry -
-
- - -{{ template "footer.html" .}} diff --git a/go/templates/comics/comic.html b/go/templates/comics/comic.html deleted file mode 100644 index 8184605..0000000 --- a/go/templates/comics/comic.html +++ /dev/null @@ -1,34 +0,0 @@ -{{ template "header.html" .}} -{{ template "comics/menu.html" .}} - -
- {{ if .ErrorTitle}} -

- {{.ErrorTitle}}: {{.ErrorMessage}} -

- {{end}} -
-
- - {{ if .payload.Title }} - - {{ else }} - - {{ end }} -
-
- - -
- - - {{ if eq .action "Save" }} - - {{ end }} -
-
-{{ template "footer.html" .}} diff --git a/go/templates/comics/comics.html b/go/templates/comics/comics.html deleted file mode 100644 index aeca37f..0000000 --- a/go/templates/comics/comics.html +++ /dev/null @@ -1,24 +0,0 @@ - -{{ template "header.html" .}} -{{ template "comics/menu.html" .}} - - -
- - - - {{range .payload }} - - {{end}} -
List of Comics
Name
{{.Title}}
-
- Add entry -
-
- - -{{ template "footer.html" .}} diff --git a/go/templates/comics/menu.html b/go/templates/comics/menu.html deleted file mode 100644 index 6fec416..0000000 --- a/go/templates/comics/menu.html +++ /dev/null @@ -1,38 +0,0 @@ -{{ define "comics/menu.html" }} - -{{ end }} diff --git a/go/templates/comics/publisher.html b/go/templates/comics/publisher.html deleted file mode 100644 index fe38dcd..0000000 --- a/go/templates/comics/publisher.html +++ /dev/null @@ -1,32 +0,0 @@ -{{ define "comics/publisher.html" }} -{{ template "header.html" .}} -{{ template "comics/menu.html" .}} - -
- {{ if .ErrorTitle}} -

- {{.ErrorTitle}}: {{.ErrorMessage}} -

- {{end}} -
-
- - {{ if .payload.Name }} - - {{ else }} - - {{ end }} -
- - - {{ if eq .action "Save" }} - - {{ end }} -
-
-{{ template "footer.html" .}} -{{ end }} diff --git a/go/templates/comics/publishers.html b/go/templates/comics/publishers.html deleted file mode 100644 index d691cdc..0000000 --- a/go/templates/comics/publishers.html +++ /dev/null @@ -1,25 +0,0 @@ - -{{ define "comics/publishers.html" }} -{{ template "header.html" .}} -{{ template "comics/menu.html" .}} - - -
- - - - {{range .payload }} - - {{end}} -
Comic Publishers
Name
{{.Name}}
-
- Add entry -
-
- -{{ template "footer.html" .}} -{{ end }} diff --git a/go/templates/kontor/admin-menu.html b/go/templates/kontor/admin-menu.html deleted file mode 100644 index d5738a2..0000000 --- a/go/templates/kontor/admin-menu.html +++ /dev/null @@ -1,34 +0,0 @@ - diff --git a/go/templates/kontor/admin.html b/go/templates/kontor/admin.html deleted file mode 100644 index 9dd19ad..0000000 --- a/go/templates/kontor/admin.html +++ /dev/null @@ -1,11 +0,0 @@ - -{{ define "kontor/admin.html" }} -{{ template "header.html" .}} -{{ template "admin-menu.html" .}} - - -{{ template "footer.html" .}} -{{ end }} diff --git a/go/templates/kontor/create-user.html b/go/templates/kontor/create-user.html deleted file mode 100644 index 1a67785..0000000 --- a/go/templates/kontor/create-user.html +++ /dev/null @@ -1,40 +0,0 @@ -{{ define "kontor/create-user.html" }} -{{ template "header.html" .}} -{{ template "admin-menu.html" .}} - - -
-
- - {{ if .ErrorTitle}} -

- {{.ErrorTitle}}: {{.ErrorMessage}} -

- {{end}} - -
-
- - -
-
- - -
-
- - -
-
- - -
- -
-
-
-{{ template "footer.html" .}} -{{end}} diff --git a/go/templates/kontor/data-upload.html b/go/templates/kontor/data-upload.html deleted file mode 100644 index b2f77f2..0000000 --- a/go/templates/kontor/data-upload.html +++ /dev/null @@ -1,29 +0,0 @@ -{{ define "kontor/data-upload.html" }} -{{ template "header.html" .}} -{{ template "admin-menu.html" .}} - - -
-
- - {{ if .ErrorTitle}} -

- {{.ErrorTitle}}: {{.ErrorMessage}} -

- {{end}} - -
-
- - -
- -
-
-
- -{{ template "footer.html" .}} -{{end}} diff --git a/go/templates/kontor/footer.html b/go/templates/kontor/footer.html deleted file mode 100644 index 3760315..0000000 --- a/go/templates/kontor/footer.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - diff --git a/go/templates/kontor/header.html b/go/templates/kontor/header.html deleted file mode 100644 index bcf20aa..0000000 --- a/go/templates/kontor/header.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - {{ .title }} - - - - - - - - - - diff --git a/go/templates/kontor/index.html b/go/templates/kontor/index.html deleted file mode 100644 index 4e23ba7..0000000 --- a/go/templates/kontor/index.html +++ /dev/null @@ -1,17 +0,0 @@ - -{{ define "kontor/index.html" }} - -{{ template "header.html" .}} - -{{ template "menu.html" . }} - -
- {{ if .InfoMessage}} -

{{.InfoMessage}}

- {{end}} -
- - -{{ template "footer.html" .}} - -{{ end }} diff --git a/go/templates/kontor/login-successful.html b/go/templates/kontor/login-successful.html deleted file mode 100644 index 46e07fa..0000000 --- a/go/templates/kontor/login-successful.html +++ /dev/null @@ -1,12 +0,0 @@ - - - -{{ template "header.html" .}} -{{ template "menu.html" . }} - -
- You have successfully logged in. -
- - -{{ template "footer.html" .}} diff --git a/go/templates/kontor/login.html b/go/templates/kontor/login.html deleted file mode 100644 index 83fce69..0000000 --- a/go/templates/kontor/login.html +++ /dev/null @@ -1,35 +0,0 @@ - - - -{{ template "header.html" .}} -{{ template "menu.html" . }} - -

Login

- - -
-
- - {{ if .ErrorTitle}} -

- {{.ErrorTitle}}: {{.ErrorMessage}} -

- {{end}} - -
-
- - -
-
- - -
- -
-
-
- - - -{{ template "footer.html" .}} diff --git a/go/templates/kontor/menu.html b/go/templates/kontor/menu.html deleted file mode 100644 index b52a358..0000000 --- a/go/templates/kontor/menu.html +++ /dev/null @@ -1,36 +0,0 @@ - diff --git a/go/templates/kontor/user-detail.html b/go/templates/kontor/user-detail.html deleted file mode 100644 index 983a614..0000000 --- a/go/templates/kontor/user-detail.html +++ /dev/null @@ -1,59 +0,0 @@ -{{ define "kontor/user-detail.html" }} -{{ template "header.html" .}} -{{ template "admin-menu.html" .}} - - -
- - {{ if .ErrorTitle}} -

- {{.ErrorTitle}}: {{.ErrorMessage}} -

- {{end}} -
-
- - {{ if .payload.Username }} - - {{ else }} - - {{ end }} -
-
-
- - {{ if .payload.Firstname }} - - {{ else }} - - {{ end }} -
-
- - {{ if .payload.Lastname }} - - {{ else }} - - {{ end }} -
-
-
- - -
-
- - -
- - - {{ if eq .action "Save" }} - - {{ end }} -
-
-{{ template "footer.html" .}} -{{end}} diff --git a/go/templates/kontor/users.html b/go/templates/kontor/users.html deleted file mode 100644 index 8aef51c..0000000 --- a/go/templates/kontor/users.html +++ /dev/null @@ -1,38 +0,0 @@ -{{ define "kontor/users.html" }} -{{ template "header.html" .}} -{{ template "admin-menu.html" .}} - - -
- - - - - - - - - {{range .payload }} - - - - - {{ if .IsAdmin}} - - {{end}} - {{ if not .IsAdmin }} - - {{end}} - - {{end}} -
Registered users of Kontor
UsernameFirst NameLast NameAdministrator
{{.Username}}{{.Firstname}}{{.Lastname}}
-
- Add entry -
-
- -{{ template "footer.html" .}} -{{end}} diff --git a/go/templates/library/authors.html b/go/templates/library/authors.html deleted file mode 100644 index 781ec26..0000000 --- a/go/templates/library/authors.html +++ /dev/null @@ -1,25 +0,0 @@ - -{{ define "library/authors.html" }} -{{ template "header.html" .}} -{{ template "library/menu.html" .}} - -
- - - - {{range .payload }} - - {{end}} -
Liste der Autoren
Name
{{.Name}}
-
- Add entry -
-
- - -{{ template "footer.html" .}} -{{ end }} diff --git a/go/templates/library/books.html b/go/templates/library/books.html deleted file mode 100644 index 456cb82..0000000 --- a/go/templates/library/books.html +++ /dev/null @@ -1,25 +0,0 @@ - -{{ define "library/books.html" }} -{{ template "header.html" .}} -{{ template "library/menu.html" . }} - -
- - - - {{range .payload }} - - {{end}} -
Liste der Bücher
Title
{{.Title}}
-
- Add entry -
-
- -{{ template "footer.html" .}} - -{{ end }} diff --git a/go/templates/library/menu.html b/go/templates/library/menu.html deleted file mode 100644 index 2e6257f..0000000 --- a/go/templates/library/menu.html +++ /dev/null @@ -1,38 +0,0 @@ -{{ define "library/menu.html" }} - -{{ end }} diff --git a/go/templates/library/publisher.html b/go/templates/library/publisher.html deleted file mode 100644 index c0dae5e..0000000 --- a/go/templates/library/publisher.html +++ /dev/null @@ -1,32 +0,0 @@ -{{ define "library/publisher.html" }} -{{ template "header.html" .}} -{{ template "library/menu.html" .}} - -
- {{ if .ErrorTitle}} -

- {{.ErrorTitle}}: {{.ErrorMessage}} -

- {{end}} -
-
- - {{ if .payload.Name }} - - {{ else }} - - {{ end }} -
- - - {{ if eq .action "Save" }} - - {{ end }} -
-
-{{ template "footer.html" .}} -{{ end }} diff --git a/go/templates/library/publishers.html b/go/templates/library/publishers.html deleted file mode 100644 index a166167..0000000 --- a/go/templates/library/publishers.html +++ /dev/null @@ -1,24 +0,0 @@ - -{{ define "library/publishers.html" }} -{{ template "header.html" .}} -{{ template "library/menu.html" .}} - -
- - - - {{range .payload }} - - {{end}} -
Liste der Verlage
Name
{{.Name}}
-
- Add entry -
-
- -{{ template "footer.html" .}} -{{end}} diff --git a/go/templates/office/index.html b/go/templates/office/index.html deleted file mode 100644 index 3932a29..0000000 --- a/go/templates/office/index.html +++ /dev/null @@ -1,10 +0,0 @@ - -{{ define "office/index.html" }} -{{ template "header.html" .}} -{{ template "office/menu.html" . }} - -

Home Office

- -{{ template "footer.html" .}} - -{{ end }} diff --git a/go/templates/office/menu.html b/go/templates/office/menu.html deleted file mode 100644 index ddcd03d..0000000 --- a/go/templates/office/menu.html +++ /dev/null @@ -1,38 +0,0 @@ -{{ define "office/menu.html" }} - -{{ end }} diff --git a/go/templates/tradingcards/index.html b/go/templates/tradingcards/index.html deleted file mode 100644 index 6911e17..0000000 --- a/go/templates/tradingcards/index.html +++ /dev/null @@ -1,10 +0,0 @@ - -{{ define "tradingcards/index.html" }} -{{ template "header.html" .}} -{{ template "tradingcards/menu.html" . }} - -

Trading Cards

- -{{ template "footer.html" .}} - -{{ end }} diff --git a/go/templates/tradingcards/menu.html b/go/templates/tradingcards/menu.html deleted file mode 100644 index 524080c..0000000 --- a/go/templates/tradingcards/menu.html +++ /dev/null @@ -1,38 +0,0 @@ -{{ define "tradingcards/menu.html" }} - -{{ end }} diff --git a/go/templates/tysc/index.html b/go/templates/tysc/index.html deleted file mode 100644 index b1d135d..0000000 --- a/go/templates/tysc/index.html +++ /dev/null @@ -1,16 +0,0 @@ -{{ define "tysc/index.html" }} -{{ template "header.html" .}} -{{ template "tysc/menu.html" . }} - -{{ template "footer.html" .}} -{{ end }} diff --git a/go/templates/tysc/menu.html b/go/templates/tysc/menu.html deleted file mode 100644 index 53a8e9e..0000000 --- a/go/templates/tysc/menu.html +++ /dev/null @@ -1,38 +0,0 @@ -{{ define "tysc/menu.html" }} - -{{ end }} diff --git a/go/templates/tysc/sports.html b/go/templates/tysc/sports.html deleted file mode 100644 index cf65f25..0000000 --- a/go/templates/tysc/sports.html +++ /dev/null @@ -1,28 +0,0 @@ -{{ define "tysc/sports.html" }} -{{ template "header.html" .}} -{{ template "tysc/menu.html" .}} - -
- - - - {{range .payload }} - - {{end}} -
List of Amertican Sports
Name
{{.Name}}
-
- Add entry -
-
-{{ template "footer.html" .}} -{{ end }} diff --git a/go/tysc-20041010-1819.sql b/go/tysc-20041010-1819.sql deleted file mode 100644 index 167c41d..0000000 --- a/go/tysc-20041010-1819.sql +++ /dev/null @@ -1,168 +0,0 @@ -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */; -CREATE DATABASE /*!32312 IF NOT EXISTS*/ `tysc`; -USE `tysc`; - -DROP TABLE IF EXISTS `angebote`; -CREATE TABLE `angebote` ( - `user_id` int(11) NOT NULL default '0', - `karte_id` int(11) NOT NULL default '0' -) TYPE=MyISAM; -INSERT INTO `angebote` (`user_id`,`karte_id`) VALUES (3,28),(3,30); - -DROP TABLE IF EXISTS `benutzer`; -CREATE TABLE `benutzer` ( - `ID` int(11) NOT NULL auto_increment, - `forename` varchar(40) default NULL, - `surname` varchar(40) default NULL, - `strasse` varchar(60) default NULL, - `plz` int(6) default NULL, - `ort` varchar(20) default NULL, - `username` varchar(20) default NULL, - `email` varchar(60) default NULL, - `password` varchar(32) default NULL, - `java` char(1) default NULL, - `language` int(11) NOT NULL default '0', - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `benutzer` (`ID`,`forename`,`surname`,`strasse`,`plz`,`ort`,`username`,`email`,`password`,`java`,`language`) VALUES (1,'Thomas','Peetz','Reichweindamm 24',13627,'Berlin','gophard','thomas.peetz@snafu.de','t.log1n','N',1),(2,'Heiko','John','Johannastr.49',13581,'Berlin','John','healjo@hotmail.com','redskins','N',1),(3,'Thomas','Peetz','Reichweindamm 24',13627,'Berlin','peetz','gophard@snafu.de','peetz','N',1); - -DROP TABLE IF EXISTS `changelog`; -CREATE TABLE `changelog` ( - `datum` date default NULL, - `tablename` varchar(20) default NULL, - `id` int(11) NOT NULL default '0' -) TYPE=MyISAM; -INSERT INTO `changelog` (`datum`,`tablename`,`id`) VALUES ('2002-02-27','benutzer',1),('2002-02-28','benutzer',2),('2002-03-05','benutzer',3),('2002-03-05','angebote',0),('2002-03-05','angebote',0); - -DROP TABLE IF EXISTS `hersteller`; -CREATE TABLE `hersteller` ( - `ID` int(11) NOT NULL auto_increment, - `name` varchar(30) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `hersteller` (`ID`,`name`) VALUES (1,'Pacific'),(2,'Fleer'),(3,'Bowman'),(6,'Topps'),(7,'Donruss'),(8,'Score'),(9,'Flair'); - -DROP TABLE IF EXISTS `inserts`; -CREATE TABLE `inserts` ( - `ID` int(11) NOT NULL auto_increment, - `hersteller_id` int(11) NOT NULL default '0', - `name` varchar(40) default NULL, - PRIMARY KEY (`ID`,`hersteller_id`) -) TYPE=MyISAM; -INSERT INTO `inserts` (`ID`,`hersteller_id`,`name`) VALUES (1,2,'Mystique Big Buzz'); - -DROP TABLE IF EXISTS `karte`; -CREATE TABLE `karte` ( - `ID` int(11) NOT NULL auto_increment, - `spieler_id` int(11) NOT NULL default '0', - `team_id` int(11) NOT NULL default '0', - `hersteller_id` int(11) NOT NULL default '0', - `serie_id` int(11) default NULL, - `parallel_id` int(11) default NULL, - `inserts_id` int(11) default NULL, - `rookie` char(1) default NULL, - `jahr` int(4) default NULL, - `nummer` int(11) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `karte` (`ID`,`spieler_id`,`team_id`,`hersteller_id`,`serie_id`,`parallel_id`,`inserts_id`,`rookie`,`jahr`,`nummer`) VALUES (12,12,13,1,1,0,0,'N',2001,212),(1,1,2,1,1,0,0,'N',2001,185),(2,2,2,1,1,0,0,'N',2001,250),(3,3,8,1,1,0,0,'N',2001,103),(4,4,8,1,1,0,0,'N',2001,112),(5,5,6,1,1,0,0,'N',2001,37),(6,6,6,1,1,0,0,'N',2001,38),(7,7,6,1,1,0,0,'N',2001,31),(8,8,10,1,1,0,0,'N',2001,338),(9,9,10,1,1,0,0,'N',2001,335),(10,10,10,1,1,0,0,'N',2001,345),(11,11,13,1,1,0,0,'N',2001,213),(13,13,14,1,1,0,0,'N',2001,311),(14,14,14,1,1,0,0,'N',2001,312),(15,15,16,1,1,0,0,'N',2001,403),(16,16,16,1,1,0,0,'N',2001,397),(17,17,16,1,1,0,0,'N',2001,404),(18,18,18,1,1,0,0,'N',2001,116),(19,19,18,1,1,0,0,'N',2001,122),(20,20,18,1,1,0,0,'N',2001,117),(21,21,19,1,1,0,0,'N',2001,281),(22,22,19,1,1,0,0,'N',2001,321),(23,23,20,1,1,0,0,'N',2001,331),(24,24,20,1,1,0,0,'N',2001,324),(25,25,21,1,1,0,0,'N',2001,445),(26,26,27,1,1,0,0,'N',2001,28),(27,27,27,1,1,0,0,'N',2001,17),(28,28,27,1,1,0,0,'N',2001,23),(29,29,29,1,1,0,0,'N',2001,273); -INSERT INTO `karte` (`ID`,`spieler_id`,`team_id`,`hersteller_id`,`serie_id`,`parallel_id`,`inserts_id`,`rookie`,`jahr`,`nummer`) VALUES (30,30,31,1,1,0,0,'N',2001,380),(31,31,31,1,1,0,0,'N',2001,390),(32,32,31,1,1,0,0,'N',2001,381),(33,33,31,1,1,0,0,'N',2001,387),(34,34,31,1,1,0,0,'N',2001,386),(35,35,30,1,1,0,0,'N',2001,349),(36,36,30,1,1,0,0,'N',2001,350),(37,37,44,5,8,0,0,'N',1994,106); - -DROP TABLE IF EXISTS `language`; -CREATE TABLE `language` ( - `ID` int(11) NOT NULL auto_increment, - `name` varchar(15) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; - -DROP TABLE IF EXISTS `mannschaft`; -CREATE TABLE `mannschaft` ( - `ID` int(11) NOT NULL auto_increment, - `team_id` int(11) NOT NULL default '0', - `sportart_id` int(11) NOT NULL default '0', - PRIMARY KEY (`ID`) -) TYPE=MyISAM; - -DROP TABLE IF EXISTS `parallelset`; -CREATE TABLE `parallelset` ( - `ID` int(11) NOT NULL auto_increment, - `hersteller_id` int(11) NOT NULL default '0', - `name` varchar(40) default NULL, - PRIMARY KEY (`ID`,`hersteller_id`) -) TYPE=MyISAM; -INSERT INTO `parallelset` (`ID`,`hersteller_id`,`name`) VALUES (1,2,'Mystique Gold'),(2,1,'Pacific Copper'),(3,1,'Pacific Gold'); - -DROP TABLE IF EXISTS `position`; -CREATE TABLE `position` ( - `ID` int(11) NOT NULL auto_increment, - `sportart_id` int(11) NOT NULL default '0', - `name` varchar(20) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `position` (`ID`,`sportart_id`,`name`) VALUES (1,1,'QB'),(2,1,'WR'),(3,1,'RB'),(4,1,'LB'),(5,1,'TE'),(6,1,'FB'),(7,1,'SS'),(8,1,'DE'),(9,1,'K'),(10,1,'P'),(11,1,'LG'),(12,1,'RG'),(13,1,'OF'),(14,1,'DB'),(15,1,'CB'),(16,2,'C'),(17,2,'1B'),(18,2,'2B'),(19,2,'3B'),(20,2,'SS'),(21,2,'LF'),(22,2,'CF'),(23,2,'RF'),(24,2,'DH'),(25,2,'P'); - -DROP TABLE IF EXISTS `serie`; -CREATE TABLE `serie` ( - `ID` int(11) NOT NULL auto_increment, - `hersteller_id` int(11) NOT NULL default '0', - `name` varchar(40) default NULL, - PRIMARY KEY (`ID`,`hersteller_id`) -) TYPE=MyISAM; -INSERT INTO `serie` (`ID`,`hersteller_id`,`name`) VALUES (1,1,'Pacific'),(2,2,'Fleer'),(3,3,'Bowman'),(4,4,'Leaf'),(5,2,'Ultra'),(6,2,'Mystique'),(7,1,'Finest Hour'),(8,5,'SP'),(9,5,'SPX'),(10,5,'SP Authentic'),(11,5,'Black Diamond'); - -DROP TABLE IF EXISTS `spiele`; -CREATE TABLE `spiele` ( - `datum` date default NULL, - `gast` int(11) NOT NULL default '0', - `gast_pkt` int(11) default NULL, - `heim` int(11) NOT NULL default '0', - `heim_pkt` int(11) default NULL -) TYPE=MyISAM; - -DROP TABLE IF EXISTS `spieler`; -CREATE TABLE `spieler` ( - `ID` int(11) NOT NULL auto_increment, - `name` varchar(40) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `spieler` (`ID`,`name`) VALUES (1,'Pathon, Jerome'),(2,'Bruschi, Tedy'),(3,'Couch, Tim'),(4,'Shea, Aaron'),(5,'Lewis, Jamal'),(6,'Lewis, Jermaine'),(7,'Banks, Tony'),(8,'Fuamatu-Ma\'Afala, Chris'),(9,'Bettis, Jerome'),(10,'Stewart, Kordell'),(11,'Moon, Warren'),(12,'Lockett, Kevin'),(13,'Gannon, Rich'),(14,'Jett, James'),(15,'Strong, Mack'),(16,'Huard, Brock'),(17,'Watters, Ricky'),(18,'Aikman, Troy'),(19,'LaFleur, David'),(20,'Brazzell, Chris'),(21,'Dayne, Ron'),(22,'Brown, Na'),(23,'Small, Torrance'),(24,'Lewis, Chad'),(25,'Murrell, Adrian'),(26,'Smith, Maurice'),(27,'Chandler, Chris'),(28,'Kanell, Danny'),(29,'Williams, Ricky'),(30,'Garcia, Jeff'),(31,'Streets, Tai'),(32,'Garner, Charlie'),(33,'Rice, Jerry'),(34,'Owens, Terrell'),(35,'Bruce, Isaac'),(36,'Canidate, Trung'); - -DROP TABLE IF EXISTS `spielerposition`; -CREATE TABLE `spielerposition` ( - `spieler_id` int(11) NOT NULL default '0', - `sportart_id` int(11) NOT NULL default '0', - `position_id` int(11) NOT NULL default '0' -) TYPE=MyISAM; - -DROP TABLE IF EXISTS `sportart`; -CREATE TABLE `sportart` ( - `ID` int(11) NOT NULL auto_increment, - `name` varchar(30) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `sportart` (`ID`,`name`) VALUES (1,'Football'),(2,'Baseball'),(3,'Basketball'),(4,'Hockey'); - -DROP TABLE IF EXISTS `suche`; -CREATE TABLE `suche` ( - `user_id` int(11) NOT NULL default '0', - `karte_id` int(11) NOT NULL default '0' -) TYPE=MyISAM; - -DROP TABLE IF EXISTS `team`; -CREATE TABLE `team` ( - `ID` int(11) NOT NULL auto_increment, - `sportart_id` int(11) NOT NULL default '0', - `name` varchar(40) default NULL, - `short` varchar(15) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `team` (`ID`,`sportart_id`,`name`,`short`) VALUES (1,1,'Buffalo Bills','Bills'),(2,1,'Indianapolis Colts','Colts'),(3,1,'Miami Dolphins','Dolphins'),(4,1,'New England Patriots','Patriots'),(5,1,'New York Jets','Jets'),(6,1,'Baltimore Ravens','Ravens'),(7,1,'Cincinnati Bengals','Bengals'),(8,1,'Cleveland Browns','Browns'),(9,1,'Jacksonville Jaguars','Jaguars'),(10,1,'Pittsburgh Steelers','Steelers'),(11,1,'Tennessee Titans','Titans'),(12,1,'Denver Broncos','Broncos'),(13,1,'Kansas City Chiefs','Chiefs'),(14,1,'Oakland Raiders','Raiders'),(15,1,'San Diego Chargers','Chargers'),(16,1,'Seattle Seahawks','Seahawks'),(17,1,'Arizona Cardinals','Cardinals'),(18,1,'Dallas Cowboys','Cowboys'),(19,1,'New York Giants','Giants'),(20,1,'Philadelphia Eagles','Eagles'),(21,1,'Washington Redskins','Redskins'),(22,1,'Chicago Bears','Bears'),(23,1,'Detroit Lions','Lions'),(24,1,'Green Bay Packers','Packers'),(25,1,'Minnesota Vikings','Vikings'),(26,1,'Tampa Bay Buccaneers','Buccaneers'),(27,1,'Atlanta Falcons','Falcons'),(28,1,'Carolina Panthers','Panthers'); -INSERT INTO `team` (`ID`,`sportart_id`,`name`,`short`) VALUES (29,1,'New Orleans Saints','Saints'),(30,1,'St.Louis Rams','Rams'),(31,1,'San Francisco 49ers','49ers'),(32,2,'Baltimore Orioles','Orioles'),(33,2,'Boston Red Sox','Red Sox'),(34,2,'New York Yankees','Yankees'),(35,2,'Tampa Bay Devil Rays','Devil Rays'),(36,2,'Toronto Blue Jays','Blue Jays'),(37,2,'Chicago White Sox','White Sox'),(38,2,'Cleveland Indians','Indians'),(39,2,'Detroit Tigers','Tigers'),(40,2,'Kansas City Royals','Royals'),(41,2,'Minnesota Twins','Twins'),(42,2,'Anaheim Angels','Angels'),(43,2,'Oakland Athletics','Athletics'),(44,2,'Seattle Mariners','Mariners'),(45,2,'Texas Rangers','Rangers'),(46,2,'Atlanta Braves','Braves'),(47,2,'Florida Marlins','Marlins'),(48,2,'Montreal Expos','Expos'),(49,2,'New York Mets','Mets'),(50,2,'Philadelphia Phillies','Phillies'),(51,2,'Chicago Cubs','Cubs'),(52,2,'Cincinnati Reds','Reds'),(53,2,'Houston Astros','Astros'),(54,2,'Milwaukee Brewers','Brewers'),(55,2,'Pittsburgh Pirates','Pirates'),(56,2,'St.Louis Cardinals','Cardinals'); -INSERT INTO `team` (`ID`,`sportart_id`,`name`,`short`) VALUES (57,2,'Arizona Diamondbacks','Diamondbacks'),(58,2,'Colorado Rockies','Rockies'),(59,2,'Los Angeles Dodgers','Dodgers'),(60,2,'San Diego Padres','Padres'),(61,2,'San Francisco Giants','Giants'),(62,3,'Boston Celtics','Celtics'),(63,3,'Miami Heat','Heat'),(64,3,'New Jersey Nets','Mets'),(65,3,'New York Knicks','Knicks'),(66,3,'Orlando Magic','Magic'),(67,3,'Philadelphia 76ers','76ers'),(68,3,'Washington Wizards','Wizards'),(69,3,'Atlanta Hawks','Hawks'),(70,3,'Charlotte Hornets','Hornets'),(71,3,'Chicago Bulls','Bulls'),(72,3,'Cleveland Cavaliers','Cavaliers'),(73,3,'Detroit Pistons','Pistons'),(74,3,'Indiana Pacers','Pacers'),(75,3,'Milwaukee Bucks','Bucks'),(76,3,'Toronto Raptors','Raptors'),(77,3,'Dallas Mavericks','Mavericks'),(78,3,'Denver Nuggets','Nuggets'),(79,3,'Houston Rockets','Rockets'),(80,3,'Minnesota Timberwolves','Timberwolves'),(81,3,'San Antonio Spurs','Spurs'),(82,3,'Utah Jazz','Jazz'),(83,3,'Vancouver Grizzlies','Grizzlies'),(84,3,'Golden State Warriors','Warriors'); -INSERT INTO `team` (`ID`,`sportart_id`,`name`,`short`) VALUES (85,3,'Los Angeles Clippers','Clippers'),(86,3,'Los Angeles Lakers','Lakers'),(87,3,'Phoenix Suns','Suns'),(88,3,'Portland Trail Blazers','Blazers'),(89,3,'Sacramento Kings','Kings'),(90,3,'Seattle SuperSonics','SuperSonics'),(91,4,'Boston Bruins','Bruins'),(92,4,'Buffalo Sabres','Sabres'),(93,4,'Montreal Canadiens','Canadiens'),(94,4,'Ottawa Senators','Senators'),(95,4,'Toronto Maple Leafs','Maple Leafs'),(96,4,'New Jersey Devils','Devils'),(97,4,'New York Islander','Islander'),(98,4,'New York Rangers','Rangers'),(99,4,'Philadelphia Flyers','Flyers'),(100,4,'Pittsburgh Penguins','Penguins'),(101,4,'Atlanta Trashers','Trashers'),(102,4,'Carolina Hurricanes','Hurricanes'),(103,4,'Florida Panthers','Panthers'),(104,4,'Tampa Bay Lightnings','Lightnings'),(105,4,'Washington Capitals','Capitals'),(106,4,'Chicago Blackhawks','Blackhawks'),(107,4,'Columbo Blue Jackets','Blue Jackets'),(108,4,'Detroit Red Wings','Red Wings'),(109,4,'Nashville Predators','Predators'),(110,4,'St.Louis Blues','Blues'); -INSERT INTO `team` (`ID`,`sportart_id`,`name`,`short`) VALUES (111,4,'Calgary Flames','Flames'),(112,4,'Colorado Avalanche','Avalanche'),(113,4,'Edmonton Oilers','Oilers'),(114,4,'Minnesota Wild','Wild'),(115,4,'Vancouver Canucks','Canucks'),(116,4,'Anaheim Mighty Ducks','Mighty Ducks'),(117,4,'Dallas Stars','Stars'),(118,4,'Los Angeles Kings','Kings'),(119,4,'Phoenix Coyotes','Coyotes'),(120,4,'San Jose Sharks','Sharks'),(121,1,'Houston Texans','Texans'),(122,1,'Houston Oilers','Oilers'); -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; diff --git a/java-ee/ComicsImpl/build.gradle b/java-ee/ComicsImpl/build.gradle deleted file mode 100644 index 9aa2749..0000000 --- a/java-ee/ComicsImpl/build.gradle +++ /dev/null @@ -1,5 +0,0 @@ -jar { - manifest { - attributes 'Implementation-Title': 'Comics', 'Implementation-Version': version - } -} diff --git a/java-ee/ComicsImpl/config/checkstyle/checkstyle.xml b/java-ee/ComicsImpl/config/checkstyle/checkstyle.xml deleted file mode 100644 index 7c682c3..0000000 --- a/java-ee/ComicsImpl/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java-ee/ComicsImpl/config/checkstyle/checkstyle.xsl b/java-ee/ComicsImpl/config/checkstyle/checkstyle.xsl deleted file mode 100644 index 393a01b..0000000 --- a/java-ee/ComicsImpl/config/checkstyle/checkstyle.xsl +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -

CheckStyle Audit

Designed for use with CheckStyle and Ant.
-
- - - -
- - - -
- - - - - -

-

- -


- - - - -
- - - - -

Files

- - - - - - - - - - - - - - -
NameErrors
-
- - - - -

File

- - - - - - - - - - - - - -
Error DescriptionLine
- Back to top -
- - - -

Summary

- - - - - - - - - - - - -
FilesErrors
-
- - - - a - b - - -
- - diff --git a/java-ee/ComicsImpl/config/findbugs/findbugs.xml b/java-ee/ComicsImpl/config/findbugs/findbugs.xml deleted file mode 100644 index 34a6e01..0000000 --- a/java-ee/ComicsImpl/config/findbugs/findbugs.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/dal/ArtistDao.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/dal/ArtistDao.java deleted file mode 100644 index 346f363..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/dal/ArtistDao.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.peetz.comics.dal; - -import java.util.List; - -import javax.ejb.Local; - -import com.peetz.comics.entity.ArtistEntity; - -@Local -public interface ArtistDao { - - public ArtistEntity getById(Long id); - - public List findByIds(List ids); - - public ArtistEntity store(ArtistEntity entity); - - public void delete(ArtistEntity entity); -} \ No newline at end of file diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/dal/ArtistImpl.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/dal/ArtistImpl.java deleted file mode 100644 index 0f18e6c..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/dal/ArtistImpl.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.peetz.comics.dal; - -import java.util.List; - -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -import com.peetz.comics.entity.ArtistEntity; - -@Stateless(name = "ArtistDao") -@TransactionAttribute(TransactionAttributeType.REQUIRED) -public class ArtistImpl implements ArtistDao { - - @PersistenceContext(unitName = "kontor") - private EntityManager em; - - @Override - public ArtistEntity getById(Long id) { - Query q = em.createNamedQuery(""); - q.setParameter("id", id); - ArtistEntity entity = (ArtistEntity)q.getSingleResult(); - return entity; - } - - @Override - public List findByIds(List ids) { - // TODO Auto-generated method stub - return null; - } - - @Override - public ArtistEntity store(ArtistEntity entity) { - em.persist(entity); - return entity; - } - - @Override - public void delete(ArtistEntity entity) { - em.remove(entity); - } -} \ No newline at end of file diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/dal/ComicDao.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/dal/ComicDao.java deleted file mode 100644 index 957bc01..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/dal/ComicDao.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.peetz.comics.dal; - -import java.util.List; - -import javax.ejb.Local; - -import com.peetz.comics.entity.ComicEntity; -import com.peetz.comics.entity.PublisherEntity; - -@Local -public interface ComicDao { - public ComicEntity getById(Long id); - - public List findByIds(List ids); - - public List findByTitle(String title); - - public ComicEntity assignPublisher(ComicEntity comic, PublisherEntity publisher); - - public ComicEntity store(ComicEntity entity); - - public void delete(ComicEntity entity); -} diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/dal/ComicImpl.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/dal/ComicImpl.java deleted file mode 100644 index d2adb99..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/dal/ComicImpl.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.peetz.comics.dal; - -import java.util.List; - -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -import com.peetz.comics.entity.ComicEntity; -import com.peetz.comics.entity.PublisherEntity; - -@Stateless(name = "ComicDao") -@TransactionAttribute(TransactionAttributeType.REQUIRED) -public class ComicImpl implements ComicDao { - - @PersistenceContext(unitName = "kontor") - private EntityManager em; - - @Override - public ComicEntity getById(Long id) { - Query q = em.createNamedQuery("Comic.findById"); - q.setParameter("id", id); - ComicEntity entity = (ComicEntity)q.getSingleResult(); - return entity; - } - - @Override - public List findByIds(List ids) { - // TODO Auto-generated method stub - return null; - } - - @Override - public List findByTitle(String title) { - Query q = em.createNamedQuery("Comic.findByTitle"); - q.setParameter("title", title); - @SuppressWarnings("unchecked") - List resultList = q.getResultList(); - return resultList; - } - - @Override - public ComicEntity assignPublisher(ComicEntity comic, - PublisherEntity publisher) { - // TODO Auto-generated method stub - return null; - } - - @Override - public ComicEntity store(ComicEntity entity) { - em.persist(entity); - return entity; - } - - @Override - public void delete(ComicEntity entity) { - em.remove(entity); - } -} diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/ArtistEntity.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/ArtistEntity.java deleted file mode 100644 index 57e0474..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/ArtistEntity.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.peetz.comics.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Artist.findAll", query="SELECT a from ArtistEntity as a"), - @NamedQuery(name="Artist.findByName", query="SELECT a from ArtistEntity as a WHERE a.name = :name") -}) - -@Entity -@Table(name="ARTIST") -public class ArtistEntity { - - private Long id; - - private String name; - - private Collection writtenIssues = new ArrayList(); - - - private Collection inkedIssues = new ArrayList(); - - private Collection penciledIssues = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { return name; } - - public void setName(String name) { this.name = name; } - - public void setWrittenIssues(Collection writtenIssues) { this.writtenIssues = writtenIssues; } - - @OneToMany(mappedBy="writer", cascade=CascadeType.REMOVE) - public Collection getWrittenIssues() { - return writtenIssues; - } - - public void setInkedIssues(Collection inkedIssues) { this.inkedIssues = inkedIssues; } - - @OneToMany(mappedBy="inker", cascade=CascadeType.REMOVE) - public Collection getInkedIssues() { - return inkedIssues; - } - - public void setPenciledIssues(Collection penciledIssues) { this.penciledIssues = penciledIssues; } - - @OneToMany(mappedBy="penciler", cascade=CascadeType.REMOVE) - public Collection getPenciledIssues() { - return penciledIssues; - } -} diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/ComicEntity.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/ComicEntity.java deleted file mode 100644 index 4475647..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/ComicEntity.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.peetz.comics.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Comic.findAll", query="SELECT c from ComicEntity as c"), - @NamedQuery(name="Comic.findByTitle", query="SELECT c from ComicEntity as c WHERE c.title = :title") -}) - -@Entity -@Table(name="COMIC") -public class ComicEntity -{ - private Long id; - - private String title; - - private Boolean completed; - - private Boolean currentOrder; - - private Collection issues = new ArrayList(); - - private Collection storyArc = new ArrayList(); - - private Collection volumes = new ArrayList(); - - public PublisherEntity publisher; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } - - @Column - public Boolean getCompleted() { return completed; } - - public Boolean isCompleted() { return completed; } - - public void setCompleted(Boolean completed) { this.completed = completed; } - - @Column - public Boolean getCurrentOrder() { return currentOrder; } - - public Boolean isCurrentOrder() { return currentOrder; } - - public void setCurrentOrder(Boolean currentOrder) { this.currentOrder = currentOrder; } - - public void setIssues(Collection issues) { this.issues = issues; } - - @OneToMany(mappedBy="comic", cascade=CascadeType.REMOVE) - public Collection getIssues() { return issues; } - - public void setStoryArc(Collection storyArc) { this.storyArc = storyArc; } - - @OneToMany(mappedBy="comic", cascade=CascadeType.REMOVE) - public Collection getStoryArc() { return storyArc; } - - public void setVolumes(Collection volumes) { this.volumes = volumes; } - - @OneToMany(mappedBy="comic", cascade=CascadeType.REMOVE) - public Collection getVolumes() { return volumes; } - - @ManyToOne - public PublisherEntity getPublisher() { return publisher; } - - public void setPublisher(PublisherEntity publisher) { - this.publisher = publisher; - } -} diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/IssueEntity.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/IssueEntity.java deleted file mode 100644 index fbda2c4..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/IssueEntity.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.peetz.comics.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Issue.findAll", query="SELECT i from IssueEntity as i"), - @NamedQuery(name="Issue.findByNumber", query="SELECT i from IssueEntity as i WHERE i.number = :number") -}) - -@Entity -@Table(name = "ISSUE") -public class IssueEntity { - - private Long id; - - private String number; - - private Boolean completed; - - private ComicEntity comic; - - private ArtistEntity writer; - - private ArtistEntity inker; - - private ArtistEntity penciler; - - private StoryArcEntity storyArc; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getNumber() { return number; } - - public void setNumber(String number) { this.number = number; } - - @Column - public Boolean getCompleted() { return completed; } - public Boolean isCompleted() { return completed; } - - public void setCompleted(Boolean completed) { this.completed = completed; } - - public void setComic(ComicEntity comic) { this.comic = comic; } - - @ManyToOne - public ComicEntity getComic() { return comic; } - - public void setWriter(ArtistEntity writer) { this.writer = writer; } - - @ManyToOne - public ArtistEntity getWriter() { return writer; } - - public void setInker(ArtistEntity inker) { this.inker = inker; } - - @ManyToOne - public ArtistEntity getInker() { return inker; } - - public void setPenciler(ArtistEntity penciler) { this.penciler = penciler; } - - @ManyToOne - public ArtistEntity getPenciler() { return penciler; } - - public void setStoryArc(StoryArcEntity storyArc) { this.storyArc = storyArc; } - - @ManyToOne - public StoryArcEntity getStoryArc() { return storyArc; } -} diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/PublisherEntity.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/PublisherEntity.java deleted file mode 100644 index 9252ea8..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/PublisherEntity.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.peetz.comics.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Publisher.findAll", query="SELECT p from PublisherEntity as p"), - @NamedQuery(name="Publisher.findByName", query="SELECT p from PublisherEntity as p WHERE p.name = :name") -}) - -@Entity -@Table(name="PUBLISHER") -public class PublisherEntity { - - private Long id; - - private String name; - - private Collection comic = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { return name; } - - public void setName(String name) { this.name = name; } - - public void setComic(Collection comic) { this.comic = comic; } - - @OneToMany(mappedBy="publisher", cascade=CascadeType.REMOVE) - public Collection getComic() { return comic; } -} diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/StoryArcEntity.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/StoryArcEntity.java deleted file mode 100644 index cffec70..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/StoryArcEntity.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.peetz.comics.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="StoryArc.findAll", query="SELECT a from StoryArcEntity as a"), - @NamedQuery(name="StoryArc.findByArtist", query="SELECT a from StoryArcEntity as a WHERE a.title = :title") -}) - -@Entity -@Table(name="STORYARC") -public class StoryArcEntity { - - private Long id; - - private String title; - - private Collection issues = new ArrayList(); - - private ComicEntity comic; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } - - public void setIssues(Collection issues) { this.issues = issues; } - - @OneToMany(mappedBy="storyArc", cascade=CascadeType.REMOVE) - public Collection getIssues() { return issues; } - - public void setComic(ComicEntity comic) { this.comic = comic; } - - @ManyToOne - public ComicEntity getComic() { return comic; } -} diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/VolumeEntity.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/VolumeEntity.java deleted file mode 100644 index 8f25d13..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/entity/VolumeEntity.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.peetz.comics.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -@Entity -@Table(name="VOLUME") -public class VolumeEntity { - - private Long id; - - private String title; - - ComicEntity comic; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } - - @ManyToOne - public ComicEntity getComic() { return comic; } - - public void setComic(ComicEntity comic) { this.comic = comic; } -} diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/service/ComicService.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/service/ComicService.java deleted file mode 100644 index 523d230..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/service/ComicService.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.peetz.comics.service; - -import java.util.Collection; - -import javax.ejb.Local; - -import com.peetz.comics.entity.ArtistEntity; -import com.peetz.comics.entity.ComicEntity; -import com.peetz.comics.entity.IssueEntity; -import com.peetz.comics.entity.PublisherEntity; -import com.peetz.comics.entity.StoryArcEntity; - -@Local -public interface ComicService { - public Collection getAllComics(); - - public Collection getAllPublisher(); - - public Collection getAllArtists(); - - public Collection getAllIssuesForComic(ComicEntity comic); - - public Collection getAllStoryArcs(); - - public void addStoryArc(String title); - - public void addPublisher(String name); - - public ComicEntity addComic(String title); - - public PublisherEntity getPublisherById(String nodeValue); - - public void assignPublisher(ComicEntity comic, PublisherEntity publisher); -} diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/service/ComicServiceImpl.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/service/ComicServiceImpl.java deleted file mode 100644 index 5f3e222..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/service/ComicServiceImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.peetz.comics.service; - -import java.util.Collection; - -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; - -import com.peetz.comics.entity.ArtistEntity; -import com.peetz.comics.entity.ComicEntity; -import com.peetz.comics.entity.IssueEntity; -import com.peetz.comics.entity.PublisherEntity; -import com.peetz.comics.entity.StoryArcEntity; -import java.util.ArrayList; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -@Stateless(name="ComicService") -@TransactionAttribute(TransactionAttributeType.REQUIRED) -public class ComicServiceImpl implements ComicService { - - @PersistenceContext(unitName = "kontor") - private EntityManager em; - - @SuppressWarnings("unchecked") - @Override - public Collection getAllComics() { - Query query = em.createNamedQuery("Comic.findAll"); - ArrayList comicList = new ArrayList(query.getResultList()); - return comicList; - } - - @Override - public Collection getAllPublisher() { - Query query = em.createNamedQuery("Publisher.findAll"); - @SuppressWarnings("unchecked") - ArrayList publisherList = new ArrayList(query.getResultList()); - return publisherList; - } - - @SuppressWarnings("unchecked") - @Override - public Collection getAllArtists() { - Query query = em.createNamedQuery("Artist.findAll"); - ArrayList artistList = new ArrayList(query.getResultList()); - return artistList; - } - - @Override - public Collection getAllIssuesForComic(ComicEntity comic) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Collection getAllStoryArcs() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void addStoryArc(String title) { - // TODO Auto-generated method stub - - } - - @Override - public void addPublisher(String name) { - // TODO Auto-generated method stub - - } - - @Override - public ComicEntity addComic(String title) { - // TODO Auto-generated method stub - return null; - } - - @Override - public PublisherEntity getPublisherById(String nodeValue) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void assignPublisher(ComicEntity comic, PublisherEntity publisher) { - // TODO Auto-generated method stub - - } - -} diff --git a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/service/package-info.java b/java-ee/ComicsImpl/src/main/java/com/peetz/comics/service/package-info.java deleted file mode 100644 index a2d9305..0000000 --- a/java-ee/ComicsImpl/src/main/java/com/peetz/comics/service/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * - */ -/** - * @author TPEETZ - * - */ -package com.peetz.comics.service; \ No newline at end of file diff --git a/java-ee/ComicsImpl/src/test/java/com/peetz/comics/service/ComicServiceImplTest.java b/java-ee/ComicsImpl/src/test/java/com/peetz/comics/service/ComicServiceImplTest.java deleted file mode 100644 index 05f38c1..0000000 --- a/java-ee/ComicsImpl/src/test/java/com/peetz/comics/service/ComicServiceImplTest.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package com.peetz.comics.service; - -import com.peetz.comics.entity.ArtistEntity; -import com.peetz.comics.entity.ComicEntity; -import com.peetz.comics.entity.IssueEntity; -import com.peetz.comics.entity.PublisherEntity; -import com.peetz.comics.entity.StoryArcEntity; -import java.util.Collection; -import javax.ejb.embeddable.EJBContainer; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Ignore; - -/** - * - * @author TPEETZ - */ -public class ComicServiceImplTest { - - private static ComicService instance; - private static EJBContainer container; - - public ComicServiceImplTest() { - } - - @BeforeClass - public static void setUpClass() throws Exception { - container = javax.ejb.embeddable.EJBContainer.createEJBContainer(); - instance = (ComicService)container.getContext().lookup("java:global/main/ComicService"); - } - - @AfterClass - public static void tearDownClass() { - container.close(); - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } - - /** - * Test of getAllComics method, of class ComicServiceImpl. - */ - @Ignore - @Test - public void testGetAllComics() throws Exception { - System.out.println("getAllComics"); - Collection expResult = null; - Collection result = instance.getAllComics(); - assertEquals(expResult, result); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of getAllPublisher method, of class ComicServiceImpl. - */ - @Ignore - @Test - public void testGetAllPublisher() throws Exception { - System.out.println("getAllPublisher"); - Collection expResult = null; - Collection result = instance.getAllPublisher(); - assertEquals(expResult, result); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of getAllArtists method, of class ComicServiceImpl. - */ - @Ignore - @Test - public void testGetAllArtists() throws Exception { - System.out.println("getAllArtists"); - Collection expResult = null; - Collection result = instance.getAllArtists(); - assertEquals(expResult, result); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of getAllIssuesForComic method, of class ComicServiceImpl. - */ - @Ignore - @Test - public void testGetAllIssuesForComic() throws Exception { - System.out.println("getAllIssuesForComic"); - ComicEntity comic = null; - Collection expResult = null; - Collection result = instance.getAllIssuesForComic(comic); - assertEquals(expResult, result); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of getAllStoryArcs method, of class ComicServiceImpl. - */ - @Ignore - @Test - public void testGetAllStoryArcs() throws Exception { - System.out.println("getAllStoryArcs"); - Collection expResult = null; - Collection result = instance.getAllStoryArcs(); - assertEquals(expResult, result); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of addStoryArc method, of class ComicServiceImpl. - */ - @Ignore - @Test - public void testAddStoryArc() throws Exception { - System.out.println("addStoryArc"); - String title = ""; - instance.addStoryArc(title); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of addPublisher method, of class ComicServiceImpl. - */ - @Ignore - @Test - public void testAddPublisher() throws Exception { - System.out.println("addPublisher"); - String name = ""; - instance.addPublisher(name); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of addComic method, of class ComicServiceImpl. - */ - @Ignore - @Test - public void testAddComic() throws Exception { - System.out.println("addComic"); - String title = ""; - ComicEntity expResult = null; - ComicEntity result = instance.addComic(title); - assertEquals(expResult, result); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of getPublisherById method, of class ComicServiceImpl. - */ - @Ignore - @Test - public void testGetPublisherById() throws Exception { - System.out.println("getPublisherById"); - String nodeValue = ""; - PublisherEntity expResult = null; - PublisherEntity result = instance.getPublisherById(nodeValue); - assertEquals(expResult, result); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of assignPublisher method, of class ComicServiceImpl. - */ - @Ignore - @Test - public void testAssignPublisher() throws Exception { - System.out.println("assignPublisher"); - ComicEntity comic = null; - PublisherEntity publisher = null; - instance.assignPublisher(comic, publisher); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } -} diff --git a/java-ee/ComicsWeb/build.gradle b/java-ee/ComicsWeb/build.gradle deleted file mode 100644 index 30e1d2e..0000000 --- a/java-ee/ComicsWeb/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -apply plugin: 'war' - -version = '0.0.1' - -dependencies { - compile project(':ComicsImpl') -} diff --git a/java-ee/ComicsWeb/src/main/java/com/peetz/comics/view/ComicView.java b/java-ee/ComicsWeb/src/main/java/com/peetz/comics/view/ComicView.java deleted file mode 100644 index d21494c..0000000 --- a/java-ee/ComicsWeb/src/main/java/com/peetz/comics/view/ComicView.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.peetz.comics.view; - -import com.peetz.comics.service.ComicService; -import java.io.Serializable; -import java.util.logging.Logger; -import javax.ejb.EJB; -import javax.faces.bean.ManagedBean; -import javax.faces.bean.RequestScoped; - -/** - * - * @author TPEETZ - */ -@ManagedBean(name="ComicView") -@RequestScoped -public class ComicView implements Serializable { - - private static final Logger LOG = Logger.getLogger(ComicView.class.getName()); - - @EJB - private ComicService comicService; - - private static final long serialVersionUID = -8261128991042235283L; - - public ComicView() { - LOG.info("ComicView created"); - } - - public Integer getComicsNumber() { - return comicService.getAllComics().size(); - } - - public Integer getPublisherNumber() { - return comicService.getAllPublisher().size(); - } -} diff --git a/java-ee/ComicsWeb/src/main/webapp/artistAdd.jsp b/java-ee/ComicsWeb/src/main/webapp/artistAdd.jsp deleted file mode 100644 index 9328510..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/artistAdd.jsp +++ /dev/null @@ -1,64 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Comic Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.comics.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - -
Name:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/ComicsWeb/src/main/webapp/artistEdit.jsp b/java-ee/ComicsWeb/src/main/webapp/artistEdit.jsp deleted file mode 100644 index 3007a9a..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/artistEdit.jsp +++ /dev/null @@ -1,66 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Comic Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.comics.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - -
Name:
- <%-- hidden fields for id and userId --%> - - <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/ComicsWeb/src/main/webapp/artistList.jsp b/java-ee/ComicsWeb/src/main/webapp/artistList.jsp deleted file mode 100644 index 1414873..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/artistList.jsp +++ /dev/null @@ -1,95 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Comic Application - - - - - - - - - - - - - - - - - - - - - - - - -
Liste der Comics
- <% out.println(com.peetz.comics.navigation.MenuLinks.getInstance().toString()); %> - -

Comic Manager

- Show the comic artist list - - - - <%-- set the header --%> - - - - - - <%-- check if publisher exists and display message or iterate over books --%> - - - - - - - - - <%-- print out the book informations --%> - - <%-- print out the edit and delete link for each artist --%> - - - - - - <%-- end interate --%> - - <%-- if publishers cannot be found display a text --%> - - - - - - - -
Artist name  
No artists available
EditDelete
No artists found.
-
- <%-- add and back to menu button --%> - Add a new artist -   - Back to menu - - - - - -
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/ComicsWeb/src/main/webapp/comicAdd.jsp b/java-ee/ComicsWeb/src/main/webapp/comicAdd.jsp deleted file mode 100644 index c623224..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/comicAdd.jsp +++ /dev/null @@ -1,67 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Comic Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.comics.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - -
Title:
Publisher:
Completed:
Current Order:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/ComicsWeb/src/main/webapp/comicEdit.jsp b/java-ee/ComicsWeb/src/main/webapp/comicEdit.jsp deleted file mode 100644 index ea1cae9..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/comicEdit.jsp +++ /dev/null @@ -1,90 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Comic Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.comics.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - -
Title:
Publisher:
Completed:
Current Order:
- <%-- hidden fields for id and userId --%> - - <%-- set the parameter for the dispatch action --%> - - - - - - - - - - - - - - - - - - - - -
Issues  
No issues available
EditDelete
No issues available
Add issue
-
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/ComicsWeb/src/main/webapp/comicList.jsp b/java-ee/ComicsWeb/src/main/webapp/comicList.jsp deleted file mode 100644 index 4f2cc06..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/comicList.jsp +++ /dev/null @@ -1,99 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Comic Application - - - - - - - - - - - - - - - - - - - - - - - - -
Liste der Comics
- <% out.println(com.peetz.comics.navigation.MenuLinks.getInstance().toString()); %> - -

Comic Manager

- Show the comic list - - - - <%-- set the header --%> - - - - - - - - <%-- check if book exists and display message or iterate over books --%> - - - - - - - - - <%-- print out the book informations --%> - - - - <%-- print out the edit and delete link for each book --%> - - - - - - <%-- end interate --%> - - <%-- if books cannot be found display a text --%> - - - - - - - -
Comic namePublisherOrder  
No comics available
EditDelete
No comicss found.
-
- <%-- add and back to menu button --%> - Add a new comic -   - Back to menu - - - - - -
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/ComicsWeb/src/main/webapp/comics.xhtml b/java-ee/ComicsWeb/src/main/webapp/comics.xhtml deleted file mode 100644 index 506f71f..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/comics.xhtml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - Comics Application - - - - - - - - - - - - - - - - - - - - - - - - - -
Kontor Manager
- Kontor
- Comics
- Library
- Medien
- TradingCards -
-

Kontor Manager

- - -
 
-

Ingenieurbüro Thomas Peetz

-
- - diff --git a/java-ee/ComicsWeb/src/main/webapp/index.jsp b/java-ee/ComicsWeb/src/main/webapp/index.jsp deleted file mode 100644 index 5825223..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/index.jsp +++ /dev/null @@ -1,35 +0,0 @@ - - Comic Application - - - - - - - - - - - - - - - - - - - - - - - - - -
Comic Manager
test -

Comic Manager

- Show the comic list -
 
-

Ingenieurbüro Thomas Peetz

-
- - diff --git a/java-ee/ComicsWeb/src/main/webapp/issueAdd.jsp b/java-ee/ComicsWeb/src/main/webapp/issueAdd.jsp deleted file mode 100644 index 91aaae1..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/issueAdd.jsp +++ /dev/null @@ -1,67 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Comic Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.comics.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - -
Comic:
Number:
Author:
Read:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/ComicsWeb/src/main/webapp/issueEdit.jsp b/java-ee/ComicsWeb/src/main/webapp/issueEdit.jsp deleted file mode 100644 index 0ea25cb..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/issueEdit.jsp +++ /dev/null @@ -1,66 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Comic Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.comics.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - -
Number:
Author:
Read:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/ComicsWeb/src/main/webapp/publisherAdd.jsp b/java-ee/ComicsWeb/src/main/webapp/publisherAdd.jsp deleted file mode 100644 index 85f220a..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/publisherAdd.jsp +++ /dev/null @@ -1,64 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Comic Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.comics.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - -
Name:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/ComicsWeb/src/main/webapp/publisherEdit.jsp b/java-ee/ComicsWeb/src/main/webapp/publisherEdit.jsp deleted file mode 100644 index a8eb56d..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/publisherEdit.jsp +++ /dev/null @@ -1,66 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Comic Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.comics.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - -
Name:
- <%-- hidden fields for id and userId --%> - - <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/ComicsWeb/src/main/webapp/publisherList.jsp b/java-ee/ComicsWeb/src/main/webapp/publisherList.jsp deleted file mode 100644 index b0ef596..0000000 --- a/java-ee/ComicsWeb/src/main/webapp/publisherList.jsp +++ /dev/null @@ -1,95 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Comic Application - - - - - - - - - - - - - - - - - - - - - - - - -
Liste der Comics
- <% out.println(com.peetz.comics.navigation.MenuLinks.getInstance().toString()); %> - -

Comic Manager

- Show the comic list - - - - <%-- set the header --%> - - - - - - <%-- check if publisher exists and display message or iterate over books --%> - - - - - - - - - <%-- print out the book informations --%> - - <%-- print out the edit and delete link for each book --%> - - - - - - <%-- end interate --%> - - <%-- if publishers cannot be found display a text --%> - - - - - - - -
Publisher name  
No publishers available
EditDelete
No publishers found.
-
- <%-- add and back to menu button --%> - Add a new publisher -   - Back to menu - - - - - -
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/DVDs.csv b/java-ee/DVDs.csv deleted file mode 100644 index 1b8df87..0000000 --- a/java-ee/DVDs.csv +++ /dev/null @@ -1,391 +0,0 @@ -Title -(T)Raumschiff Surprise - Periode 1 -7 Zwerge - Männer allein im Wald -A Beatiful Mind -About Schmidt -Akte X: Der Film -Aladdin -"Alias - Die Agentin -Vol. 1" -"Alias - Die Agentin -Vol. 2" -"Alias - Die Agentin -Vol. 3" -Alles tanzt nach meiner Pfeife -American Beauty -American History X -American Pie -American Pie 2 -American Pie Jetzt wird geheiratet -American Psycho -An jedem verdammten Sonntag -Angeklagt -Antz -Apollo 13 -Arac Attack -Arachnophobia -Arlington Road -Asso -Atlantis Das Geheimnis der verlorenen Stadt -Austin Powers -Austin Powers Goldständer -Austin Powers Spion in geheimer Missionarsstellung -"Avanti, Avanti" -Backdraft -Bad Taste -Bang Boom Bang -Bärenbrüder -Being John Malkovich -"Berlin, Berlin - Staffel 1" -"Berlin, Berlin - Staffel 2" -"Berlin, Berlin - Staffel 3" -"Berlin, Berlin - Staffel 4" -Bernard & Bianca -Beverly Hills Cop -Beverly Hills Cop II -Beverly Hills Cop III -Black Hawk Down -Blow -Blues Brothers -Blues Brothers 2000 -Bowfingers grosse Nummer -Braveheart -Brust oder Keule -Caddyshack -Chasing Amy -Cheech & Chong's The Corsican Brothers -Cheech & Chong im Dauerstress -Cheech & Chong Jetzt raucht überhaupt nichts mehr -Cheech & Chong Viel Rauch um Nichts -Cheech & Chongs Heisse Träume -Cocktail für eine Leiche -ConAir -Daredevil -Dark City -Das Appartment -Das Fenster zum Hof -Das fünfte Element -Das grosse Krabbeln -Das Jesus Video -Das kleine Arschloch -Das Krokodil und sein Nilpferd -Das Netz -Das Schweigen der Lämmer -Das Wunder von Bern -Der Boss -Der Club der toten Dichter -Der dritte Mann -Der Glückspilz -Der Hauch des Todes -Der kleine Horrorladen -Der Knochenjäger -Der Mann mit dem goldenen Colt -"Der Mann, der zuviel wußte" -Der Millionenfinger -Der Mondmann -Der Morgen stirbt nie -Der Name der Rose -Der Pate 1-3 -Der Puppenspieler -Der Querkopf -Der Schatzplanet -"Der Spion, der mich liebte" -Der talentierte Mr. Ripley -Der Totmacher -Der Wixxer -Diamantenfieber -"Dick und Doof erben eine Insel, Atoll K" -Didi - der Doppelgänger -Didi - Der Experte -Didi - Der Schnüffler -Didi - und die Rache der Enterbten -Didi auf vollen Touren -Die Ärzte Unplugged Rock'n' Roll Realschule -Die Einsteiger -"Die Geister, die ich rief" -Die Glücksjäger -Die Glücksritter -Die große Schlacht des Don Camillo -Die Harald Schmidt Show - Best Of Vol. 2 -Die Harald Schmidt Show - Best of -Die Jury -Die Liga der aussergewöhnlichen Gentlemen -Die Monster AG -Die Muppets erobern Manhattan -Die Muppets Weihnachtsgeschichte -Die nackte Kanone -Die nackte Kanone 2 1/2 -Die nackte Kanone 33 1/3 -Die neun Pforten -Die rechte und die linke Hand des Teufels -Die Truman Show -Die unglaubliche Reise in einem verrückten Flugzeug -Die unglaubliche Reise in einem verrückten Raumschiff -Die Unglaublichen -Die Verurteilten -Die Welt ist nicht genug -Die Wiege der Sonne -Diese Zwei sind nicht zu fassen -Dogma -Don Camillo und Peppone -Don Camillos Rückkehr -Dr. Dolittle 1+2 -Dragonheart -Drei Amigos -Ein Fisch namens Wanda -Ein Fisch namens Wanda -Ein irrer Typ -Ein Ticket für Zwei -Eine Leiche zum Dessert -"Eine schrecklich nette Familie -Dritte Staffel" -"Eine schrecklich nette Familie -Erste Staffel" -"Eins, Zwei, Drei" -Eiskalte Engel -El Dorado -Elektra -Es war einmal in Amerika -Evolution -Ey Mann - Wo is' mein Auto? -Faceoff - Im Körper des Feindes -Fahrenheit 9/11 -Falsches Spiel mit Roger Rabbit -Feuerball -Findet Nemo -Flammendes Inferno -Fletcher's Visionen -Fluch der Karibik -Forrest Gump -Four Rooms -Foxy Brown -Freddy vs. Jason -Freeze - Alptraum Nachtwache -Frenzy -Frequency -Fröhliche Ostern -From Dusk Till Dawn -From Dusk Till Dawn 2 -"From Dusk Till Dawn 3 -The Hangman's Daughter" -From Hell -Galaxy Quest -Gangs of New York -Gegen jede Regel -Geld oder Leber -Genosse Don Camillo -Ghost Ship -Ghostbusters 2 -Girls United -Glauben ist Alles! -God's Army -God's Army 3 -GoldenEye -Goldfinger -Good Bye Lenin! -Good Morning Vietnam -Good Will Hunting -Gottes Werk und Teufels Beitrag -Grosse Erwartungen -Hannibal -Harald Schmidt Best of Vol. 1+2 + Golden Goals -Helden aus der zweiten Reihe -Hercules -Hero -Hochwürden Don Camillo -Höllentour - Die Tour der Helden -Hot Shots 1 + 2 -Hulk -"I, Robot" -Ice Age -Im Angesicht des Todes -Im Geheimdienst Ihrer Majestät -Immer Ärger mit Bernie -In 80 Tagen um die Welt Teil 1 -In 80 Tagen um die Welt Teil 2 -In tödlicher Mission -Independence Day -Irma La Douce -Jabberwocky -Jackie Brown -Jagd auf einen Unsichtbaren -Jagd auf Roter Oktober -James Bond jagt Dr. No -JFK John F. Kennedy - Tatort Dallas -Johnny English -Jumanji -Kentucky Fried Movie -Kill Bill Vol. 1 -Kill Bill Vol. 2 -"Knight Moves -Ein mörderisches Spiel" -König der Fischer -La Boum -La Boum 2 -Leben und Sterben lassen -Liebesgrüße aus Moskau -Lizenz zum Töten -Lola rennt -Lost in Space -Lost In Translation -Louis und seine außerirdischen Kohlköpfe -Luther -Mallrats -Man lebt nur zweimal -Marillion Christmas in the Chapel -Marillion Live From Loreley -Marillion shot in the dark -Marnie -Master & Commander -Maverick -"MexiCollection -El Mariachi -Desperado -Irgendwann in Mexico" -MIB -MIB 2 -Missing -"Montys enzyklopythonia (Das Leben des Brian, Die Ritter der Kokosnuss, Der Sinn des Lebens)" -Moonraker - Streng Geheim -Mörderischer Vorsprung -Mr. Bean 1 -Mr. Bean 2 -Mr. Bean 3 -Muppets aus dem All -Muppets Die Schatzinsel -Mystic River -Nick Knatterton Teil 1 -Nick Knatterton Teil 2 -Nightmare Before Christmas -Nightwish - end of innocence -Nur 48 Stunden -"O Brother, Where Art Thou?" -Ocean's Eleven -Ocean's Twelve -Octopussy -"Onkel Paul, die große Pflaume" -Open Range -Oscar -Panic Room -Perdita Durango -Peter Gabriel Growing Up Live -Peter Gabriel Secret World Live -Platoon -Pulp Fiction -Rat Race Der nackte Wahnsinn -Reservoir Dogs -Resident Evil -Richy Guitar -Romeo Must Die -Roter Drache -Sag niemals nie -Scary Movie -Scary Movie 2 -Scharfe Kurven für Madame -Schiffsmeldungen -Schlappe Bullen beissen nicht -Scooby-Doo -Scream -Scream 2 -Scrubs: Die Anfänger - Die komplette erste Staffel (4 DVDs) -Scrubs: Die Anfänger - Die komplette zweite Staffel (4 DVDs) -Scrubs: Die Anfänger - Die komplette dritte Staffel (4 DVDs) -Shaft -Shakespeare in Love -Shang-High Noon -Shrek -Shrek 2 -Sideways -Sin City -Sin Eater -Sleepers -Sleepy Hollow -Small Soldiers -snatch Schweine und Diamanten -Solo für Zwei -Sonnenallee -South Park Der Film -Space Cowboys -Spaceballs -Speed Teil 1 + Teil 2 -Sphere -Spider-Man 2 -Spiel mir das Lied vom Tod -Stakeout II -Star Trek 1 -Star Trek 10 Nemesis -Star Trek 2 Der Zorn des Khan -Star Trek 3 Auf der Such nach Mr. Spock -Star Trek 4 Zurück in die Gegenwart -Star Trek 5 Am Rande des Universums -Star Trek 6 Das unentdeckte Land -Star Trek 7 Treffen der Generationen -Star Trek 8 Der erste Kontakt -Star Trek 9 Der Aufstand -Star Wars - Bonusmaterial -Star Wars - Clone Wars Vol. 1 -Star Wars - Clone Wars Vol. 2 -Star Wars - Episode 2 -Star Wars - Episode 3 - Die Rache der Sith -Star Wars - Episode IV - Eine neue Hoffnung -Star Wars - Episode V - Das Imperium schlägt zurück -Star Wars - Episode VI - Die Rückkehr der Jedi-Ritter -Stigmata -Stirb an einem anderen Tag -Stirb langsam 1+2 -Sumo Bruno -Tanz der Teufel -Tanz der Vampire -Terminator 2 Tag der Abrechnung -Terminator 3 Rebellion der Maschinen -The Abyss -The Art of War -The Big Lebowski -The Core -The Crow -The Day After Tomorrow -The Fog Nebel des Grauens -The Game -The Green Mile -The Rock -The Scorpion King -The Time Machine -Three Kings -Tiger & Dragon -Tomb Raider -Tomb Raider Die Wiege des Lebens -Topas -Toy Story -Toy Story 2 -Traffic Macht des Kartells -Troja -Tron -Twister -U-Turn -UHF -Und dann kam Polly -under suspicion Mörderisches Spiel -Underworld -Van Helsing -Verlockende Falle -Verrückt nach Mary -Verrückt nach mehr Mary -Vertigo -Vier Fäuste für ein Halleluja -Vier Fäuste gegen Rio -Volcano -Volker Pispers Live -Wayne's World -Wayne's World 2 -Wilde Kreaturen -X-Men -X-Men 2 -Zoolander -Zurück in die Zukunft Trilogie Boxset -Zwei Asse trumpfen auf -Zwei außer Rand und Band -Zwei bärenstarke Typen -Zwei Himmelhunde auf dem Weg zur Hölle -Zwei hinreissend verdorbene Schurken -Zwei Nasen tanken Super -Zwei sind nicht zu bremsen diff --git a/java-ee/Jenkinsfile b/java-ee/Jenkinsfile deleted file mode 100644 index 2f64305..0000000 --- a/java-ee/Jenkinsfile +++ /dev/null @@ -1,15 +0,0 @@ -node { - stage "Checkout" - checkout scm - stage 'Prepare Gradle build' - sh "chmod +x gradlew" - stage 'Stage Build' - sh "./gradlew --no-daemon clean build -x findbugsMain -x findbugsTest -x test" - stage 'Archive Artifacts' - archiveArtifacts allowEmptyArchive: true, artifacts: '**/build/reports/*/*.xml', defaultExcludes: false, onlyIfSuccessful: true - archiveArtifacts allowEmptyArchive: true, artifacts: '**/reports/*/*.html' - junit allowEmptyResults: true, testResults: '**/build/test-results/*.xml' - //step([$class: 'CheckStylePublisher', pattern: '**/build/reports/checkstyle/*.xml']) - //step([$class: 'FindBugsPublisher', pattern: '**/build/reports/findbugs/*.xml']) -} - diff --git a/java-ee/KontorApp/build.gradle b/java-ee/KontorApp/build.gradle deleted file mode 100644 index 437481b..0000000 --- a/java-ee/KontorApp/build.gradle +++ /dev/null @@ -1,19 +0,0 @@ -apply plugin: 'java' -apply plugin: 'application' - -dependencies { - compile 'org.hibernate:hibernate-core:4.3.8.Final' - compile 'org.hibernate:hibernate-entitymanager:4.3.8.Final' - compile 'org.hsqldb:hsqldb:2.3.0' - compile 'ch.qos.logback:logback-core:1.1.2' - compile 'ch.qos.logback:logback-classic:1.1.2' - testCompile group: 'junit', name: 'junit', version: '4.11' -} - -mainClassName = 'com.ibtp.kontor.KontorApp' - -jar { - manifest { - attributes 'Implementation-Title': 'Kontor Application', 'Implementation-Version': version, 'Main-Class': mainClassName - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/KontorApp.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/KontorApp.java deleted file mode 100644 index b87a849..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/KontorApp.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ibtp.kontor; - -/** - * Created by TPEETZ on 10.02.2015. - */ -public class KontorApp { - - private KontorGUI mainframe; - - public KontorApp() { - mainframe = new KontorGUI(this); - - mainframe.setVisible(true); - } - - public void exitApplication() { - System.exit(0); - } - - public static void main(String[] args) { - new KontorApp(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/KontorGUI.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/KontorGUI.java deleted file mode 100644 index 40a4b2d..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/KontorGUI.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.ibtp.kontor; - - -import com.ibtp.kontor.comics.view.ComicsMenu; -import com.ibtp.kontor.library.view.LibraryMenu; -import com.ibtp.kontor.tradingcards.view.TradingCardsMenu; - -import javax.swing.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -/** - * Created by TPEETZ on 11.02.2015. - */ -public class KontorGUI extends javax.swing.JFrame { - - KontorApp application; - JMenuBar menuBar; - JMenu menuFile; - JMenuItem menuFileExit; - - JMenuItem menuFileStart = new JMenuItem(); - - JMenu menuHelp; - JMenuItem menuHelpAbout; - - public KontorGUI(KontorApp kontorApp) { - application = kontorApp; - initComponents(); - } - - private void initComponents() { - setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - GroupLayout layout = new GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 400, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 300, Short.MAX_VALUE) - ); - pack(); - setTitle("Kontor Application"); - createMainMenu(); - //createToolBar(); - } - - private void createMainMenu() { - menuBar = new JMenuBar(); - menuFile = new JMenu("File"); - menuFileExit = new JMenuItem("Exit"); - menuHelp = new JMenu("Help"); - menuHelpAbout = new JMenuItem("About"); - setJMenuBar(menuBar); - menuBar.add(menuFile); - menuFile.add(menuFileExit); - menuBar.add(new ComicsMenu()); - menuBar.add(new LibraryMenu()); - menuBar.add(new TradingCardsMenu()); - menuBar.add(menuHelp); - menuHelp.add(menuHelpAbout); - menuFileExit.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - application.exitApplication(); - } - }); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/ArtistDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/ArtistDao.java deleted file mode 100644 index 00c4b01..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/ArtistDao.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.ArtistEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 16.01.2015. - */ -interface ArtistDao { - - public ArtistEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public Collection findAll(); - - public ArtistEntity addArtist(String name); - - public ArtistEntity store(ArtistEntity entity); - - public void delete(ArtistEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/ArtistImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/ArtistImpl.java deleted file mode 100644 index 1f5c604..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/ArtistImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.ArtistEntity; -import com.ibtp.kontor.dal.BaseImpl; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 16.01.2015. - */ -public class ArtistImpl extends BaseImpl implements ArtistDao { - - public ArtistImpl() {} - - @Override - public ArtistEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Artist.findById"); - query.setParameter("id", id); - return (ArtistEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Artist.findAll"); - return query.getResultList(); - - } - - @Override - public Collection findByName(String name) { - Query query = getEntityManager().createNamedQuery("Artist.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public ArtistEntity addArtist(String name) { - ArtistEntity artist = new ArtistEntity(name); - artist = store(artist); - return artist; - } - - @Override - public ArtistEntity store(ArtistEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(ArtistEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/ComicDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/ComicDao.java deleted file mode 100644 index c77fb89..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/ComicDao.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.ComicEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by thomas on 17.01.15. - */ -interface ComicDao { - - public ComicEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByTitle(String title); - - public Collection findAll(); - - public ComicEntity addComic(String title); - - public ComicEntity store(ComicEntity entity); - - public void delete(ComicEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/ComicImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/ComicImpl.java deleted file mode 100644 index ecbad88..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/ComicImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.ComicEntity; -import com.ibtp.kontor.dal.BaseImpl; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class ComicImpl extends BaseImpl implements ComicDao { - - @Override - public ComicEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Comic.findById"); - query.setParameter("id", id); - return (ComicEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByTitle(String title) { - Query query = getEntityManager().createNamedQuery("Comic.findByTitle"); - query.setParameter("title", title); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Comic.findAll"); - return query.getResultList(); - } - - @Override - public ComicEntity addComic(String title) { - ComicEntity comicEntity = new ComicEntity(); - comicEntity.setTitle(title); - store(comicEntity); - return comicEntity; - } - - @Override - public ComicEntity store(ComicEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(ComicEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/IssueDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/IssueDao.java deleted file mode 100644 index 49a5ab2..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/IssueDao.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.IssueEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -interface IssueDao { - public IssueEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByNumber(String number); - - public Collection findAll(); - - public IssueEntity store(IssueEntity entity); - - public void delete(IssueEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/IssueImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/IssueImpl.java deleted file mode 100644 index 8f70845..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/IssueImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.IssueEntity; -import com.ibtp.kontor.dal.BaseImpl; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class IssueImpl extends BaseImpl implements IssueDao { - - @Override - public IssueEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Issue.findById"); - query.setParameter("id", id); - return (IssueEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByNumber(String number) { - Query query = getEntityManager().createNamedQuery("Issue.findByNumber"); - query.setParameter("number", number); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Issue.findAll"); - return query.getResultList(); - } - - @Override - public IssueEntity store(IssueEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(IssueEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/PublisherDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/PublisherDao.java deleted file mode 100644 index 0722522..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/PublisherDao.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.PublisherEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by thomas on 17.01.15. - */ -interface PublisherDao { - - public PublisherEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public Collection findAll(); - - public PublisherEntity addPublisher(String name); - - public PublisherEntity store(PublisherEntity entity); - - public void delete(PublisherEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/PublisherImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/PublisherImpl.java deleted file mode 100644 index d911c4d..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/PublisherImpl.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.PublisherEntity; -import com.ibtp.kontor.dal.BaseImpl; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 20.01.2015. - */ -public class PublisherImpl extends BaseImpl implements PublisherDao { - - @Override - public PublisherEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - Query query = getEntityManager().createNamedQuery("Publisher.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Publisher.findAll"); - return query.getResultList(); - } - - @Override - public PublisherEntity addPublisher(String name) { - PublisherEntity publisher = new PublisherEntity(name); - store(publisher); - return publisher; - } - - @Override - public PublisherEntity store(PublisherEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(PublisherEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/StoryArcDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/StoryArcDao.java deleted file mode 100644 index 40761fe..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/StoryArcDao.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.StoryArcEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -interface StoryArcDao { - - public StoryArcEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByTitle(String title); - - public Collection findAll(); - - public StoryArcEntity store(StoryArcEntity entity); - - public void delete(StoryArcEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/StoryArcImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/StoryArcImpl.java deleted file mode 100644 index 3a39271..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/StoryArcImpl.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.StoryArcEntity; -import com.ibtp.kontor.dal.BaseImpl; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class StoryArcImpl extends BaseImpl implements StoryArcDao { - - @Override - public StoryArcEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByTitle(String title) { - Query query = getEntityManager().createNamedQuery("StoryArc.findByTitle"); - query.setParameter("title", title); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("StoryArc.findAll"); - return query.getResultList(); - } - - @Override - public StoryArcEntity store(StoryArcEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(StoryArcEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/VolumeDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/VolumeDao.java deleted file mode 100644 index 26759bd..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/VolumeDao.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.VolumeEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -interface VolumeDao { - - public VolumeEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByTitle(String title); - - public Collection findAll(); - - public VolumeEntity store(VolumeEntity entity); - - public void delete(VolumeEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/VolumeImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/VolumeImpl.java deleted file mode 100644 index bb20a4a..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/dal/VolumeImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.VolumeEntity; -import com.ibtp.kontor.dal.BaseImpl; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class VolumeImpl extends BaseImpl implements VolumeDao { - - @Override - public VolumeEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Volume.findById"); - query.setParameter("id", id); - return (VolumeEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByTitle(String title) { - Query query = getEntityManager().createNamedQuery("Volume.findByTitle"); - query.setParameter("title", title); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Volume.findAll"); - return query.getResultList(); - } - - @Override - public VolumeEntity store(VolumeEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(VolumeEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/ArtistEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/ArtistEntity.java deleted file mode 100644 index 50ede83..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/ArtistEntity.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Created by TPEETZ on 16.01.2015. - */ -@NamedQueries({ - @NamedQuery(name="Artist.findAll", query="SELECT a from ArtistEntity as a"), - @NamedQuery(name="Artist.findByName", query="SELECT a from ArtistEntity as a WHERE a.name = :name") -}) - -@Entity -@Table(name="ARTIST") -public class ArtistEntity { - - private Long id; - - private String name; - - private Collection writtenIssues = new ArrayList(); - - private Collection inkedIssues = new ArrayList(); - - private Collection penciledIssues = new ArrayList(); - - public ArtistEntity(String name) { - setName(name); - } - - public ArtistEntity() {} - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - String getName() { return name; } - - void setName(String name) { this.name = name; } - - public void setWrittenIssues(Collection writtenIssues) { this.writtenIssues = writtenIssues; } - - @OneToMany(mappedBy="writer", cascade=CascadeType.REMOVE) - public Collection getWrittenIssues() { - return writtenIssues; - } - - public void setInkedIssues(Collection inkedIssues) { this.inkedIssues = inkedIssues; } - - @OneToMany(mappedBy="inker", cascade=CascadeType.REMOVE) - public Collection getInkedIssues() { - return inkedIssues; - } - - public void setPenciledIssues(Collection penciledIssues) { this.penciledIssues = penciledIssues; } - - @OneToMany(mappedBy="penciler", cascade=CascadeType.REMOVE) - public Collection getPenciledIssues() { - return penciledIssues; - } - - @Override - public String toString() { - return "Artist[" + "id=" + getId() + ",name=" + getName() + "]"; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/ComicEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/ComicEntity.java deleted file mode 100644 index 2d21c10..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/ComicEntity.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Created by thomas on 17.01.15. - */ -@NamedQueries({ - @NamedQuery(name="Comic.findAll", query="SELECT c from ComicEntity as c"), - @NamedQuery(name="Comic.findByTitle", query="SELECT c from ComicEntity as c WHERE c.title = :title") -}) -@Entity -@Table(name = "COMIC") -public class ComicEntity { - - private Long id; - - private String title; - - private Boolean completed; - - private Boolean currentOrder; - - private Collection issues = new ArrayList(); - - private Collection storyArc = new ArrayList(); - - private Collection volumes = new ArrayList(); - - private PublisherEntity publisher; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } - - @Column - public Boolean getCompleted() { return completed; } - - public Boolean isCompleted() { return completed; } - - public void setCompleted(Boolean completed) { this.completed = completed; } - - @Column - public Boolean getCurrentOrder() { return currentOrder; } - - public Boolean isCurrentOrder() { return currentOrder; } - - public void setCurrentOrder(Boolean currentOrder) { this.currentOrder = currentOrder; } - - public void setIssues(Collection issues) { this.issues = issues; } - - @OneToMany(mappedBy="comic", cascade=CascadeType.REMOVE) - public Collection getIssues() { return issues; } - - public void setStoryArc(Collection storyArc) { this.storyArc = storyArc; } - - @OneToMany(mappedBy="comic", cascade=CascadeType.REMOVE) - public Collection getStoryArc() { return storyArc; } - - public void setVolumes(Collection volumes) { this.volumes = volumes; } - - @OneToMany(mappedBy="comic", cascade=CascadeType.REMOVE) - public Collection getVolumes() { return volumes; } - - @ManyToOne - public PublisherEntity getPublisher() { return publisher; } - - public void setPublisher(PublisherEntity publisher) { - this.publisher = publisher; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/IssueEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/IssueEntity.java deleted file mode 100644 index 93a7662..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/IssueEntity.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import javax.persistence.*; - -/** - * Created by thomas on 18.01.15. - */ -@NamedQueries({ - @NamedQuery(name="Issue.findAll", query="SELECT i from IssueEntity as i"), - @NamedQuery(name="Issue.findByNumber", query="SELECT i from IssueEntity as i WHERE i.number = :number") -}) - -@Entity -@Table(name = "ISSUE") -public class IssueEntity { - - private Long id; - - private String number; - - private Boolean completed; - - private ComicEntity comic; - - private ArtistEntity writer; - - private ArtistEntity inker; - - private ArtistEntity penciler; - - private StoryArcEntity storyArc; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getNumber() { return number; } - - public void setNumber(String number) { this.number = number; } - - @Column - public Boolean getCompleted() { return completed; } - public Boolean isCompleted() { return completed; } - - public void setCompleted(Boolean completed) { this.completed = completed; } - - public void setComic(ComicEntity comic) { this.comic = comic; } - - @ManyToOne - public ComicEntity getComic() { return comic; } - - public void setWriter(ArtistEntity writer) { this.writer = writer; } - - @ManyToOne - public ArtistEntity getWriter() { return writer; } - - public void setInker(ArtistEntity inker) { this.inker = inker; } - - @ManyToOne - public ArtistEntity getInker() { return inker; } - - public void setPenciler(ArtistEntity penciler) { this.penciler = penciler; } - - @ManyToOne - public ArtistEntity getPenciler() { return penciler; } - - public void setStoryArc(StoryArcEntity storyArc) { this.storyArc = storyArc; } - - @ManyToOne - public StoryArcEntity getStoryArc() { return storyArc; } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/PublisherEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/PublisherEntity.java deleted file mode 100644 index 9aec40e..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/PublisherEntity.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Created by thomas on 17.01.15. - */ -@NamedQueries({ - @NamedQuery(name="Publisher.findAll", query="SELECT p from PublisherEntity as p"), - @NamedQuery(name="Publisher.findByName", query="SELECT p from PublisherEntity as p WHERE p.name = :name") -}) - -@Entity -@Table(name = "PUBLISHER") -public class PublisherEntity { - - private Long id; - - private String name; - - private Collection comic = new ArrayList(); - - public PublisherEntity() {} - - public PublisherEntity(String name) { - setName(name); - } - - @Id - @GeneratedValue(strategy= GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { return name; } - - void setName(String name) { this.name = name; } - - public void setComic(Collection comic) { this.comic = comic; } - - @OneToMany(mappedBy="publisher", cascade=CascadeType.REMOVE) - public Collection getComic() { return comic; } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/StoryArcEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/StoryArcEntity.java deleted file mode 100644 index e3ea22b..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/StoryArcEntity.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Created by thomas on 17.01.15. - */ -@NamedQueries({ - @NamedQuery(name="StoryArc.findAll", query="SELECT s from StoryArcEntity as s"), - @NamedQuery(name="StoryArc.findByTitle", query="SELECT s from StoryArcEntity as s WHERE s.title = :title") -}) - -@Entity -@Table(name = "STORYARC") -public class StoryArcEntity { - - private Long id; - - private String title; - - private Collection issues = new ArrayList(); - - private ComicEntity comic; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } - - public void setIssues(Collection issues) { this.issues = issues; } - - @OneToMany(mappedBy="storyArc", cascade=CascadeType.REMOVE) - public Collection getIssues() { return issues; } - - public void setComic(ComicEntity comic) { this.comic = comic; } - - @ManyToOne - public ComicEntity getComic() { return comic; } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/VolumeEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/VolumeEntity.java deleted file mode 100644 index 6f896ad..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/entity/VolumeEntity.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.ibtp.kontor.comics.entity; - - -import javax.persistence.*; - -/** - * Created by TPEETZ on 19.01.2015. - */ -@NamedQueries({ - @NamedQuery(name="Volume.findAll", query="SELECT v from VolumeEntity as v"), - @NamedQuery(name="Volume.findByTitle", query="SELECT v from VolumeEntity as v WHERE v.title = :title") -}) - -@Entity -@Table(name = "VOLUME") -public class VolumeEntity { - - private Long id; - - private String title; - - private ComicEntity comic; - - @Id - @GeneratedValue(strategy= GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } - - @ManyToOne - public ComicEntity getComic() { return comic; } - - public void setComic(ComicEntity comic) { this.comic = comic; } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/view/ComicsMenu.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/view/ComicsMenu.java deleted file mode 100644 index 5201a11..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/comics/view/ComicsMenu.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.ibtp.kontor.comics.view; - -import javax.swing.*; - -/** - * Created by tpeetz on 12.02.2015. - */ -public class ComicsMenu extends JMenu { - - public ComicsMenu() { - super("Comics"); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/dal/BaseImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/dal/BaseImpl.java deleted file mode 100644 index fa22722..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/dal/BaseImpl.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.ibtp.kontor.dal; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.persistence.EntityManager; - -/** - * Created by TPEETZ on 16.01.2015. - */ -public class BaseImpl { - - protected BaseImpl() { - Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - logger.info("BaseImpl started"); - } - - protected EntityManager getEntityManager() { - return DatabaseManager.getDatabase().getEntityManager(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/dal/Database.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/dal/Database.java deleted file mode 100644 index 67dbda9..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/dal/Database.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.ibtp.kontor.dal; - -import javax.persistence.EntityManager; - -/** - * Created by TPEETZ on 21.01.2015. - */ -public interface Database { - - public EntityManager getEntityManager(); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/dal/DatabaseManager.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/dal/DatabaseManager.java deleted file mode 100644 index 0ccc25d..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/dal/DatabaseManager.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ibtp.kontor.dal; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Created by TPEETZ on 22.01.2015. - */ -public class DatabaseManager { - - private static Database database; - private static Logger logger = LoggerFactory.getLogger(DatabaseManager.class.getName()); - - public static Database getDatabase() { - logger.info("return " + database.toString()); - return database; - } - - public static void setDatabase(Database database) { - logger.info("set " + database.toString()); - DatabaseManager.database = database; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/dal/LocalDatabase.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/dal/LocalDatabase.java deleted file mode 100644 index 37cc68b..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/dal/LocalDatabase.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.ibtp.kontor.dal; - -import org.hibernate.jpa.HibernatePersistenceProvider; -import org.hsqldb.Server; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import javax.persistence.spi.PersistenceProvider; -import javax.persistence.spi.PersistenceProviderResolver; -import javax.persistence.spi.PersistenceProviderResolverHolder; -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -public class LocalDatabase implements Database { - - private static Server server; - private static EntityManagerFactory factory; - private static EntityManager em; - private static Logger logger = LoggerFactory.getLogger(LocalDatabase.class.getName()); - - private LocalDatabase() { - logger.info("LocalDatabase started"); - } - - private static void assureDatabaseRunning() { - if (LocalDatabase.server == null) { - LocalDatabase.startDatabase(); - } - } - - private static void startDatabase() { - Logger logger = LoggerFactory.getLogger(LocalDatabase.class.getName()); - logger.info("startDatabase as kontor in hsqldb_databases/kontor"); - LocalDatabase.server = new Server(); - LocalDatabase.server.setAddress("localhost"); - LocalDatabase.server.setDatabaseName(0, "kontor"); - LocalDatabase.server.setDatabasePath(0, "file:hsqldb_databases/kontor"); - LocalDatabase.server.setPort(2345); - LocalDatabase.server.setTrace(true); - LocalDatabase.server.setLogWriter(new PrintWriter(System.out)); - LocalDatabase.server.start(); - } - - private static void stopDatabase() { - server.shutdown(); - } - private static EntityManagerFactory getFactory() { - if (LocalDatabase.factory == null) { - LocalDatabase.assureDatabaseRunning(); - PersistenceProviderResolverHolder.setPersistenceProviderResolver(new PersistenceProviderResolver() { - private final List providers_ = Arrays.asList((PersistenceProvider) new HibernatePersistenceProvider()); - - @Override - public void clearCachedProviders() { - // Auto-generated method stub - } - - @Override - public List getPersistenceProviders() { - return providers_; - } - }); - LocalDatabase.factory = Persistence.createEntityManagerFactory("com.ibtp.kontor"); - logger.info("EntityManagerFactory(com.ibtp.kontor) created"); - } - return LocalDatabase.factory; - } - - private static EntityManager getSingleEntityManager() { - return LocalDatabase.em; - } - - private static void setSingleEntityManager(EntityManager manager) { - LocalDatabase.em = manager; - } - - @Override - public EntityManager getEntityManager() { - if (getSingleEntityManager() == null) { - setSingleEntityManager(getFactory().createEntityManager()); - logger.info("EntityManager created"); - } - return getSingleEntityManager(); - } - - @Override - public String toString() { - String serverMessage; - if (LocalDatabase.server == null) { - serverMessage = "server:null"; - } else { - serverMessage = LocalDatabase.server.toString(); - } - return LocalDatabase.class.getName() + " " + serverMessage; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/ArticleDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/ArticleDao.java deleted file mode 100644 index f9cd144..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/ArticleDao.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.library.entity.ArticleEntity; - -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -interface ArticleDao { - - public ArticleEntity getById(Long id); - - public List findByIds(List ids); - - public List findAll(); - - public List findByTitle(String title); - - public ArticleEntity store(ArticleEntity entity); - - public void delete(ArticleEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/ArticleImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/ArticleImpl.java deleted file mode 100644 index ada92d9..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/ArticleImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.library.entity.ArticleEntity; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -public class ArticleImpl extends BaseImpl implements ArticleDao { - - @Override - public ArticleEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Article.findById"); - query.setParameter("id", id); - return (ArticleEntity)query.getSingleResult(); - } - - @Override - public List findByIds(List ids) { - return null; - } - - @Override - public List findAll() { - Query query = getEntityManager().createNamedQuery("Article.findAll"); - //noinspection unchecked - return query.getResultList(); - } - - @Override - public List findByTitle(String title) { - Query query = getEntityManager().createNamedQuery("Article.findByTitle"); - query.setParameter("title", title); - //noinspection unchecked - return query.getResultList(); - } - - public ArticleEntity addArticle(String title) { - ArticleEntity entity = new ArticleEntity(title); - store(entity); - return entity; - } - - @Override - public ArticleEntity store(ArticleEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(ArticleEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/AuthorDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/AuthorDao.java deleted file mode 100644 index 85f4c83..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/AuthorDao.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.library.entity.AuthorEntity; - -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -interface AuthorDao { - - public AuthorEntity getById(Long id); - - public List findByIds(List ids); - - public List findByName(String name); - - public List findAll(); - - public AuthorEntity addAuthor(String name); - - public AuthorEntity store(AuthorEntity entity); - - public void delete(AuthorEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/AuthorImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/AuthorImpl.java deleted file mode 100644 index 573d7d9..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/AuthorImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.library.entity.AuthorEntity; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.List; - -/** - * Created by thomas on 23.01.15. - */ -public class AuthorImpl extends BaseImpl implements AuthorDao { - - public AuthorImpl() {} - - @Override - public AuthorEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Author.findById"); - query.setParameter("id", id); - return (AuthorEntity)query.getSingleResult(); - } - - @Override - public List findByIds(List ids) { - return null; - } - - @Override - public List findByName(String name) { - Query query = getEntityManager().createNamedQuery("Author.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public List findAll() { - Query query = getEntityManager().createNamedQuery("Author.findAll"); - return query.getResultList(); - } - - @Override - public AuthorEntity addAuthor(String name) { - AuthorEntity author = new AuthorEntity(name); - store(author); - return author; - } - - @Override - public AuthorEntity store(AuthorEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(AuthorEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/BookDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/BookDao.java deleted file mode 100644 index d89a1b7..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/BookDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.library.entity.BookEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -interface BookDao { - - public BookEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public BookEntity store(BookEntity entity); - - public void delete(BookEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/BookImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/BookImpl.java deleted file mode 100644 index 63f0ab1..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/BookImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.library.entity.BookEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class BookImpl extends BaseImpl implements BookDao { - - @Override - public BookEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public BookEntity store(BookEntity entity) { - return null; - } - - @Override - public void delete(BookEntity entity) { - - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/FileDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/FileDao.java deleted file mode 100644 index f123e69..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/FileDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.library.entity.FileEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -interface FileDao { - - public FileEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public FileEntity store(FileEntity entity); - - public void delete(FileEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/FileImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/FileImpl.java deleted file mode 100644 index 1af2900..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/FileImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.library.entity.FileEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class FileImpl extends BaseImpl implements FileDao { - - @Override - public FileEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public FileEntity store(FileEntity entity) { - return null; - } - - @Override - public void delete(FileEntity entity) { - - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/TitleDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/TitleDao.java deleted file mode 100644 index 81da92b..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/TitleDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.library.entity.TitleEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -interface TitleDao { - - public TitleEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public TitleEntity store(TitleEntity entity); - - public void delete(TitleEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/TitleImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/TitleImpl.java deleted file mode 100644 index 410c2c5..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/dal/TitleImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.library.entity.TitleEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class TitleImpl extends BaseImpl implements TitleDao { - - @Override - public TitleEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public TitleEntity store(TitleEntity entity) { - return null; - } - - @Override - public void delete(TitleEntity entity) { - - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/ArticleEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/ArticleEntity.java deleted file mode 100644 index d61eda5..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/ArticleEntity.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ibtp.kontor.library.entity; - -import javax.persistence.*; - -/** - * Created by TPEETZ on 23.01.2015. - */ -@NamedQueries({ - @NamedQuery(name="Article.findAll", query="SELECT a from ArticleEntity as a"), - @NamedQuery(name="Article.findByTitle", query="SELECT a from ArticleEntity as a WHERE a.title = :title") -}) - -@Entity -@Table(name = "ARTICLE") -public class ArticleEntity { - - private Long id; - - private String title; - - private AuthorEntity author; - - public ArticleEntity() {} - - public ArticleEntity(String title) { - setTitle(title); - } - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - @Column - public String getTitle() { - return title; - } - - void setTitle(String title) { - this.title = title; - } - - @ManyToOne - public AuthorEntity getAuthor() { - return author; - } - - public void setAuthor(AuthorEntity author) { - this.author = author; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/AuthorEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/AuthorEntity.java deleted file mode 100644 index 63a6f4b..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/AuthorEntity.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.ibtp.kontor.library.entity; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Created by TPEETZ on 23.01.2015. - */ -@NamedQueries({ - @NamedQuery(name="Author.findAll", query="SELECT a from AuthorEntity as a"), - @NamedQuery(name="Author.findById", query="SELECT a from AuthorEntity as a WHERE a.id = :id"), - @NamedQuery(name="Author.findByName", query="SELECT a from AuthorEntity as a WHERE a.name = :name") -}) -@Entity -@Table(name="AUTHOR") -public class AuthorEntity { - - private Long id; - - private String name; - - private Collection books = new ArrayList(); - - private Collection articles = new ArrayList(); - - public AuthorEntity() {} - - public AuthorEntity(String name) { - setName(name); - } - - @Id - @GeneratedValue(strategy= GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { return name; } - - void setName(String name) { this.name = name; } - - @OneToMany(mappedBy="author", cascade=CascadeType.REMOVE) - public Collection getBooks() { - return books; - } - - public void setBooks(Collection books) { - this.books = books; - } - - @OneToMany(mappedBy="author", cascade=CascadeType.REMOVE) - public Collection getArticles() { - return articles; - } - - public void setArticles(Collection articles) { - this.articles = articles; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/BookEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/BookEntity.java deleted file mode 100644 index b57705c..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/BookEntity.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.ibtp.kontor.library.entity; - -import javax.persistence.*; - -/** - * Created by TPEETZ on 23.01.2015. - */ -@Entity -@Table(name = "BOOK") -public class BookEntity { - - private Long id; - - private String title; - - private AuthorEntity author; - - private String publisher; - - private String isbn; - - private Long page; - - private String edition; - - public BookEntity() {} - - public BookEntity(String title) { - setTitle(title); - } - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - public Long getId() { - return id; - } - - /* unused */ - public void setId(Long id) { - this.id = id; - } - - @Column - public String getTitle() { - return title; - } - - void setTitle(String title) { - this.title = title; - } - - @ManyToOne - public AuthorEntity getAuthor() { - return author; - } - - public void setAuthor(AuthorEntity author) { - this.author = author; - } - - @Column - public String getIsbn() { - return isbn; - } - - public void setIsbn(String isbn) { - this.isbn = isbn; - } - - @Column - public Long getPage() { - return page; - } - - public void setPage(Long page) { - this.page = page; - } - - @Column - public String getEdition() { - return edition; - } - - public void setEdition(String edition) { - this.edition = edition; - } - - @Column - public String getPublisher() { - return publisher; - } - - public void setPublisher(String publisher) { - this.publisher = publisher; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/FileEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/FileEntity.java deleted file mode 100644 index 05f4577..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/FileEntity.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.ibtp.kontor.library.entity; - -import javax.persistence.*; - -/** - * Created by TPEETZ on 23.01.2015. - */ -@Entity -@Table(name = "FILE") -public class FileEntity { - - private Long id; - - private String title; - - public FileEntity() {} - - public FileEntity(String title) { - setTitle(title); - } - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - public Long getId() { - return id; - } - - /* unused */ - public void setId(Long id) { - this.id = id; - } - - @Column - public String getTitle() { - return title; - } - - void setTitle(String title) { - this.title = title; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/TitleEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/TitleEntity.java deleted file mode 100644 index ba25eb9..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/entity/TitleEntity.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.ibtp.kontor.library.entity; - -import javax.persistence.*; - -/** - * Created by TPEETZ on 23.01.2015. - */ -@Entity -@Table(name = "TITLE") -public class TitleEntity { - - private Long id; - - private String title; - - @Id - @GeneratedValue(strategy= GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/view/LibraryMenu.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/view/LibraryMenu.java deleted file mode 100644 index 0b97e27..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/library/view/LibraryMenu.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.ibtp.kontor.library.view; - -import javax.swing.*; - -/** - * Created by tpeetz on 12.02.2015. - */ -public class LibraryMenu extends JMenu { - - public LibraryMenu() { - super("Library"); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/BaseSetDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/BaseSetDao.java deleted file mode 100644 index 29692d4..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/BaseSetDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.BaseSetEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -interface BaseSetDao { - - public BaseSetEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public BaseSetEntity store(BaseSetEntity entity); - - public void delete(BaseSetEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/BaseSetImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/BaseSetImpl.java deleted file mode 100644 index 9e584a4..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/BaseSetImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.BaseSetEntity; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class BaseSetImpl extends BaseImpl implements BaseSetDao { - - @Override - public BaseSetEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("BaseSet.findById"); - query.setParameter("id", id); - return (BaseSetEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - Query query = getEntityManager().createNamedQuery("BaseSet.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public BaseSetEntity store(BaseSetEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(BaseSetEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/InsertDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/InsertDao.java deleted file mode 100644 index c68790f..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/InsertDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.InsertEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -interface InsertDao { - - public InsertEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public InsertEntity store(InsertEntity entity); - - public void delete(InsertEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/InsertImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/InsertImpl.java deleted file mode 100644 index 598763c..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/InsertImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.InsertEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class InsertImpl extends BaseImpl implements InsertDao { - - @Override - public InsertEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public InsertEntity store(InsertEntity entity) { - return null; - } - - @Override - public void delete(InsertEntity entity) { - - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/ManufacturerDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/ManufacturerDao.java deleted file mode 100644 index 451d18b..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/ManufacturerDao.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - - -import com.ibtp.kontor.tradingcards.entity.BaseSetEntity; -import com.ibtp.kontor.tradingcards.entity.ManufacturerEntity; - -import java.util.Collection; -import java.util.List; - -/** - * - * @author tpeetz - */ -interface ManufacturerDao { - - public ManufacturerEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public ManufacturerEntity assignBaseSet(ManufacturerEntity manufacturer, BaseSetEntity baseSet); - - public ManufacturerEntity addManufacturer(String name); - - public ManufacturerEntity store(ManufacturerEntity entity); - - public void delete(ManufacturerEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/ManufacturerImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/ManufacturerImpl.java deleted file mode 100644 index 58c2fd6..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/ManufacturerImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.BaseSetEntity; -import com.ibtp.kontor.tradingcards.entity.ManufacturerEntity; - -import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.Query; - -/** - * - * @author tpeetz - */ -public class ManufacturerImpl extends BaseImpl implements ManufacturerDao { - - @Override - public ManufacturerEntity getById(Long id) { - Query q = getEntityManager().createNamedQuery("Manufacturer.findById"); - q.setParameter("id", id); - return (ManufacturerEntity)q.getSingleResult(); - } - - @Override - public List findByIds(List ids) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @SuppressWarnings("unchecked") - @Override - public List findByName(String name) { - Query q = getEntityManager().createNamedQuery("Manufacturer.findByName"); - q.setParameter("name", name); - return q.getResultList(); - } - - @Override - public ManufacturerEntity assignBaseSet(ManufacturerEntity comic, BaseSetEntity baseSet) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public ManufacturerEntity addManufacturer(String name) { - ManufacturerEntity manufacturer = new ManufacturerEntity(name); - store(manufacturer); - return manufacturer; - } - - @Override - public ManufacturerEntity store(ManufacturerEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(ManufacturerEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/ParallelSetDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/ParallelSetDao.java deleted file mode 100644 index c4d36ba..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/ParallelSetDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.ParallelSetEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -interface ParallelSetDao { - - public ParallelSetEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public ParallelSetEntity store(ParallelSetEntity entity); - - public void delete(ParallelSetEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/ParallelSetImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/ParallelSetImpl.java deleted file mode 100644 index cb604a0..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/ParallelSetImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.ParallelSetEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class ParallelSetImpl extends BaseImpl implements ParallelSetDao { - - @Override - public ParallelSetEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public ParallelSetEntity store(ParallelSetEntity entity) { - return null; - } - - @Override - public void delete(ParallelSetEntity entity) { - - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/PlayerDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/PlayerDao.java deleted file mode 100644 index 11d045e..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/PlayerDao.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.PlayerEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -interface PlayerDao { - - public PlayerEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public PlayerEntity addPlayer(String name); - - public PlayerEntity store(PlayerEntity entity); - - public void delete(PlayerEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/PlayerImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/PlayerImpl.java deleted file mode 100644 index c3d5104..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/PlayerImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.PlayerEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class PlayerImpl extends BaseImpl implements PlayerDao { - - @Override - public PlayerEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public PlayerEntity addPlayer(String name) { - return null; - } - - @Override - public PlayerEntity store(PlayerEntity entity) { - return null; - } - - @Override - public void delete(PlayerEntity entity) { - - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/PositionDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/PositionDao.java deleted file mode 100644 index 9970491..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/PositionDao.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.PositionEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -interface PositionDao { - - public PositionEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public Collection findAll(); - - public PositionEntity addPosition(String name); - - public PositionEntity store(PositionEntity entity); - - public void delete(PositionEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/PositionImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/PositionImpl.java deleted file mode 100644 index 8aad906..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/PositionImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.PositionEntity; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class PositionImpl extends BaseImpl implements PositionDao { - - @Override - public PositionEntity getById(Long id) { - Query q = getEntityManager().createNamedQuery("Position.findById"); - q.setParameter("id", id); - return (PositionEntity)q.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - Query q = getEntityManager().createNamedQuery("Position.findByName"); - q.setParameter("name", name); - return q.getResultList(); - } - - @Override - public Collection findAll() { - Query q = getEntityManager().createNamedQuery("Position.findAll"); - return q.getResultList(); - } - - @Override - public PositionEntity addPosition(String name) { - PositionEntity position = new PositionEntity(name); - store(position); - return position; - } - - @Override - public PositionEntity store(PositionEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(PositionEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/SportCardDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/SportCardDao.java deleted file mode 100644 index 25fb244..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/SportCardDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.SportCardEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -interface SportCardDao { - - public SportCardEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public SportCardEntity store(SportCardEntity entity); - - public void delete(SportCardEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/SportCardImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/SportCardImpl.java deleted file mode 100644 index 5939d2c..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/SportCardImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.SportCardEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class SportCardImpl extends BaseImpl implements SportCardDao { - - @Override - public SportCardEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public SportCardEntity store(SportCardEntity entity) { - return null; - } - - @Override - public void delete(SportCardEntity entity) { - - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/SportDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/SportDao.java deleted file mode 100644 index f5ba51e..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/SportDao.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.SportEntity; - -import java.util.Collection; -import java.util.List; - -/** - * - * @author tpeetz - */ -interface SportDao { - public SportEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public Collection findAll(); - - public SportEntity addSport(String name); - - public SportEntity store(SportEntity entity); - - public void delete(SportEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/SportImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/SportImpl.java deleted file mode 100644 index 223236d..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/SportImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.SportEntity; - -import java.util.Collection; -import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.Query; - -/** - * - * @author tpeetz - */ -public class SportImpl extends BaseImpl implements SportDao { - - @Override - public SportEntity getById(Long id) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public List findByIds(List ids) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @SuppressWarnings("unchecked") - @Override - public List findByName(String name) { - Query query = getEntityManager().createNamedQuery("Sport.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Sport.findAll"); - return query.getResultList(); - } - - @Override - public SportEntity addSport(String name) { - SportEntity sport = new SportEntity(name); - store(sport); - return sport; - } - - @Override - public SportEntity store(SportEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(SportEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/TeamDao.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/TeamDao.java deleted file mode 100644 index c2f9eff..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/TeamDao.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.SportEntity; -import com.ibtp.kontor.tradingcards.entity.TeamEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -interface TeamDao { - public TeamEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public Collection findAll(); - - public TeamEntity addTeam(String name, SportEntity sport); - - public TeamEntity store(TeamEntity entity); - - public void delete(TeamEntity entity); -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/TeamImpl.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/TeamImpl.java deleted file mode 100644 index 7fb8244..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/dal/TeamImpl.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.SportEntity; -import com.ibtp.kontor.tradingcards.entity.TeamEntity; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -public class TeamImpl extends BaseImpl implements TeamDao { - - @Override - public TeamEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Team.findById"); - query.setParameter("id", id); - return (TeamEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - Query query = getEntityManager().createNamedQuery("Team.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Team.findAll"); - return query.getResultList(); - } - - @Override - public TeamEntity addTeam(String name, SportEntity sport) { - TeamEntity team = new TeamEntity(name); - team.setSport(sport); - store(team); - return team; - } - - @Override - public TeamEntity store(TeamEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(TeamEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/BaseSetEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/BaseSetEntity.java deleted file mode 100644 index 3111e98..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/BaseSetEntity.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@Entity -@Table(name="BASESET") -public class BaseSetEntity { - private Long id; - private String name; - private ManufacturerEntity manufacturer; - private Collection parallelSets = new ArrayList(); - private Collection inserts = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @ManyToOne - public ManufacturerEntity getManufacturer() { - return manufacturer; - } - - public void setManufacturer(ManufacturerEntity manufacturer) { - this.manufacturer = manufacturer; - } - - @OneToMany(mappedBy="baseSet", cascade=CascadeType.REMOVE) - public Collection getParallelSets() { - return parallelSets; - } - - public void setParallelSets(Collection parallelSets) { - this.parallelSets = parallelSets; - } - - @OneToMany(mappedBy="baseSet", cascade=CascadeType.REMOVE) - public Collection getInserts() { - return inserts; - } - - public void setInserts(Collection inserts) { - this.inserts = inserts; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/InsertEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/InsertEntity.java deleted file mode 100644 index ce59037..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/InsertEntity.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="InsertSet.findAll", query="SELECT i from InsertEntity as i"), - @NamedQuery(name="InsertSet.findById", query="SELECT i from InsertEntity as i WHERE i.id = :id"), - @NamedQuery(name="InsertSet.findByName", query="SELECT i from InsertEntity as i WHERE i.name = :name") -}) - -@Entity -@Table(name="INSERTSET") -public class InsertEntity { - private Long id; - private String name; - private ManufacturerEntity manufacturer; - private BaseSetEntity baseSet; - private Collection sportCard = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @ManyToOne - public ManufacturerEntity getManufacturer() { - return manufacturer; - } - - public void setManufacturer(ManufacturerEntity manufacturer) { - this.manufacturer = manufacturer; - } - - @ManyToOne - public BaseSetEntity getBaseSet() { - return baseSet; - } - - public void setBaseSet(BaseSetEntity baseSet) { - this.baseSet = baseSet; - } - - @OneToMany(mappedBy="insert", cascade=CascadeType.REMOVE) - public Collection getSportCard() { - return sportCard; - } - - public void setSportCard(Collection sportCard) { - this.sportCard = sportCard; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/ManufacturerEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/ManufacturerEntity.java deleted file mode 100644 index f83da2a..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/ManufacturerEntity.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Manufacturer.findAll", query="SELECT m from ManufacturerEntity as m"), - @NamedQuery(name="Manufacturer.findByName", query="SELECT m from ManufacturerEntity as m WHERE m.name = :name") -}) - -@Entity -@Table(name="MANUFACTURER") -public class ManufacturerEntity { - - private Long id; - private String name; - private Collection baseSets = new ArrayList(); - private Collection parallelSets = new ArrayList(); - private Collection inserts = new ArrayList(); - - public ManufacturerEntity(String name) { - setName(name); - } - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - void setName(String name) { - this.name = name; - } - - @OneToMany(mappedBy="manufacturer", cascade=CascadeType.REMOVE) - public Collection getBaseSets() { - return baseSets; - } - - public void setBaseSets(Collection baseSets) { - this.baseSets = baseSets; - } - - @OneToMany(mappedBy="manufacturer", cascade=CascadeType.REMOVE) - public Collection getParallelSets() { - return parallelSets; - } - - public void setParallelSets(Collection parallelSets) { - this.parallelSets = parallelSets; - } - - @OneToMany(mappedBy="manufacturer", cascade=CascadeType.REMOVE) - public Collection getInserts() { - return inserts; - } - - public void setInserts(Collection inserts) { - this.inserts = inserts; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/ParallelSetEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/ParallelSetEntity.java deleted file mode 100644 index 0ce0c69..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/ParallelSetEntity.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -@Entity -@Table(name="PARALLELSET") -public class ParallelSetEntity { - private Long id; - private String name; - private ManufacturerEntity manufacturer; - - private BaseSetEntity baseSet; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - @ManyToOne - public ManufacturerEntity getManufacturer() { - return manufacturer; - } - - public void setManufacturer(ManufacturerEntity manufacturer) { - this.manufacturer = manufacturer; - } - - public void setName(String name) { - this.name = name; - } - - @ManyToOne - public BaseSetEntity getBaseSet() { - return baseSet; - } - - public void setBaseSet(BaseSetEntity baseSet) { - this.baseSet = baseSet; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/PlayerEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/PlayerEntity.java deleted file mode 100644 index 7c19d70..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/PlayerEntity.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@Entity -@Table(name="PLAYER") -public class PlayerEntity { - private Long id; - private TeamEntity team; - private Collection cards = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @ManyToOne - public TeamEntity getTeam() { - return team; - } - - public void setTeam(TeamEntity team) { - this.team = team; - } - - @OneToMany(mappedBy="player", cascade=CascadeType.REMOVE) - public Collection getCards() { - return cards; - } - - public void setCards(Collection cards) { - this.cards = cards; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/PositionEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/PositionEntity.java deleted file mode 100644 index 3e575e0..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/PositionEntity.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import javax.persistence.*; - -@NamedQueries({ - @NamedQuery(name="Position.findAll", query="SELECT m from PositionEntity as m"), - @NamedQuery(name="Position.findByName", query="SELECT m from PositionEntity as m WHERE m.name = :name") -}) - -@Entity -@Table(name="POSITION") -public class PositionEntity { - - private Long id; - private String name; - private String shortName; - private SportEntity sport; - - public PositionEntity() {} - - public PositionEntity(String name) { setName(name); } - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Column - public String getShortName() { - return shortName; - } - - public void setShortName(String shortName) { - this.shortName = shortName; - } - - @ManyToOne - public SportEntity getSport() { - return sport; - } - - public void setSport(SportEntity sport) { - this.sport = sport; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/SportCardEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/SportCardEntity.java deleted file mode 100644 index f71f722..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/SportCardEntity.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="SportCard.findAll", query="SELECT s from SportCardEntity as s") -}) - -@Entity -@Table(name = "SPORTCARD") -public class SportCardEntity { - private Long id; - private PlayerEntity player; - private BaseSetEntity baseSet; - private ParallelSetEntity parallelSet; - private InsertEntity insert; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @ManyToOne - public PlayerEntity getPlayer() { - return player; - } - - public void setPlayer(PlayerEntity player) { - this.player = player; - } - - @ManyToOne - public BaseSetEntity getBaseSet() { - return baseSet; - } - - public void setBaseSet(BaseSetEntity baseSet) { - this.baseSet = baseSet; - } - - @ManyToOne - public ParallelSetEntity getParallelSet() { - return parallelSet; - } - - public void setParallelSet(ParallelSetEntity parallelSet) { - this.parallelSet = parallelSet; - } - - @ManyToOne - public InsertEntity getInsert() { - return insert; - } - - public void setInsert(InsertEntity insert) { - this.insert = insert; - } - -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/SportEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/SportEntity.java deleted file mode 100644 index 8e2258e..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/SportEntity.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Sport.findAll", query="SELECT s from SportEntity as s"), - @NamedQuery(name="Sport.findByName", query="SELECT s from SportEntity as s WHERE s.name = :name") -}) - -@Entity -@Table(name="SPORT") -public class SportEntity { - - private Long id; - private String name; - private Collection teams = new ArrayList(); - private Collection positions = new ArrayList(); - - public SportEntity() {} - - public SportEntity(String name) { - setName(name); - } - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - String getName() { - return name; - } - - void setName(String name) { - this.name = name; - } - - @OneToMany(mappedBy="sport", cascade=CascadeType.REMOVE) - public Collection getTeams() { - return teams; - } - - public void setTeams(Collection teams) { - this.teams = teams; - } - - @OneToMany(mappedBy="sport", cascade=CascadeType.REMOVE) - public Collection getPositions() { - return positions; - } - - public void setPositions(Collection positions) { - this.positions = positions; - } - - @Override - public String toString() { - return "Sport[" + "id=" + getId() + ",name=" + getName() + "]"; - } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/TeamEntity.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/TeamEntity.java deleted file mode 100644 index 8dbcb77..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/entity/TeamEntity.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Team.findAll", query="SELECT t from TeamEntity as t"), - @NamedQuery(name="Team.findByName", query="SELECT t from TeamEntity as t WHERE t.name = :name") -}) - -@Entity -@Table(name="TEAM") -public class TeamEntity { - - private Long id; - private String name; - private SportEntity sport; - - public TeamEntity() {} - - public TeamEntity(String name) { - setName(name); - } - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { return name; } - - void setName(String name) { this.name = name; } - - @ManyToOne - public SportEntity getSport() { return sport; } - - public void setSport(SportEntity sport) { this.sport = sport; } -} diff --git a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/view/TradingCardsMenu.java b/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/view/TradingCardsMenu.java deleted file mode 100644 index f124056..0000000 --- a/java-ee/KontorApp/src/main/java/com/ibtp/kontor/tradingcards/view/TradingCardsMenu.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.ibtp.kontor.tradingcards.view; - -import javax.swing.*; - -/** - * Created by TPEETZ on 13.02.2015. - */ -public class TradingCardsMenu extends JMenu { - - public TradingCardsMenu() { - super("TradingCards"); - } -} diff --git a/java-ee/KontorApp/src/main/resources/META-INF/persistence.xml b/java-ee/KontorApp/src/main/resources/META-INF/persistence.xml deleted file mode 100644 index 35d671b..0000000 --- a/java-ee/KontorApp/src/main/resources/META-INF/persistence.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - org.hibernate.jpa.HibernatePersistenceProvider - com.ibtp.kontor.comics.entity.ArtistEntity - com.ibtp.kontor.comics.entity.ComicEntity - com.ibtp.kontor.comics.entity.IssueEntity - com.ibtp.kontor.comics.entity.StoryArcEntity - com.ibtp.kontor.comics.entity.VolumeEntity - com.ibtp.kontor.comics.entity.PublisherEntity - com.ibtp.kontor.library.entity.AuthorEntity - com.ibtp.kontor.library.entity.ArticleEntity - com.ibtp.kontor.library.entity.BookEntity - com.ibtp.kontor.library.entity.FileEntity - com.ibtp.kontor.library.entity.TitleEntity - com.ibtp.kontor.tradingcards.entity.SportEntity - com.ibtp.kontor.tradingcards.entity.TeamEntity - com.ibtp.kontor.tradingcards.entity.PositionEntity - com.ibtp.kontor.tradingcards.entity.PlayerEntity - com.ibtp.kontor.tradingcards.entity.ManufacturerEntity - com.ibtp.kontor.tradingcards.entity.BaseSetEntity - com.ibtp.kontor.tradingcards.entity.InsertEntity - com.ibtp.kontor.tradingcards.entity.ParallelSetEntity - com.ibtp.kontor.tradingcards.entity.SportCardEntity - - - - - - - - - - - - - diff --git a/java-ee/KontorApp/src/main/resources/logback.xml b/java-ee/KontorApp/src/main/resources/logback.xml deleted file mode 100644 index e8cff02..0000000 --- a/java-ee/KontorApp/src/main/resources/logback.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - %d{yyyy-MM-dd_HH:mm:ss.SSS} %-5level %logger{36} - %msg%n - - - - - - c:/kontor.log - - %d{yyyy-MM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - c:/kontor.%i.log.zip - 1 - 10 - - - - 2MB - - - - - - - - - - - - - diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/CollectionTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/CollectionTest.java deleted file mode 100644 index 146c854..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/CollectionTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.ibtp.kontor.comics; - -import com.ibtp.kontor.comics.dal.PublisherImpl; -import com.ibtp.kontor.comics.entity.PublisherEntity; -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.*; - -import java.util.Collection; -import java.util.Iterator; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class CollectionTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @After - public void cleanup() { - PublisherImpl publisherImpl = new PublisherImpl(); - Collection publisherEntities = publisherImpl.findAll(); - for (Iterator iterator = publisherEntities.iterator(); iterator.hasNext(); ) { - PublisherEntity next = iterator.next(); - publisherImpl.delete(next); - } - } - - @Test - public void testAddPublishers() { - String publisherName = "Bongo Comics"; - PublisherImpl publisherImpl = new PublisherImpl(); - publisherImpl.addPublisher("Bongo Comics"); - publisherImpl.addPublisher("Marvel"); - Collection publisherList = publisherImpl.findAll(); - Assert.assertEquals(2, publisherList.size()); - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/ArtistImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/ArtistImplTest.java deleted file mode 100644 index 4095fba..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/ArtistImplTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.ArtistEntity; -import com.ibtp.kontor.dal.*; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.*; - -import java.util.Collection; -import java.util.Iterator; - -public class ArtistImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testArtistAddAndDelete() { - String artistName = "testArtistAddAndDelete"; - ArtistImpl artistImpl = new ArtistImpl(); - artistImpl.addArtist(artistName); - Collection resultList = artistImpl.findByName(artistName); - Assert.assertNotNull(resultList); - Assert.assertTrue(resultList.size() > 0); - ArtistEntity artist = (ArtistEntity)(resultList.toArray()[0]); - artistImpl.delete(artist); - resultList = artistImpl.findByName(artistName); - Assert.assertNotNull(resultList); - Assert.assertEquals(0, resultList.size()); - } - - @Test - public void testArtistFindAll() { - ArtistImpl artistImpl = new ArtistImpl(); - Collection artistList = artistImpl.findAll(); - Assert.assertNotNull(artistList); - Assert.assertEquals(0, artistList.size()); - artistImpl.addArtist("testArtistFindAll1"); - artistImpl.addArtist("testArtistFindAll2"); - artistImpl.addArtist("testArtistFindAll3"); - artistList = artistImpl.findAll(); - Assert.assertNotNull(artistList); - Assert.assertEquals(3, artistList.size()); - for (Iterator iterator = artistList.iterator(); iterator.hasNext(); ) { - ArtistEntity next = iterator.next(); - artistImpl.delete(next); - } - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/ComicImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/ComicImplTest.java deleted file mode 100644 index eb494c9..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/ComicImplTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.ComicEntity; -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; -import java.util.Iterator; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class ComicImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testComicAddAndDelete() { - String comicTitle = "Comic1"; - ComicImpl comicImpl = new ComicImpl(); - comicImpl.addComic(comicTitle); - Collection comicList = comicImpl.findByTitle(comicTitle); - Assert.assertNotNull(comicList); - Assert.assertEquals(1, comicList.size()); - comicImpl.delete((ComicEntity) comicList.toArray()[0]); - comicList = comicImpl.findByTitle(comicTitle); - Assert.assertNotNull(comicList); - Assert.assertEquals(0, comicList.size()); - } - - @Test - public void testComicFindAll() { - ComicImpl comicImpl = new ComicImpl(); - comicImpl.addComic("Comic1"); - comicImpl.addComic("Comic2"); - comicImpl.addComic("Comic3"); - Collection comicList = comicImpl.findAll(); - Assert.assertNotNull(comicList); - Assert.assertEquals(3, comicList.size()); - for (Iterator iterator = comicList.iterator(); iterator.hasNext(); ) { - ComicEntity next = iterator.next(); - comicImpl.delete(next); - } - comicList = comicImpl.findAll(); - Assert.assertNotNull(comicList); - Assert.assertEquals(0, comicList.size()); - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/IssueImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/IssueImplTest.java deleted file mode 100644 index 4cf7cdc..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/IssueImplTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.IssueEntity; -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; -import java.util.Iterator; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class IssueImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testIssueAddAndDelete() { - String issueNumber = "42"; - IssueImpl issueImpl = new IssueImpl(); - IssueEntity issue = new IssueEntity(); - issue.setNumber(issueNumber); - issueImpl.store(issue); - Collection issueList = issueImpl.findByNumber(issueNumber); - Assert.assertNotNull(issueList); - Assert.assertEquals(1, issueList.size()); - issueImpl.delete(issue); - issueList = issueImpl.findByNumber(issueNumber); - Assert.assertNotNull(issueList); - Assert.assertEquals(0, issueList.size()); - } - - @Test - public void testIssueFindAll() { - IssueImpl issueImpl = new IssueImpl(); - IssueEntity issue1 = new IssueEntity(); - issue1.setNumber("issue1"); - IssueEntity issue2 = new IssueEntity(); - issue1.setNumber("issue2"); - IssueEntity issue3 = new IssueEntity(); - issue1.setNumber("issue3"); - issueImpl.store(issue1); - issueImpl.store(issue2); - issueImpl.store(issue3); - Collection issueList = issueImpl.findAll(); - Assert.assertNotNull(issueList); - Assert.assertEquals(3, issueList.size()); - for (Iterator iterator = issueList.iterator(); iterator.hasNext(); ) { - IssueEntity next = iterator.next(); - issueImpl.delete(next); - } - issueList = issueImpl.findAll(); - Assert.assertNotNull(issueList); - Assert.assertEquals(0, issueList.size()); - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/PublisherImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/PublisherImplTest.java deleted file mode 100644 index 9f459cc..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/PublisherImplTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.PublisherEntity; -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; -import java.util.Iterator; - -/** - * Created by TPEETZ on 20.01.2015. - */ -public class PublisherImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testPublisherAddAndDelete() { - String publisherName = "testPublisherAddAndDelete"; - PublisherImpl publisherImpl = new PublisherImpl(); - PublisherEntity publisher = publisherImpl.addPublisher(publisherName); - Collection publisherList = publisherImpl.findByName(publisherName); - Assert.assertEquals(1, publisherList.size()); - publisherImpl.delete(publisher); - publisherList = publisherImpl.findByName(publisherName); - Assert.assertEquals(0, publisherList.size()); - } - - @Test - public void testPublisherFindAll() { - PublisherImpl publisherImpl = new PublisherImpl(); - publisherImpl.addPublisher("testDeletePublisher1"); - publisherImpl.addPublisher("testDeletePublisher2"); - publisherImpl.addPublisher("testDeletePublisher3"); - Collection publisherList = publisherImpl.findAll(); - Assert.assertEquals(3, publisherList.size()); - for (Iterator iterator = publisherList.iterator(); iterator.hasNext(); ) { - PublisherEntity next = iterator.next(); - publisherImpl.delete(next); - } - publisherList = publisherImpl.findAll(); - Assert.assertEquals(0, publisherList.size()); - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/StoryArcImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/StoryArcImplTest.java deleted file mode 100644 index 8df7b94..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/StoryArcImplTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.StoryArcEntity; -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class StoryArcImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testStoryArcAddAndDelete() { - String storyArcTtitle = "testStoryArcAddAndDelete"; - StoryArcImpl storyArcImpl = new StoryArcImpl(); - StoryArcEntity storyArc = new StoryArcEntity(); - storyArc.setTitle(storyArcTtitle); - storyArcImpl.store(storyArc); - Collection storyArcEntityCollection = storyArcImpl.findByTitle(storyArcTtitle); - Assert.assertNotNull(storyArcEntityCollection); - Assert.assertEquals(1, storyArcEntityCollection.size()); - storyArcImpl.delete(storyArc); - storyArcEntityCollection = storyArcImpl.findByTitle(storyArcTtitle); - Assert.assertNotNull(storyArcEntityCollection); - Assert.assertEquals(0, storyArcEntityCollection.size()); - } - - @Test - public void testStoryArcFindAll() { - StoryArcImpl storyArcImpl = new StoryArcImpl(); - StoryArcEntity storyArc; - storyArc = new StoryArcEntity(); - storyArc.setTitle("testStoryArcFindAll1"); - storyArcImpl.store(storyArc); - storyArc = new StoryArcEntity(); - storyArc.setTitle("testStoryArcFindAll2"); - storyArcImpl.store(storyArc); - storyArc = new StoryArcEntity(); - storyArc.setTitle("testStoryArcFindAll3"); - storyArcImpl.store(storyArc); - Collection storyArcEntityCollection = storyArcImpl.findAll(); - Assert.assertNotNull(storyArcEntityCollection); - Assert.assertEquals(3, storyArcEntityCollection.size()); - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/VolumeImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/VolumeImplTest.java deleted file mode 100644 index e5c5b3a..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/comics/dal/VolumeImplTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.VolumeEntity; -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; -import java.util.Iterator; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class VolumeImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testVolumeAddAndDelete() { - String volumeTitle = "testVolumeAddAndDelete"; - VolumeImpl volumeImpl = new VolumeImpl(); - VolumeEntity volume = new VolumeEntity(); - volume.setTitle(volumeTitle); - VolumeEntity volumeEntity = volumeImpl.store(volume); - Assert.assertNotNull(volumeEntity); - Assert.assertEquals(volumeTitle, volumeEntity.getTitle()); - Collection volumeList = volumeImpl.findByTitle(volumeTitle); - Assert.assertNotNull(volumeList); - Assert.assertEquals(1, volumeList.size()); - VolumeEntity result = (VolumeEntity)volumeList.toArray()[0]; - Assert.assertEquals(volume, result); - volumeImpl.delete(result); - volumeList = volumeImpl.findByTitle(volumeTitle); - Assert.assertEquals(0, volumeList.size()); - } - - @Test - public void testVolumeFindAll() { - VolumeImpl volumeImpl = new VolumeImpl(); - VolumeEntity volume; - volume = new VolumeEntity(); - volume.setTitle("testVolumeFindAll1"); - volumeImpl.store(volume); - volume = new VolumeEntity(); - volume.setTitle("testVolumeFindAll2"); - volumeImpl.store(volume); - volume = new VolumeEntity(); - volume.setTitle("testVolumeFindAll3"); - volumeImpl.store(volume); - Collection volumeList = volumeImpl.findAll(); - Assert.assertNotNull(volumeList); - Assert.assertEquals(3, volumeList.size()); - for (Iterator iterator = volumeList.iterator(); iterator.hasNext(); ) { - VolumeEntity next = iterator.next(); - volumeImpl.delete(next); - } - volumeList = volumeImpl.findAll(); - Assert.assertNotNull(volumeList); - Assert.assertEquals(0, volumeList.size()); - } - -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/dal/DataAccessLayerTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/dal/DataAccessLayerTest.java deleted file mode 100644 index 6351468..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/dal/DataAccessLayerTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.ibtp.kontor.dal; - -import org.junit.Assert; -import org.junit.Test; - -import java.lang.reflect.Method; - -/** - * Created by TPEETZ on 10.02.2015. - */ -public class DataAccessLayerTest { - - public void findTests(String packageName, String entityName) { - String testClassName = packageName + entityName + "ImplTest"; - Class testClass; - try { - testClass = Class.forName(testClassName); - Method addAndDelete = testClass.getMethod("test" + entityName + "AddAndDelete"); - Method findAll = testClass.getMethod("test" + entityName + "FindAll"); - } catch (ClassNotFoundException e) { - Assert.fail("Class " + testClassName + " missing"); - } catch (NoSuchMethodException e) { - Assert.fail("Test method for class " + testClassName + " missing"); - } - } - - @Test - public void testFindComicTests() { - /* - * Find all Tests - */ - String[] testClasses = new String[]{"Artist", "Comic", "Issue", "Publisher", "StoryArc", "Volume"}; - for (int i = 0; i < testClasses.length; i++) { - String testEntity = testClasses[i]; - findTests("com.ibtp.kontor.comics.dal.", testEntity); - } - } - - @Test - public void testFindLibraryTests() { - /* - * Find all Tests - */ - String[] testClasses = new String[]{"Article", "Author", "Book", "File", "Title"}; - for (int i = 0; i < testClasses.length; i++) { - String testEntity = testClasses[i]; - findTests("com.ibtp.kontor.library.dal.", testEntity); - } - } - - @Test - public void testFindTradingCardsTests() { - /* - * Find all Tests - */ - String[] testClasses = new String[]{"BaseSet", "Insert", "Manufacturer", "ParallelSet", "Player", "Position", "SportCard", "Sport", "Team"}; - for (int i = 0; i < testClasses.length; i++) { - String testEntity = testClasses[i]; - findTests("com.ibtp.kontor.tradingcards.dal." , testEntity); - } - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/BookshelfTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/BookshelfTest.java deleted file mode 100644 index 57f0a84..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/BookshelfTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.library; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Before; -import org.junit.Test; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class BookshelfTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testAddAuthors() { - - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/ArticleImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/ArticleImplTest.java deleted file mode 100644 index 5fa268b..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/ArticleImplTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import com.ibtp.kontor.library.entity.ArticleEntity; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -public class ArticleImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testAddArticle() { - String articleTitle = "testAddArticle"; - ArticleImpl articleImpl = new ArticleImpl(); - ArticleEntity article = articleImpl.addArticle(articleTitle); - Assert.assertNotNull(article); - List articleList = articleImpl.findByTitle(articleTitle); - Assert.assertEquals(1, articleList.size()); - } - - @Test - public void testArticleAddAndDelete() { - - } - - @Test - public void testArticleFindAll() { - - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/AuthorImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/AuthorImplTest.java deleted file mode 100644 index f10caf6..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/AuthorImplTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import com.ibtp.kontor.library.entity.AuthorEntity; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.List; - -/** - * Created by thomas on 23.01.15. - */ -public class AuthorImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testAddAuthor() { - String authorName = "testAddAuthor"; - AuthorImpl authorImpl = new AuthorImpl(); - AuthorEntity author = authorImpl.addAuthor(authorName); - Assert.assertNotNull(author); - } - - @Test - public void testDeleteAuthor() { - String authorName = "testDeleteAuthor"; - AuthorImpl authorImpl = new AuthorImpl(); - AuthorEntity author = authorImpl.addAuthor(authorName); - Assert.assertNotNull(author); - List authorList = authorImpl.findByName(authorName); - Assert.assertEquals(1, authorList.size()); - authorImpl.delete(author); - authorList = authorImpl.findByName(authorName); - Assert.assertEquals(0, authorList.size()); - } - - @Test - public void testAuthorAddAndDelete() { - - } - - @Test - public void testAuthorFindAll() { - - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/BookImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/BookImplTest.java deleted file mode 100644 index ba4c6d4..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/BookImplTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Before; -import org.junit.Test; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class BookImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testBookAddAndDelete() { - - } - - @Test - public void testBookFindAll() { - - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/FileImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/FileImplTest.java deleted file mode 100644 index a0afab6..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/FileImplTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Before; -import org.junit.Test; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class FileImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testFileAddAndDelete() { - - } - - @Test - public void testFileFindAll() { - - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/TitleImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/TitleImplTest.java deleted file mode 100644 index e6f06bd..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/library/dal/TitleImplTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Before; -import org.junit.Test; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class TitleImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testTitleAddAndDelete() { - - } - - @Test - public void testTitleFindAll() { - - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/CollectionTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/CollectionTest.java deleted file mode 100644 index d307051..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/CollectionTest.java +++ /dev/null @@ -1,167 +0,0 @@ -package com.ibtp.kontor.tradingcards; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.tradingcards.dal.TeamImpl; -import com.ibtp.kontor.tradingcards.entity.TeamEntity; -import com.ibtp.kontor.util.LocalTestDatabase; -import com.ibtp.kontor.tradingcards.dal.SportImpl; -import com.ibtp.kontor.tradingcards.entity.SportEntity; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; -import java.util.Iterator; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class CollectionTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - setupSports(); - } - - public void setupSports() { - SportImpl sportImpl = new SportImpl(); - SportEntity football = sportImpl.addSport("Football"); - setupFootballTeams(football); - SportEntity baseball = sportImpl.addSport("Baseball"); - setupFootballTeams(baseball); - SportEntity basketball = sportImpl.addSport("Basketball"); - setupBasketballTeams(basketball); - SportEntity hockey = sportImpl.addSport("Hockey"); - setupHockeyTeams(hockey); - } - - public void setupFootballTeams(SportEntity football) { - TeamImpl teamImpl = new TeamImpl(); - teamImpl.addTeam("Dallas Cowboys", football); - teamImpl.addTeam("New York Giants", football); - teamImpl.addTeam("Philadelphia Eagles", football); - teamImpl.addTeam("Arizona Cardinals", football); - teamImpl.addTeam("Washington Redskins", football); - teamImpl.addTeam("Detroit Lions", football); - teamImpl.addTeam("Minnesota Vikings", football); - teamImpl.addTeam("Green Bay Packers", football); - teamImpl.addTeam("Chicago Bears", football); - teamImpl.addTeam("Tampa Bay Buccaneers", football); - teamImpl.addTeam("San Francisco 49ers", football); - teamImpl.addTeam("New Orleans Saints", football); - teamImpl.addTeam("Atlanta Falcons", football); - teamImpl.addTeam("Los Angeles Rams", football); - teamImpl.addTeam("Buffalo Bills", football); - teamImpl.addTeam("Miami Dolphins", football); - teamImpl.addTeam("New York Jets", football); - teamImpl.addTeam("New England Patriots", football); - teamImpl.addTeam("Indianapolis Colts", football); - teamImpl.addTeam("Houston Oilers", football); - teamImpl.addTeam("Pittsburgh Steelers", football); - teamImpl.addTeam("Cleveland Browns", football); - teamImpl.addTeam("Kansas City Chiefs", football); - teamImpl.addTeam("Los Angeles Raiders", football); - teamImpl.addTeam("Denver Broncos", football); - teamImpl.addTeam("San Diego Chargers", football); - teamImpl.addTeam("Seattle Seahawks", football); - teamImpl.addTeam("Jacksonville Jaguars", football); - teamImpl.addTeam("Houston Texans", football); - } - - public void setupBaseballTeams(SportEntity baseball) { - TeamImpl teamImpl = new TeamImpl(); - } - - public void setupBasketballTeams(SportEntity basketball) { - TeamImpl teamImpl = new TeamImpl(); - teamImpl.addTeam("Houston Rockets", basketball); - teamImpl.addTeam("San Antonio Spurs", basketball); - teamImpl.addTeam("Utah Jazz", basketball); - teamImpl.addTeam("Denver Nuggets", basketball); - teamImpl.addTeam("Minnesota Timberwolves", basketball); - teamImpl.addTeam("Dallas Mavericks", basketball); - teamImpl.addTeam("Seattle SuperSonics", basketball); - teamImpl.addTeam("Phoenix Suns", basketball); - teamImpl.addTeam("Golden State Warriors", basketball); - teamImpl.addTeam("Portland Trail Blazers", basketball); - teamImpl.addTeam("Los Angeles Lakers", basketball); - teamImpl.addTeam("Sacramento Kings", basketball); - teamImpl.addTeam("Los Angeles Clippers", basketball); - teamImpl.addTeam("New York Knicks", basketball); - teamImpl.addTeam("Orlando Magic", basketball); - teamImpl.addTeam("New Jersey Nets", basketball); - teamImpl.addTeam("Miami Heat", basketball); - teamImpl.addTeam("Boston Celtics", basketball); - teamImpl.addTeam("Philadelphia 76ers", basketball); - teamImpl.addTeam("Washington Bullets", basketball); - teamImpl.addTeam("Atlanta Hawks", basketball); - teamImpl.addTeam("Chicago Bulls", basketball); - teamImpl.addTeam("Indiana Pacers", basketball); - teamImpl.addTeam("Cleveland Cavaliers", basketball); - teamImpl.addTeam("Charlotte Hornets", basketball); - teamImpl.addTeam("Detroit Pistons", basketball); - teamImpl.addTeam("Milwaukee Bucks", basketball); - } - - public void setupHockeyTeams(SportEntity hockey) { - TeamImpl teamImpl = new TeamImpl(); - teamImpl.addTeam("New York Rangers", hockey); - teamImpl.addTeam("Buffalo Sabers", hockey); - teamImpl.addTeam("Detroit Red Wings", hockey); - teamImpl.addTeam("Vancouver Canucks", hockey); - teamImpl.addTeam("Mighty Ducks of Anaheim", hockey); - teamImpl.addTeam("Calgary Flames", hockey); - teamImpl.addTeam("Edmonton Oilers", hockey); - teamImpl.addTeam("Los Angeles Kings", hockey); - teamImpl.addTeam("San Jose Sharks", hockey); - teamImpl.addTeam("Chicago Blackhawks", hockey); - teamImpl.addTeam("Dallas Stars", hockey); - teamImpl.addTeam("St. Louis Blues", hockey); - teamImpl.addTeam("Toronto Maple Leafs", hockey); - teamImpl.addTeam("Winnipeg Jets", hockey); - teamImpl.addTeam("Boston Bruins", hockey); - teamImpl.addTeam("Hartford Whalers", hockey); - teamImpl.addTeam("Montreal Canadiers", hockey); - teamImpl.addTeam("Ottawa Senators", hockey); - teamImpl.addTeam("Pittsburgh Penguins", hockey); - teamImpl.addTeam("Quebec Nordiques", hockey); - teamImpl.addTeam("Florida Panthers", hockey); - teamImpl.addTeam("New Jersey Devils", hockey); - teamImpl.addTeam("New York Islanders", hockey); - teamImpl.addTeam("Philadelphia Flyers", hockey); - teamImpl.addTeam("Tamba Bay Lightning", hockey); - teamImpl.addTeam("Washington Capitals", hockey); - } - - @After - public void tearDown() { - TeamImpl teamImpl = new TeamImpl(); - Collection teamEntities = teamImpl.findAll(); - for (Iterator iterator = teamEntities.iterator(); iterator.hasNext(); ) { - TeamEntity next = iterator.next(); - teamImpl.delete(next); - } - SportImpl sportImpl = new SportImpl(); - Collection sportEntities = sportImpl.findAll(); - for (Iterator iterator = sportEntities.iterator(); iterator.hasNext(); ) { - SportEntity next = iterator.next(); - sportImpl.delete(next); - } - } - - @Test - public void gettAllSports() { - SportImpl sportImpl = new SportImpl(); - Collection resultList = sportImpl.findAll(); - Assert.assertEquals(4, resultList.size()); - } - - @Test - public void getAllTeams() { - TeamImpl teamImpl = new TeamImpl(); - Collection resultList = teamImpl.findAll(); - Assert.assertEquals(111, resultList.size()); - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/BaseSetImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/BaseSetImplTest.java deleted file mode 100644 index 00785cc..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/BaseSetImplTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Before; -import org.junit.Test; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class BaseSetImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testBaseSetAddAndDelete() { - - } - - @Test - public void testBaseSetFindAll() { - - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/InsertImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/InsertImplTest.java deleted file mode 100644 index c7fe97a..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/InsertImplTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Before; -import org.junit.Test; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class InsertImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - - @Test - public void testInsertAddAndDelete() { - - } - - @Test - public void testInsertFindAll() { - - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/ManufacturerImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/ManufacturerImplTest.java deleted file mode 100644 index 972aa84..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/ManufacturerImplTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import com.ibtp.kontor.tradingcards.entity.ManufacturerEntity; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.List; - -/** - * Created by tpeetz on 20.01.2015. - */ -public class ManufacturerImplTest { - - @Before - public void setup() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void addManufacturer() { - String manufacturerName = "Manufacturer1"; - ManufacturerImpl manufacturerImpl = new ManufacturerImpl(); - ManufacturerEntity manufacturer = manufacturerImpl.addManufacturer(manufacturerName); - Assert.assertNotNull(manufacturer); - List manufacturerList = manufacturerImpl.findByName(manufacturerName); - Assert.assertTrue(manufacturerList.size() > 0); - } - - @Test - public void deleteManufacturer() { - String manufacturerName = "Manufacturer1"; - ManufacturerImpl manufacturerImpl = new ManufacturerImpl(); - List manufacturerList = manufacturerImpl.findByName(manufacturerName); - Assert.assertTrue(manufacturerList.size() > 0); - manufacturerImpl.delete(manufacturerList.get(0)); - manufacturerList = manufacturerImpl.findByName(manufacturerName); - Assert.assertEquals(0, manufacturerList.size()); - } - - @Test - public void testManufacturerAddAndDelete() { - - } - - @Test - public void testManufacturerFindAll() { - - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/ParallelSetImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/ParallelSetImplTest.java deleted file mode 100644 index 19cc143..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/ParallelSetImplTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Before; -import org.junit.Test; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class ParallelSetImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testParallelSetAddAndDelete() { - - } - - @Test - public void testParallelSetFindAll() { - - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/PlayerImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/PlayerImplTest.java deleted file mode 100644 index 6aca0db..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/PlayerImplTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Before; -import org.junit.Test; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class PlayerImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testPlayerAddAndDelete() { - - } - - @Test - public void testPlayerFindAll() { - - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/PositionImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/PositionImplTest.java deleted file mode 100644 index 3d2019b..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/PositionImplTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import com.ibtp.kontor.tradingcards.entity.PositionEntity; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class PositionImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testPositionAddAndDelete() { - String positionName = "testPositionAddAndDelete"; - PositionImpl positionImpl = new PositionImpl(); - PositionEntity position = positionImpl.addPosition(positionName); - Collection resultList = positionImpl.findByName(positionName); - Assert.assertNotNull(resultList); - Assert.assertEquals(1, resultList.size()); - positionImpl.delete(position); - resultList = positionImpl.findByName(positionName); - Assert.assertEquals(0, resultList.size()); - } - - @Test - public void testPositionFindAll() { - PositionImpl positionImpl = new PositionImpl(); - Collection resultList = positionImpl.findAll(); - Assert.assertEquals(0, resultList.size()); - } -} - diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/SportCardImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/SportCardImplTest.java deleted file mode 100644 index 4e9d190..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/SportCardImplTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.Before; -import org.junit.Test; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class SportCardImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testSportCardAddAndDelete() { - - } - - @Test - public void testSportCardFindAll() { - - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/SportImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/SportImplTest.java deleted file mode 100644 index f8053c5..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/SportImplTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import com.ibtp.kontor.tradingcards.entity.SportEntity; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -public class SportImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testSportAddAndDelete() { - String sportName = "testSportAddAndDelete"; - SportImpl sportImpl = new SportImpl(); - SportEntity sport = sportImpl.addSport(sportName); - List sportList = sportImpl.findByName(sportName); - Assert.assertEquals(1, sportList.size()); - sportImpl.delete(sport); - List result = sportImpl.findByName(sportName); - Assert.assertEquals(0, result.size()); - } - - @Test - public void testSportFindAll() { - SportImpl sportImpl = new SportImpl(); - Collection resultList = sportImpl.findAll(); - Assert.assertEquals(0, resultList.size()); - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/TeamImplTest.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/TeamImplTest.java deleted file mode 100644 index 1cfec7b..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/tradingcards/dal/TeamImplTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import com.ibtp.kontor.tradingcards.entity.TeamEntity; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collection; - -/** - * Created by tpeetz on 20.01.2015. - */ -public class TeamImplTest { - - @Before - public void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testTeamAddAndDelete() { - String teamName = "testTeamAddAndDelete"; - TeamEntity team = new TeamEntity(teamName); - TeamImpl teamImpl = new TeamImpl(); - teamImpl.store(team); - Collection resultList = teamImpl.findByName(teamName); - Assert.assertEquals(1, resultList.size()); - teamImpl.delete(team); - resultList = teamImpl.findByName(teamName); - Assert.assertEquals(0, resultList.size()); - } - - @Test - public void testTeamFindAll() { - TeamImpl teamImpl = new TeamImpl(); - Collection resultList = teamImpl.findAll(); - Assert.assertEquals(0, resultList.size()); - } -} diff --git a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/util/LocalTestDatabase.java b/java-ee/KontorApp/src/test/java/com/ibtp/kontor/util/LocalTestDatabase.java deleted file mode 100644 index 503104a..0000000 --- a/java-ee/KontorApp/src/test/java/com/ibtp/kontor/util/LocalTestDatabase.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.ibtp.kontor.util; - -import com.ibtp.kontor.dal.Database; -import org.hibernate.jpa.HibernatePersistenceProvider; -import org.hsqldb.Server; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import javax.persistence.spi.PersistenceProvider; -import javax.persistence.spi.PersistenceProviderResolver; -import javax.persistence.spi.PersistenceProviderResolverHolder; -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Created by TPEETZ on 21.01.2015. - */ -public class LocalTestDatabase implements Database { - - private static Server server; - private static EntityManagerFactory factory; - private static EntityManager em; - private static Logger logger = LoggerFactory.getLogger(LocalTestDatabase.class.getName()); - - static { - logger.info("initialization and starting database"); - LocalTestDatabase.assureDatabaseRunning(); - } - - public LocalTestDatabase() { - logger.info("LocalDatabaseTest started"); - } - - private static void assureDatabaseRunning() { - if (LocalTestDatabase.server == null) { - LocalTestDatabase.startDatabase(); - } - } - - private static void startDatabase() { - logger.info("startDatabase as kontor in hsqldb_databases/test"); - LocalTestDatabase.server = new Server(); - LocalTestDatabase.server.setAddress("localhost"); - LocalTestDatabase.server.setDatabaseName(0, "kontor"); - LocalTestDatabase.server.setDatabasePath(0, "file:build/hsqldb_databases/test"); - LocalTestDatabase.server.setPort(2345); - LocalTestDatabase.server.setTrace(true); - LocalTestDatabase.server.setLogWriter(new PrintWriter(System.out)); - LocalTestDatabase.server.start(); - } - - private static void stopDatabase() { - server.shutdown(); - } - - private static EntityManagerFactory getFactory() { - if (LocalTestDatabase.factory == null) { - LocalTestDatabase.assureDatabaseRunning(); - PersistenceProviderResolverHolder.setPersistenceProviderResolver(new PersistenceProviderResolver() { - private final List providers_ = Arrays.asList((PersistenceProvider) new HibernatePersistenceProvider()); - - @Override - public void clearCachedProviders() { - // Auto-generated method stub - } - - @Override - public List getPersistenceProviders() { - return providers_; - } - }); - LocalTestDatabase.factory = Persistence.createEntityManagerFactory("com.ibtp.kontor"); - logger.info("EntityManagerFactory(com.ibtp.kontor) created"); - } - return factory; - } - - private static EntityManager getSingleEntityManager() { - return LocalTestDatabase.em; - } - - private static void setSingleEntityManager(EntityManager manager) { - LocalTestDatabase.em = manager; - } - - @Override - public EntityManager getEntityManager() { - if (getSingleEntityManager() == null) { - setSingleEntityManager(getFactory().createEntityManager()); - logger.info("EntityManager created"); - } - return getSingleEntityManager(); - } - - @Override - public String toString() { - String serverMessage; - if (LocalTestDatabase.server == null) { - serverMessage = "server:null"; - } else { - serverMessage = LocalTestDatabase.server.toString(); - } - return LocalTestDatabase.class.getName() + " " + serverMessage; - } -} diff --git a/java-ee/KontorApp/src/test/resources/META-INF/persistence.xml b/java-ee/KontorApp/src/test/resources/META-INF/persistence.xml deleted file mode 100644 index 35d671b..0000000 --- a/java-ee/KontorApp/src/test/resources/META-INF/persistence.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - org.hibernate.jpa.HibernatePersistenceProvider - com.ibtp.kontor.comics.entity.ArtistEntity - com.ibtp.kontor.comics.entity.ComicEntity - com.ibtp.kontor.comics.entity.IssueEntity - com.ibtp.kontor.comics.entity.StoryArcEntity - com.ibtp.kontor.comics.entity.VolumeEntity - com.ibtp.kontor.comics.entity.PublisherEntity - com.ibtp.kontor.library.entity.AuthorEntity - com.ibtp.kontor.library.entity.ArticleEntity - com.ibtp.kontor.library.entity.BookEntity - com.ibtp.kontor.library.entity.FileEntity - com.ibtp.kontor.library.entity.TitleEntity - com.ibtp.kontor.tradingcards.entity.SportEntity - com.ibtp.kontor.tradingcards.entity.TeamEntity - com.ibtp.kontor.tradingcards.entity.PositionEntity - com.ibtp.kontor.tradingcards.entity.PlayerEntity - com.ibtp.kontor.tradingcards.entity.ManufacturerEntity - com.ibtp.kontor.tradingcards.entity.BaseSetEntity - com.ibtp.kontor.tradingcards.entity.InsertEntity - com.ibtp.kontor.tradingcards.entity.ParallelSetEntity - com.ibtp.kontor.tradingcards.entity.SportCardEntity - - - - - - - - - - - - - diff --git a/java-ee/KontorApp/src/test/resources/logback.xml b/java-ee/KontorApp/src/test/resources/logback.xml deleted file mode 100644 index 5254e50..0000000 --- a/java-ee/KontorApp/src/test/resources/logback.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - %d{yyyy-MM-dd_HH:mm:ss.SSS} %-5level %logger{36} - %msg%n - - - - - - build/kontortest.log - - %d{yyyy-MM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - build/kontortest.%i.log.zip - 1 - 10 - - - - 2MB - - - - - - - - - - - - - - diff --git a/java-ee/KontorEJB/build.gradle b/java-ee/KontorEJB/build.gradle deleted file mode 100755 index 5f1dfc0..0000000 --- a/java-ee/KontorEJB/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'java' - -dependencies { - compile 'javax.enterprise:cdi-api:+' - compile 'org.jboss.spec.javax.faces:jboss-jsf-api_2.2_spec:+' - compile 'org.jboss.spec.javax.ejb:jboss-ejb-api_3.2_spec:+' - compile 'org.jboss.spec.javax.annotation:jboss-annotations-api_1.2_spec:+' - compile 'org.hibernate.ogm:hibernate-ogm-mongodb:+' - compile 'org.eclipse.persistence:javax.persistence:2.1.0' - compile 'ch.qos.logback:logback-core:1.1.2' - compile 'ch.qos.logback:logback-classic:1.1.2' -} diff --git a/java-ee/KontorEJB/src/main/java/com/ibtp/kontor/ejb/Controller.java b/java-ee/KontorEJB/src/main/java/com/ibtp/kontor/ejb/Controller.java deleted file mode 100755 index 67b84ce..0000000 --- a/java-ee/KontorEJB/src/main/java/com/ibtp/kontor/ejb/Controller.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.ibtp.kontor.ejb; - -import com.ibtp.kontor.ejb.PropertyManager; -import com.ibtp.kontor.ejb.Property; - -import java.util.List; -import javax.annotation.PostConstruct; -import javax.enterprise.inject.Model; - -import javax.inject.Inject; - -@Model -public class Controller { - - List propertyList; - - private String key; - private String value; - - @PostConstruct - public void readDB() { - propertyList = ejb.queryCache(); - - } - @Inject - PropertyManager ejb; - - public void save() { - Property p = new Property(); - p.setKey(key); - p.setValue(value); - ejb.save(p); - propertyList.add(p); - key = ""; - value = ""; - } - - public List getPropertyList() { - return propertyList; - } - - public void setPropertyList(List propertyList) { - this.propertyList = propertyList; - } - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - -} \ No newline at end of file diff --git a/java-ee/KontorEJB/src/main/java/com/ibtp/kontor/ejb/Property.java b/java-ee/KontorEJB/src/main/java/com/ibtp/kontor/ejb/Property.java deleted file mode 100755 index d2fab7b..0000000 --- a/java-ee/KontorEJB/src/main/java/com/ibtp/kontor/ejb/Property.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.ibtp.kontor.ejb; - - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import org.hibernate.annotations.GenericGenerator; - -@Entity -public class Property { - - @Id - @GeneratedValue(generator = "uuid") - @GenericGenerator(name = "uuid", strategy = "uuid2") - private String id; - - private String key; - - private String value; - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - -} \ No newline at end of file diff --git a/java-ee/KontorEJB/src/main/java/com/ibtp/kontor/ejb/PropertyManager.java b/java-ee/KontorEJB/src/main/java/com/ibtp/kontor/ejb/PropertyManager.java deleted file mode 100755 index 865a0bd..0000000 --- a/java-ee/KontorEJB/src/main/java/com/ibtp/kontor/ejb/PropertyManager.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ibtp.kontor.ejb; - -import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -import com.ibtp.kontor.ejb.Property; -import javax.ejb.Stateless; - -@Stateless - public class PropertyManager { - - @PersistenceContext(unitName = "mongo-ogm") - private EntityManager em; - - public void save(Property p) { - em.persist(p); - } - - public List queryCache() { - Query query = em.createQuery("FROM Property p"); - - List list = query.getResultList(); - return list; - } -} \ No newline at end of file diff --git a/java-ee/KontorImpl/build.gradle b/java-ee/KontorImpl/build.gradle deleted file mode 100644 index b1512a8..0000000 --- a/java-ee/KontorImpl/build.gradle +++ /dev/null @@ -1,5 +0,0 @@ -jar { - manifest { - attributes 'Implementation-Title': 'Kontor', 'Implementation-Version': version - } -} diff --git a/java-ee/KontorImpl/config/checkstyle/checkstyle.xml b/java-ee/KontorImpl/config/checkstyle/checkstyle.xml deleted file mode 100644 index 7c682c3..0000000 --- a/java-ee/KontorImpl/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java-ee/KontorImpl/config/checkstyle/checkstyle.xsl b/java-ee/KontorImpl/config/checkstyle/checkstyle.xsl deleted file mode 100644 index 393a01b..0000000 --- a/java-ee/KontorImpl/config/checkstyle/checkstyle.xsl +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -

CheckStyle Audit

Designed for use with CheckStyle and Ant.
-
- - - -
- - - -
- - - - - -

-

- -


- - - - -
- - - - -

Files

- - - - - - - - - - - - - - -
NameErrors
-
- - - - -

File

- - - - - - - - - - - - - -
Error DescriptionLine
- Back to top -
- - - -

Summary

- - - - - - - - - - - - -
FilesErrors
-
- - - - a - b - - -
- - diff --git a/java-ee/KontorImpl/config/findbugs/findbugs.xml b/java-ee/KontorImpl/config/findbugs/findbugs.xml deleted file mode 100644 index 34a6e01..0000000 --- a/java-ee/KontorImpl/config/findbugs/findbugs.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/java-ee/KontorImpl/src/main/java/com/peetz/kontor/dal/KontorUserDao.java b/java-ee/KontorImpl/src/main/java/com/peetz/kontor/dal/KontorUserDao.java deleted file mode 100644 index f2c37f6..0000000 --- a/java-ee/KontorImpl/src/main/java/com/peetz/kontor/dal/KontorUserDao.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.peetz.kontor.dal; - -import java.util.List; - -import javax.ejb.Local; - -import com.peetz.kontor.entity.KontorUserEntity; - -@Local -public interface KontorUserDao { - public KontorUserEntity getById(Long id); - public List findByIds(List ids); - public KontorUserEntity findByLogin(String login); - public KontorUserEntity store(KontorUserEntity entity); - public void delete(KontorUserEntity entity); -} diff --git a/java-ee/KontorImpl/src/main/java/com/peetz/kontor/dal/KontorUserImpl.java b/java-ee/KontorImpl/src/main/java/com/peetz/kontor/dal/KontorUserImpl.java deleted file mode 100644 index 3dee67f..0000000 --- a/java-ee/KontorImpl/src/main/java/com/peetz/kontor/dal/KontorUserImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.peetz.kontor.dal; - -import java.util.List; - -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -import com.peetz.kontor.entity.KontorUserEntity; - -@Stateless(name = "ComicDao") -@TransactionAttribute(TransactionAttributeType.REQUIRED) -public class KontorUserImpl implements KontorUserDao { - - @PersistenceContext - private EntityManager em; - - @Override - public KontorUserEntity getById(Long id) { - Query q = em.createNamedQuery("findById"); - q.setParameter("id", id); - KontorUserEntity entity = (KontorUserEntity)q.getSingleResult(); - return entity; - } - - @Override - public List findByIds(List ids) { - // TODO Auto-generated method stub - return null; - } - - @Override - public KontorUserEntity findByLogin(String login) { - Query q = em.createNamedQuery("findByLogin"); - q.setParameter("login", login); - KontorUserEntity entity = (KontorUserEntity)q.getSingleResult(); - return entity; - } - - @Override - public KontorUserEntity store(KontorUserEntity entity) { - em.persist(entity); - return entity; - } - - @Override - public void delete(KontorUserEntity entity) { - em.remove(entity); - } -} diff --git a/java-ee/KontorImpl/src/main/java/com/peetz/kontor/entity/KontorUserEntity.java b/java-ee/KontorImpl/src/main/java/com/peetz/kontor/entity/KontorUserEntity.java deleted file mode 100644 index 5b8a0b5..0000000 --- a/java-ee/KontorImpl/src/main/java/com/peetz/kontor/entity/KontorUserEntity.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.peetz.kontor.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="findAll", query="SELECT u from KontorUser as u"), - @NamedQuery(name="findById", query="SELECT u from KontorUser as u WHERE u.id = :id"), - @NamedQuery(name="findByLogin", query="SELECT u from KontorUser as u WHERE u.login = :login") -}) - -@Entity -@Table(name="KONTORUSER") -public class KontorUserEntity { - private Long id; - - private String login; - - private String password; - - private String name; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getLogin() { - return login; - } - - public void setLogin(String login) { - this.login = login; - } - - @Column - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } -} diff --git a/java-ee/KontorImpl/src/main/java/com/peetz/kontor/service/package-info.java b/java-ee/KontorImpl/src/main/java/com/peetz/kontor/service/package-info.java deleted file mode 100644 index e64dc61..0000000 --- a/java-ee/KontorImpl/src/main/java/com/peetz/kontor/service/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * - */ -/** - * @author TPEETZ - * - */ -package com.peetz.kontor.service; \ No newline at end of file diff --git a/java-ee/KontorWeb/build.gradle b/java-ee/KontorWeb/build.gradle deleted file mode 100755 index e6eb2e0..0000000 --- a/java-ee/KontorWeb/build.gradle +++ /dev/null @@ -1,11 +0,0 @@ -apply plugin: 'war' - -version = '0.0.1' - -dependencies { - compile project(':KontorEJB') - compile project(':ComicsWeb') - compile project(':MedienWeb') - compile project(':LibraryWeb') - compile project(':TradingCardsWeb') -} diff --git a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ExportComics.java b/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ExportComics.java deleted file mode 100644 index 180eeda..0000000 --- a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ExportComics.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.peetz.kontor.data; - -import java.util.Collection; -import java.util.Iterator; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import com.peetz.comics.entity.ArtistEntity; -import com.peetz.comics.entity.ComicEntity; -import com.peetz.comics.entity.IssueEntity; -import com.peetz.comics.entity.PublisherEntity; -import com.peetz.comics.entity.StoryArcEntity; -import com.peetz.comics.service.ComicService; - -public class ExportComics -{ - public Element backupComics(Document document) - { - Element comics = document.createElement("comics"); - ComicService comicService = getComicService(); - if (comicService == null) return comics; - - Collection publishers = comicService.getAllPublisher(); - Iterator publisher_iterator = publishers.iterator(); - while (publisher_iterator.hasNext()) { - PublisherEntity publisher = publisher_iterator.next(); - Element publisherNode = document.createElement("publisher"); - publisherNode.setAttribute("id", publisher.getId().toString()); - publisherNode.setAttribute("name", publisher.getName()); - comics.appendChild(publisherNode); - comics.appendChild(document.createTextNode("\n")); - } - Collection artists = comicService.getAllArtists(); - Iterator artist_iterator = artists.iterator(); - while(artist_iterator.hasNext()) { - ArtistEntity artist = artist_iterator.next(); - Element artistNode = document.createElement("artist"); - artistNode.setAttribute("id", artist.getId().toString()); - artistNode.setAttribute("name", artist.getName()); - comics.appendChild(artistNode); - comics.appendChild(document.createTextNode("\n")); - } - Collection comicList = comicService.getAllComics(); - Iterator comics_iterator = comicList.iterator(); - while(comics_iterator.hasNext()) { - ComicEntity comic = comics_iterator.next(); - Element comicNode = document.createElement("comic"); - comicNode.setAttribute("id", comic.getId().toString()); - comicNode.setAttribute("title", comic.getTitle()); - String completed = "false"; - if (comic.getCompleted() != null) completed = comic.getCompleted().toString(); - comicNode.setAttribute("complete", completed); - String currentOrder = "false"; - if (comic.getCurrentOrder() != null) currentOrder = comic.getCurrentOrder().toString(); - comicNode.setAttribute("order", currentOrder); - Collection issues = comicService.getAllIssuesForComic(comic); - Iterator issues_iterator = issues.iterator(); - comicNode.appendChild(document.createTextNode("\n")); - while(issues_iterator.hasNext()) { - IssueEntity issue = issues_iterator.next(); - Element issueNode = document.createElement("issue"); - issueNode.setAttribute("id", issue.getId().toString()); - issueNode.setAttribute("number", issue.getNumber()); - comicNode.appendChild(issueNode); - comicNode.appendChild(document.createTextNode("\n")); - } - comics.appendChild(comicNode); - comics.appendChild(document.createTextNode("\n")); - } - Collection storyArcs = comicService.getAllStoryArcs(); - Iterator iterator_storyArcsIterator = storyArcs.iterator(); - while(iterator_storyArcsIterator.hasNext()) { - StoryArcEntity storyArc = iterator_storyArcsIterator.next(); - Element storyNode = document.createElement("storyArc"); - storyNode.setAttribute("id", storyArc.getId().toString()); - storyNode.setAttribute("title", storyArc.getTitle()); - comics.appendChild(storyNode); - comics.appendChild(document.createTextNode("\n")); - } - return comics; - } - - private ComicService getComicService() - { - return null; - } -} diff --git a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ExportLibrary.java b/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ExportLibrary.java deleted file mode 100644 index 1c17da9..0000000 --- a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ExportLibrary.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.peetz.kontor.data; - -import java.util.Collection; -import java.util.Iterator; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import com.peetz.library.entity.ArticleEntity; -import com.peetz.library.entity.BookEntity; -import com.peetz.library.entity.BookshelfEntity; -import com.peetz.library.entity.ShelfboardEntity; -import com.peetz.library.service.LibraryService; - -public class ExportLibrary -{ - public Element backupLibrary(Document document) - { - Element library = document.createElement("library"); - library.appendChild(document.createTextNode("\n")); - LibraryService libraryService = getLibraryService(); - - Collection books = libraryService.getAllBooks(); - Iterator iterator_books = books.iterator(); - while(iterator_books.hasNext()) { - BookEntity book = iterator_books.next(); - Element bookNode = document.createElement("book"); - bookNode.setAttribute("id", book.getId().toString()); - bookNode.setAttribute("title", book.getTitle()); - bookNode.setAttribute("author", book.getAuthor()); - bookNode.setAttribute("edition", book.getEdition()); - bookNode.setAttribute("isbn", book.getIsbn()); - bookNode.setAttribute("pages", book.getPage().toString()); - bookNode.setAttribute("publisher", book.getPublisher()); - library.appendChild(bookNode); - library.appendChild(document.createTextNode("\n")); - } - - Collection bookshelfs = libraryService.getAllBookshelfs(); - Iterator iterator_bookshelfs = bookshelfs.iterator(); - while(iterator_bookshelfs.hasNext()) { - BookshelfEntity bookshelf = iterator_bookshelfs.next(); - Element shelfNode = document.createElement("shelf"); - shelfNode.setAttribute("id", bookshelf.getId().toString()); - shelfNode.setAttribute("title", bookshelf.getTitle()); - - shelfNode.appendChild(document.createTextNode("\n")); - Collection shelfboards = bookshelf.getShelfBoards(); - Iterator iterator_shelfboards = shelfboards.iterator(); - while(iterator_shelfboards.hasNext()) { - ShelfboardEntity shelfboard = iterator_shelfboards.next(); - Element boardNode = document.createElement("board"); - boardNode.setAttribute("id", shelfboard.getId().toString()); - boardNode.setAttribute("title", shelfboard.getTitle()); - shelfNode.appendChild(boardNode); - shelfNode.appendChild(document.createTextNode("\n")); - } - library.appendChild(shelfNode); - library.appendChild(document.createTextNode("\n")); - } - - Collection articles = libraryService.getAllArticles(); - Iterator iterator_articles = articles.iterator(); - while(iterator_articles.hasNext()) { - ArticleEntity article = iterator_articles.next(); - Element articleNode = document.createElement("article"); - articleNode.setAttribute("id", article.getId().toString()); - articleNode.setAttribute("title", article.getTitle()); - - Collection origins = article.getOriginArticles(); - Iterator iterator_origins = origins.iterator(); - while(iterator_origins.hasNext()) { - ArticleEntity origin = iterator_origins.next(); - Element originNode = document.createElement("article"); - originNode.setAttribute("id", origin.getId().toString()); - articleNode.appendChild(originNode); - articleNode.appendChild(document.createTextNode("\n")); - } - - Collection relateds = article.getRelatedArticles(); - Iterator iterator_relateds = relateds.iterator(); - articleNode.appendChild(document.createTextNode("\n")); - while(iterator_relateds.hasNext()) { - ArticleEntity related = iterator_relateds.next(); - Element relatedNode = document.createElement("article"); - relatedNode.setAttribute("id", related.getId().toString()); - articleNode.appendChild(relatedNode); - articleNode.appendChild(document.createTextNode("\n")); - } - library.appendChild(articleNode); - library.appendChild(document.createTextNode("\n")); - } - return library; - } - - private LibraryService getLibraryService() - { - return null; - } -} diff --git a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ExportMedien.java b/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ExportMedien.java deleted file mode 100644 index 48d0ee4..0000000 --- a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ExportMedien.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.peetz.kontor.data; - -import java.util.Collection; -import java.util.Iterator; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import com.peetz.medien.entity.AudioCDEntity; -import com.peetz.medien.entity.BoxSetEntity; -import com.peetz.medien.entity.FilmEntity; -import com.peetz.medien.service.MedienService; - -public class ExportMedien -{ - public Element backupMedien(Document document) - { - Element medien = document.createElement("medien"); - medien.appendChild(document.createTextNode("\n")); - - MedienService medienService = getMedienService(); - - Collection cds = medienService.getAllCDs(); - Iterator iterator_cds = cds.iterator(); - while(iterator_cds.hasNext()) { - AudioCDEntity cd = iterator_cds.next(); - Element cdNode = document.createElement("audioCD"); - //cdNode.setAttribute("id", cd.getId()); - //cdNode.setAttribute("album", cd.getAlbum()); - //cdNode.setAttribute("artist", cd.getArtist()); - medien.appendChild(cdNode); - medien.appendChild(document.createTextNode("\n")); - } - - Collection films = medienService.getAllDVDs(); - Iterator iterator_films = films.iterator(); - while(iterator_films.hasNext()) { - FilmEntity film = iterator_films.next(); - Element filmNode = document.createElement("film"); - //filmNode.setAttribute("id", film.getId()); - //filmNode.setAttribute("title", film.getTitle()); - medien.appendChild(filmNode); - medien.appendChild(document.createTextNode("\n")); - } - - Collection boxsets = medienService.getAllBoxSets(); - Iterator iterator_boxsets = boxsets.iterator(); - while(iterator_boxsets.hasNext()) { - BoxSetEntity boxSet = iterator_boxsets.next(); - Element boxNode = document.createElement("boxSet"); - boxNode.setAttribute("id", boxSet.getId().toString()); - boxNode.setAttribute("title", boxSet.getTitle()); - films = boxSet.getFilms(); - iterator_films = films.iterator(); - if (iterator_films.hasNext()) { - boxNode.appendChild(document.createTextNode("\n")); - } - while(iterator_films.hasNext()) { - FilmEntity film = iterator_films.next(); - Element filmNode = document.createElement("film"); - //filmNode.setAttribute("id", film.getId()); - boxNode.appendChild(filmNode); - boxNode.appendChild(document.createTextNode("\n")); - } - medien.appendChild(boxNode); - medien.appendChild(document.createTextNode("\n")); - } - return medien; - } - - private MedienService getMedienService() - { - return null; - } -} diff --git a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ExportTradingCards.java b/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ExportTradingCards.java deleted file mode 100644 index f17e424..0000000 --- a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ExportTradingCards.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.peetz.kontor.data; - -import java.util.Collection; -import java.util.Iterator; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import com.peetz.tradingcards.entity.BaseSetEntity; -import com.peetz.tradingcards.entity.InsertEntity; -import com.peetz.tradingcards.entity.ManufacturerEntity; -import com.peetz.tradingcards.entity.ParallelSetEntity; -import com.peetz.tradingcards.entity.PositionEntity; -import com.peetz.tradingcards.entity.SportCardEntity; -import com.peetz.tradingcards.entity.SportEntity; -import com.peetz.tradingcards.entity.TeamEntity; -import com.peetz.tradingcards.service.SportService; -import com.peetz.tradingcards.service.TradingcardService; - -public class ExportTradingCards -{ - public Element backupTradingCards(Document document) - { - Element tradingcards = document.createElement("tradingcards"); - tradingcards.appendChild(document.createTextNode("\n")); - - SportService sportService = getSportService(); - backupSports(sportService, document, tradingcards); - - backupCards(document, tradingcards); - - return tradingcards; - } - - private void backupSports(SportService sportService, Document document, Element tradingcards) - { - Collection sports = sportService.getAllSports(); - Iterator iterator_sports = sports.iterator(); - while(iterator_sports.hasNext()) { - SportEntity sport = iterator_sports.next(); - Element sportNode = document.createElement("sport"); - sportNode.setAttribute("id", sport.getId().toString()); - sportNode.setAttribute("name", sport.getName()); - - Collection teams = sportService.getTeams(sport); - backupTeams(teams, document, sportNode); - - Collection positions = sportService.getPositions(sport); - backupPositions(positions, document, sportNode); - - tradingcards.appendChild(sportNode); - tradingcards.appendChild(document.createTextNode("\n")); - } - } - - private void backupTeams(Collection teams, Document document, Element sportNode) - { - Iterator iterator_teams = teams.iterator(); - while(iterator_teams.hasNext()) { - TeamEntity team = iterator_teams.next(); - Element teamNode = document.createElement("team"); - teamNode.setAttribute("id", team.getId().toString()); - teamNode.setAttribute("name", team.getName()); - //TODO what happens with null attributes? - //teamNode.setAttribute("short", teamView.getShortname()); - sportNode.appendChild(teamNode); - } - } - - private void backupPositions(Collection positions, Document document, Element sportNode) - { - Iterator iterator_positions = positions.iterator(); - while(iterator_positions.hasNext()) { - PositionEntity position = iterator_positions.next(); - Element positionNode = document.createElement("position"); - positionNode.setAttribute("id", position.getId().toString()); - positionNode.setAttribute("name", position.getName()); - positionNode.setAttribute("short", position.getShortName()); - sportNode.appendChild(positionNode); - } - sportNode.appendChild(document.createTextNode("\n")); - } - - private void backupCards(Document document, Element tradingcards) - { - Collection manufacturers = getTradingcardService().getAllManufacturers(); - Iterator iterator_manufacturers = manufacturers.iterator(); - while(iterator_manufacturers.hasNext()) { - ManufacturerEntity manufacturer = iterator_manufacturers.next(); - Element manufacturerNode = document.createElement("manufacturer"); - manufacturerNode.setAttribute("id", manufacturer.getId().toString()); - manufacturerNode.setAttribute("name", manufacturer.getName()); - Collection baseSets = getTradingcardService().getBaseSetsByManufacturer(manufacturer); - backupBaseSets(baseSets, document, manufacturerNode); - Collection parallelSets = getTradingcardService().getParallelSetsByManufacturer(manufacturer); - backupParallelSets(parallelSets, document, manufacturerNode); - Collection inserts = getTradingcardService().getInsertsByManufacturer(manufacturer); - backupInserts(inserts, document, manufacturerNode); - manufacturerNode.appendChild(document.createTextNode("\n")); - tradingcards.appendChild(manufacturerNode); - tradingcards.appendChild(document.createTextNode("\n")); - } - - Collection sportCards = getTradingcardService().getAllSportCards(); - Iterator iterator_sportCards = sportCards.iterator(); - while(iterator_sportCards.hasNext()) { - SportCardEntity sportCard = iterator_sportCards.next(); - Element cardNode = document.createElement("sportCard"); - cardNode.setAttribute("id", sportCard.getId().toString()); - cardNode.setAttribute("player", sportCard.getPlayer().getId().toString()); - cardNode.setAttribute("baseSet", sportCard.getBaseSet().getId().toString()); - if (sportCard.getParallelSet().getId() != null) - { - cardNode.setAttribute("parallelSet", sportCard.getParallelSet().getId().toString()); - } - if (sportCard.getInsert().getId() != null) - { - cardNode.setAttribute("insert", sportCard.getInsert().getId().toString()); - } - tradingcards.appendChild(cardNode); - tradingcards.appendChild(document.createTextNode("\n")); - } - } - - private void backupBaseSets(Collection baseSets, Document document, Element manufacturerNode) - { - Iterator iterator_baseSets= baseSets.iterator(); - while(iterator_baseSets.hasNext()) { - BaseSetEntity baseSet = iterator_baseSets.next(); - manufacturerNode.appendChild(document.createTextNode("\n")); - Element baseSetNode = document.createElement("baseSet"); - baseSetNode.setAttribute("id", baseSet.getId().toString()); - baseSetNode.setAttribute("name", baseSet.getName()); - manufacturerNode.appendChild(baseSetNode); - } - } - - private void backupParallelSets(Collection parallelSets, Document document, Element manufacturerNode) - { - Iterator iterator_parallelSets = parallelSets.iterator(); - while(iterator_parallelSets.hasNext()) { - ParallelSetEntity parallelSet = iterator_parallelSets.next(); - manufacturerNode.appendChild(document.createTextNode("\n")); - Element parallelSetNode = document.createElement("parallelSet"); - parallelSetNode.setAttribute("id", parallelSet.getId().toString()); - parallelSetNode.setAttribute("name", parallelSet.getName()); - parallelSetNode.setAttribute("baseSet", parallelSet.getBaseSet().getId().toString()); - manufacturerNode.appendChild(parallelSetNode); - } - } - - private void backupInserts(Collection inserts, Document document, Element manufacturerNode) - { - Iterator iterator_inserts = inserts.iterator(); - while(iterator_inserts.hasNext()) { - InsertEntity insert = iterator_inserts.next(); - manufacturerNode.appendChild(document.createTextNode("\n")); - Element insertNode = document.createElement("insert"); - insertNode.setAttribute("id", insert.getId().toString()); - insertNode.setAttribute("name", insert.getName()); - insertNode.setAttribute("baseSet", insert.getBaseSet().getId().toString()); - manufacturerNode.appendChild(insertNode); - } - } - - private SportService getSportService() - { - return null; - } - - private TradingcardService getTradingcardService() - { - return null; - } -} diff --git a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/FileExport.java b/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/FileExport.java deleted file mode 100644 index fb1848f..0000000 --- a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/FileExport.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.peetz.kontor.data; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.FactoryConfigurationError; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.w3c.dom.DOMException; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -public class FileExport -{ - public void exportFile(java.io.PrintWriter out) - { - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document document = builder.newDocument(); - ExportComics exportComics = new ExportComics(); - ExportMedien exportMedien = new ExportMedien(); - ExportLibrary exportLibrary = new ExportLibrary(); - ExportTradingCards exportTradingCards = new ExportTradingCards(); - - Element root = document.createElement("kontor"); - document.appendChild(root); - root.appendChild(document.createTextNode("\n")); - root.appendChild(exportComics.backupComics(document)); - root.appendChild(document.createTextNode("\n")); - root.appendChild(exportMedien.backupMedien(document)); - root.appendChild(document.createTextNode("\n")); - root.appendChild(exportLibrary.backupLibrary(document)); - root.appendChild(document.createTextNode("\n")); - root.appendChild(exportTradingCards.backupTradingCards(document)); - root.appendChild(document.createTextNode("\n")); - - TransformerFactory tFactory = TransformerFactory.newInstance(); - Transformer transformer = tFactory.newTransformer(); - - DOMSource source = new DOMSource(document); - StreamResult result = new StreamResult(out); - transformer.transform(source, result); - } catch (DOMException e) { - System.out.println(e.getMessage()); - } catch (TransformerConfigurationException e) { - System.out.println(e.getMessage()); - } catch (FactoryConfigurationError e) { - System.out.println(e.getMessage()); - } catch (ParserConfigurationException e) { - System.out.println(e.getMessage()); - } catch (TransformerFactoryConfigurationError e) { - System.out.println(e.getMessage()); - } catch (TransformerException e) { - System.out.println(e.getMessage()); - } - } -} diff --git a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/FileImport.java b/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/FileImport.java deleted file mode 100644 index 7b03dee..0000000 --- a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/FileImport.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.peetz.kontor.data; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.FactoryConfigurationError; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -public class FileImport -{ - public void importFile(File file) - { - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document document = builder.parse(file); - - Node xmlNode = document.getFirstChild(); - if (!xmlNode.getNodeName().equals("kontor")) return; - NodeList nodeList = xmlNode.getChildNodes(); - for (int i=0; i songs = new ArrayList(); - - System.out.println("AudioCD: " + id + ", " + album + "/" + artist); - AudioCDEntity audioCD = getMedienService().addCD(album); - audioCD.setArtist(artist); - audioCD.setCategory(category); - audioCD.setReleaseYear(year); - audioCD.setWantList(wantList); - audioCD.getSongs().addAll(songs); - getMedienService().saveCD(audioCD); - } - - public void parseFilm(Node node) - { - NamedNodeMap attr = node.getAttributes(); - Node idNode = attr.getNamedItem("id"); - String id = idNode.getNodeValue(); - - Node titleNode = attr.getNamedItem("title"); - String title = titleNode.getNodeValue(); - - System.out.println("DVD: " + id + ", " + title); - MedienService service = getMedienService(); - - service.addDVD(title); - } - - public void parseBoxSet(Node node) - { - NamedNodeMap attr = node.getAttributes(); - Node idNode = attr.getNamedItem("id"); - String id = idNode.getNodeValue(); - - Node titleNode = attr.getNamedItem("title"); - String title = titleNode.getNodeValue(); - - System.out.println("BoxSet: " + id + ", " + title); - MedienService service = getMedienService(); - - service.addBoxSet(title); - } - - private MedienService getMedienService() - { - return null; - } -} diff --git a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ImportTradingCards.java b/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ImportTradingCards.java deleted file mode 100644 index 79c4e23..0000000 --- a/java-ee/KontorWeb/src/main/java/com/peetz/kontor/data/ImportTradingCards.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.peetz.kontor.data; - -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import com.peetz.tradingcards.service.SportService; -import com.peetz.tradingcards.service.TradingcardService; - -public class ImportTradingCards -{ - public void parseNode(Node xmlNode) - { - NodeList childNodes = xmlNode.getChildNodes(); - for (int i=0; i - - - - org.eclipse.persistence.jpa.PersistenceProvider - jdbc/kontor - - - com.peetz.kontor.entity.KontorUserEntity - - com.peetz.comics.entity.ArtistEntity - com.peetz.comics.entity.ComicEntity - com.peetz.comics.entity.IssueEntity - com.peetz.comics.entity.PublisherEntity - com.peetz.comics.entity.StoryArcEntity - com.peetz.comics.entity.VolumeEntity - - com.peetz.library.entity.ArticleEntity - com.peetz.library.entity.BookEntity - com.peetz.library.entity.BookshelfEntity - com.peetz.library.entity.FileEntity - com.peetz.library.entity.MagazineEntity - com.peetz.library.entity.ShelfObjectEntity - com.peetz.library.entity.ShelfboardEntity - - com.peetz.medien.entity.AudioCDEntity - com.peetz.medien.entity.BoxSetEntity - com.peetz.medien.entity.FilmEntity - - com.peetz.tradingcards.entity.BaseSetEntity - com.peetz.tradingcards.entity.InsertEntity - com.peetz.tradingcards.entity.ManufacturerEntity - com.peetz.tradingcards.entity.ParallelSetEntity - com.peetz.tradingcards.entity.PlayerEntity - com.peetz.tradingcards.entity.PositionEntity - com.peetz.tradingcards.entity.SportCardEntity - com.peetz.tradingcards.entity.SportEntity - com.peetz.tradingcards.entity.TeamEntity - - - - - - diff --git a/java-ee/KontorWeb/src/main/webapp/WEB-INF/faces-config.xml b/java-ee/KontorWeb/src/main/webapp/WEB-INF/faces-config.xml deleted file mode 100644 index 77df4e5..0000000 --- a/java-ee/KontorWeb/src/main/webapp/WEB-INF/faces-config.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - kontor - /index.xhtml - - - comics - /comics.xhtml - - - library - /library.xhtml - - - medien - /medien.xhtml - - - tradingcards - /tradingcards.xhtml - - - sport - /sport.xhtml - - - sportAdd - /sport/sportAdd.xhtml - - - - /sport/sportAdd.xhtml - - addSport - /sport/sportDetails.xhtml - - - saveSport - /sport/sportDetails.xhtml - - - - now - java.util.Date - request - - - comicView - com.peetz.comics.view.ComicView - request - - - libraryView - com.peetz.library.view.LibraryView - request - - - medienView - com.peetz.medien.view.MedienView - request - - - tradingCardsView - com.peetz.tradingcards.view.TradingCardsView - request - - - sportView - com.peetz.tradingcards.view.SportView - request - - diff --git a/java-ee/KontorWeb/src/main/webapp/WEB-INF/glassfish-web.xml b/java-ee/KontorWeb/src/main/webapp/WEB-INF/glassfish-web.xml deleted file mode 100644 index c95df12..0000000 --- a/java-ee/KontorWeb/src/main/webapp/WEB-INF/glassfish-web.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - /kontor - - - diff --git a/java-ee/KontorWeb/src/main/webapp/WEB-INF/web.xml b/java-ee/KontorWeb/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 112c02f..0000000 --- a/java-ee/KontorWeb/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - javax.faces.PROJECT_STAGE - Development - - - Faces Servlet - javax.faces.webapp.FacesServlet - 1 - - - Faces Servlet - /faces/* - - - 30 - - - faces/index.xhtml - - diff --git a/java-ee/KontorWeb/src/main/webapp/comics.xhtml b/java-ee/KontorWeb/src/main/webapp/comics.xhtml deleted file mode 100644 index 15d340f..0000000 --- a/java-ee/KontorWeb/src/main/webapp/comics.xhtml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - Kontor Application - - -
Comics Application
-
-
- Kontor

- Comics

- Library

- Medien

- Trading Cards

-
-
- -
- - - - - - - - -
-
-
-
Ingenieurbüro Thomas Peetz
- -
- diff --git a/java-ee/KontorWeb/src/main/webapp/css/store.css b/java-ee/KontorWeb/src/main/webapp/css/store.css deleted file mode 100755 index de05f30..0000000 --- a/java-ee/KontorWeb/src/main/webapp/css/store.css +++ /dev/null @@ -1,145 +0,0 @@ -.spring { - border: thin solid black; - - font-size:10px; - font-family:Arial; - font-weight:normal; - background-color: #ABE7FA; - - } -.myButton { - -moz-box-shadow: 0px 10px 14px -7px #276873; - -webkit-box-shadow: 0px 10px 14px -7px #276873; - box-shadow: 0px 10px 14px -7px #276873; - background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #599bb3), color-stop(1, #408c99)); - background:-moz-linear-gradient(top, #599bb3 5%, #408c99 100%); - background:-webkit-linear-gradient(top, #599bb3 5%, #408c99 100%); - background:-o-linear-gradient(top, #599bb3 5%, #408c99 100%); - background:-ms-linear-gradient(top, #599bb3 5%, #408c99 100%); - background:linear-gradient(to bottom, #599bb3 5%, #408c99 100%); - filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#599bb3', endColorstr='#408c99',GradientType=0); - background-color:#599bb3; - -moz-border-radius:8px; - -webkit-border-radius:8px; - border-radius:8px; - display:inline-block; - cursor:pointer; - color:#ffffff; - font-family:Arial; - font-size:12px; - font-weight:bold; - padding:7px 15px; - text-decoration:none; - text-shadow:0px 1px 0px #3d768a; -} -.myButton:hover { - background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #408c99), color-stop(1, #599bb3)); - background:-moz-linear-gradient(top, #408c99 5%, #599bb3 100%); - background:-webkit-linear-gradient(top, #408c99 5%, #599bb3 100%); - background:-o-linear-gradient(top, #408c99 5%, #599bb3 100%); - background:-ms-linear-gradient(top, #408c99 5%, #599bb3 100%); - background:linear-gradient(to bottom, #408c99 5%, #599bb3 100%); - filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#408c99', endColorstr='#599bb3',GradientType=0); - background-color:#408c99; -} -.myButton:active { - position:relative; - top:1px; -} - - - .tablestyle { - margin:0px;padding:0px; - width:50%; - box-shadow: 10px 10px 5px #888888; - border:1px solid #000000; - - -moz-border-radius-bottomleft:0px; - -webkit-border-bottom-left-radius:0px; - border-bottom-left-radius:0px; - - -moz-border-radius-bottomright:0px; - -webkit-border-bottom-right-radius:0px; - border-bottom-right-radius:0px; - - -moz-border-radius-topright:0px; - -webkit-border-top-right-radius:0px; - border-top-right-radius:0px; - - -moz-border-radius-topleft:0px; - -webkit-border-top-left-radius:0px; - border-top-left-radius:0px; -}.tablestyle table{ - border-collapse: collapse; - border-spacing: 0; - width:100%; - height:100%; - margin:0px;padding:0px; -}.tablestyle tr:last-child td:last-child { - -moz-border-radius-bottomright:0px; - -webkit-border-bottom-right-radius:0px; - border-bottom-right-radius:0px; -} -.tablestyle table tr:first-child td:first-child { - -moz-border-radius-topleft:0px; - -webkit-border-top-left-radius:0px; - border-top-left-radius:0px; -} -.tablestyle table tr:first-child td:last-child { - -moz-border-radius-topright:0px; - -webkit-border-top-right-radius:0px; - border-top-right-radius:0px; -}.tablestyle tr:last-child td:first-child{ - -moz-border-radius-bottomleft:0px; - -webkit-border-bottom-left-radius:0px; - border-bottom-left-radius:0px; -}.tablestyle tr:hover td{ - -} -.tablestyle tr:nth-child(odd){ background-color:#aad4ff; } -.tablestyle tr:nth-child(even) { background-color:#ffffff; }.tablestyle td{ - vertical-align:middle; - - - border:1px solid #000000; - border-width:0px 1px 1px 0px; - text-align:left; - padding:7px; - font-size:10px; - font-family:Arial; - font-weight:normal; - color:#000000; -}.tablestyle tr:last-child td{ - border-width:0px 1px 0px 0px; -}.tablestyle tr td:last-child{ - border-width:0px 0px 1px 0px; -}.tablestyle tr:last-child td:last-child{ - border-width:0px 0px 0px 0px; -} -.tablestyle tr:first-child td{ - background:-o-linear-gradient(bottom, #005fbf 5%, #003f7f 100%); background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #005fbf), color-stop(1, #003f7f) ); - background:-moz-linear-gradient( center top, #005fbf 5%, #003f7f 100% ); - filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#005fbf", endColorstr="#003f7f"); background: -o-linear-gradient(top,#005fbf,003f7f); - - background-color:#005fbf; - border:0px solid #000000; - text-align:center; - border-width:0px 0px 1px 1px; - font-size:14px; - font-family:Arial; - font-weight:bold; - color:#ffffff; -} -.tablestyle tr:first-child:hover td{ - background:-o-linear-gradient(bottom, #005fbf 5%, #003f7f 100%); background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #005fbf), color-stop(1, #003f7f) ); - background:-moz-linear-gradient( center top, #005fbf 5%, #003f7f 100% ); - filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#005fbf", endColorstr="#003f7f"); background: -o-linear-gradient(top,#005fbf,003f7f); - - background-color:#005fbf; -} -.tablestyle tr:first-child td:first-child{ - border-width:0px 0px 1px 0px; -} -.tablestyle tr:first-child td:last-child{ - border-width:0px 0px 1px 1px; -} diff --git a/java-ee/KontorWeb/src/main/webapp/index.xhtml b/java-ee/KontorWeb/src/main/webapp/index.xhtml deleted file mode 100755 index 870d904..0000000 --- a/java-ee/KontorWeb/src/main/webapp/index.xhtml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - -
- - - - - - - - - - - - -
- - -
- - - - Key - - - - Value - - - -
-
- diff --git a/java-ee/KontorWeb/src/main/webapp/kontorTemplate.xhtml b/java-ee/KontorWeb/src/main/webapp/kontorTemplate.xhtml deleted file mode 100644 index 90a8e65..0000000 --- a/java-ee/KontorWeb/src/main/webapp/kontorTemplate.xhtml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - Kontor Application - - - - -
- Top -
-
-
- - Kontor

- Comics

- Library

- Medien - Trading Cards

-
-
-
- -
- Content -
-
-
-
- Ingenieurbüro Thomas Peetz -
- -
- - diff --git a/java-ee/KontorWeb/src/main/webapp/library.xhtml b/java-ee/KontorWeb/src/main/webapp/library.xhtml deleted file mode 100644 index ffeac85..0000000 --- a/java-ee/KontorWeb/src/main/webapp/library.xhtml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - Kontor Application - - -
Library Application
-
-
- Kontor

- Comics

- Library

- Medien

- Trading Cards

-
-
- -
- - - - - - - - -
-
-
-
Ingenieurbüro Thomas Peetz
- -
- diff --git a/java-ee/KontorWeb/src/main/webapp/medien.xhtml b/java-ee/KontorWeb/src/main/webapp/medien.xhtml deleted file mode 100644 index b77bd49..0000000 --- a/java-ee/KontorWeb/src/main/webapp/medien.xhtml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - Kontor Application - - -
Medien Application
-
-
- Kontor

- Comics

- Library

- Medien

- Trading Cards

-
-
- -
- - - - - - - - -
-
-
-
Ingenieurbüro Thomas Peetz
- -
- diff --git a/java-ee/KontorWeb/src/main/webapp/resources/css/cssLayout.css b/java-ee/KontorWeb/src/main/webapp/resources/css/cssLayout.css deleted file mode 100644 index b2f98ff..0000000 --- a/java-ee/KontorWeb/src/main/webapp/resources/css/cssLayout.css +++ /dev/null @@ -1,71 +0,0 @@ - -#top { - position: relative; - background-color: lightgrey; - text-align: center; - width: 100%; - height: 30px; - color: white; - padding: 5px; - //margin: 0px 0px 10px 0px; -} - -#bottom { - position: relative; - background-color: lightgrey; - width: 100%; - height: 30px; - padding: 5px; - //margin: 10px 0px 0px 0px; -} - -#left { - float: left; - background-color: tan; - padding: 5px; - width: 150px; - height: 50%; -} - -#right { - float: right; - background-color: tan; - //padding: 5px; - width: 150px; - height: 50%; -} - -.center_content { - position: relative; - background-color: wheat; - padding: 5px; - height: 50%; -} - -.left_content { - background-color: tan; - padding: 5px; - margin-left: 170px; - height: 50%; -} - -.right_content { - background-color: wheat; - padding: 5px; - //margin: 0px 170px 0px 170px; - height: 50%; -} - -#top a:link, #top a:visited { - color: white; - font-weight : bold; - text-decoration: none; -} - -#top a:link:hover, #top a:visited:hover { - color: black; - font-weight : bold; - text-decoration : underline; -} - - diff --git a/java-ee/KontorWeb/src/main/webapp/resources/css/default.css b/java-ee/KontorWeb/src/main/webapp/resources/css/default.css deleted file mode 100644 index 6cbc3d1..0000000 --- a/java-ee/KontorWeb/src/main/webapp/resources/css/default.css +++ /dev/null @@ -1,29 +0,0 @@ -body { - background-color: #ffffff; - font-size: 12px; - font-family: Verdana, "Verdana CE", Arial, "Arial CE", "Lucida Grande CE", lucida, "Helvetica CE", sans-serif; - color: #000000; - margin: 10px; -} - -h1 { - font-family: Arial, "Arial CE", "Lucida Grande CE", lucida, "Helvetica CE", sans-serif; - border-bottom: 1px solid #AFAFAF; - font-size: 16px; - font-weight: bold; - margin: 0px; - padding: 0px; - color: #D20005; -} - -a:link, a:visited { - color: #045491; - font-weight : bold; - text-decoration: none; -} - -a:link:hover, a:visited:hover { - color: #045491; - font-weight : bold; - text-decoration : underline; -} diff --git a/java-ee/KontorWeb/src/main/webapp/seite.html b/java-ee/KontorWeb/src/main/webapp/seite.html deleted file mode 100644 index 8478fea..0000000 --- a/java-ee/KontorWeb/src/main/webapp/seite.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - Testseite - - -
-
Testseite
-
- -
Hauptseite
-
Details
-
- -
- - \ No newline at end of file diff --git a/java-ee/KontorWeb/src/main/webapp/sport.xhtml b/java-ee/KontorWeb/src/main/webapp/sport.xhtml deleted file mode 100644 index 840a202..0000000 --- a/java-ee/KontorWeb/src/main/webapp/sport.xhtml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - Kontor Application - - -
Trading Cards Application
-
-
- Kontor

- Comics

- Library

- Medien

- Trading Cards

- Sport

-
-
- -
- - - - - - - - -
-
-
-
Ingenieurbüro Thomas Peetz
- -
- diff --git a/java-ee/KontorWeb/src/main/webapp/sport/sportAdd.xhtml b/java-ee/KontorWeb/src/main/webapp/sport/sportAdd.xhtml deleted file mode 100644 index ee5ee2d..0000000 --- a/java-ee/KontorWeb/src/main/webapp/sport/sportAdd.xhtml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - Kontor Application - - -
Trading Cards Application
-
-
- Kontor

- Comics

- Library

- Medien

- Trading Cards

- Sport

-
-
- -
- - - - - - - -
-
-
-
Ingenieurbüro Thomas Peetz
- -
- diff --git a/java-ee/KontorWeb/src/main/webapp/sport/sportDetails.xhtml b/java-ee/KontorWeb/src/main/webapp/sport/sportDetails.xhtml deleted file mode 100644 index cc6be43..0000000 --- a/java-ee/KontorWeb/src/main/webapp/sport/sportDetails.xhtml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - Kontor Application - - -
Trading Cards Application
-
-
- Kontor

- Comics

- Library

- Medien

- Trading Cards

- Sport

-
-
- -
- - - - - - - -
-
-
-
Ingenieurbüro Thomas Peetz
- -
- diff --git a/java-ee/KontorWeb/src/main/webapp/tradingcards.xhtml b/java-ee/KontorWeb/src/main/webapp/tradingcards.xhtml deleted file mode 100644 index 585697e..0000000 --- a/java-ee/KontorWeb/src/main/webapp/tradingcards.xhtml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - Kontor Application - - -
Trading Cards Application
-
-
- Kontor

- Comics

- Library

- Medien

- Trading Cards

- Sport

-
-
- -
- - - - - - - - -
-
-
-
Ingenieurbüro Thomas Peetz
- -
- diff --git a/java-ee/LibraryImpl/build.gradle b/java-ee/LibraryImpl/build.gradle deleted file mode 100644 index fa86a7f..0000000 --- a/java-ee/LibraryImpl/build.gradle +++ /dev/null @@ -1,5 +0,0 @@ -jar { - manifest { - attributes 'Implementation-Title': 'Library', 'Implementation-Version': version - } -} diff --git a/java-ee/LibraryImpl/config/checkstyle/checkstyle.xml b/java-ee/LibraryImpl/config/checkstyle/checkstyle.xml deleted file mode 100644 index 7c682c3..0000000 --- a/java-ee/LibraryImpl/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java-ee/LibraryImpl/config/checkstyle/checkstyle.xsl b/java-ee/LibraryImpl/config/checkstyle/checkstyle.xsl deleted file mode 100644 index 393a01b..0000000 --- a/java-ee/LibraryImpl/config/checkstyle/checkstyle.xsl +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -

CheckStyle Audit

Designed for use with CheckStyle and Ant.
-
- - - -
- - - -
- - - - - -

-

- -


- - - - -
- - - - -

Files

- - - - - - - - - - - - - - -
NameErrors
-
- - - - -

File

- - - - - - - - - - - - - -
Error DescriptionLine
- Back to top -
- - - -

Summary

- - - - - - - - - - - - -
FilesErrors
-
- - - - a - b - - -
- - diff --git a/java-ee/LibraryImpl/config/findbugs/findbugs.xml b/java-ee/LibraryImpl/config/findbugs/findbugs.xml deleted file mode 100644 index 34a6e01..0000000 --- a/java-ee/LibraryImpl/config/findbugs/findbugs.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/ArticleDao.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/ArticleDao.java deleted file mode 100644 index a62a119..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/ArticleDao.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.peetz.library.dal; - -import java.util.List; - -import javax.ejb.Local; - -import com.peetz.library.entity.ArticleEntity; - -@Local -public interface ArticleDao { - public ArticleEntity getById(Long id); - - public List findByIds(List ids); - - public List findByTitle(String title); - - public List getRelatedArticles(ArticleEntity entity); - - public ArticleEntity assign(ArticleEntity origin, ArticleEntity reference); - - public ArticleEntity store(ArticleEntity entity); - - public void delete(ArticleEntity entity); - -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/BookDao.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/BookDao.java deleted file mode 100644 index 56f2fea..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/BookDao.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.peetz.library.dal; - -import java.util.Collection; - -import javax.ejb.Local; - -import com.peetz.library.entity.BookEntity; - -@Local -public interface BookDao { - public BookEntity findById(Long id); - public Collection findByIds(Collection ids); - public BookEntity store(BookEntity entity); - public void delete(BookEntity entity); -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/BookshelfDao.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/BookshelfDao.java deleted file mode 100644 index ddf5b10..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/BookshelfDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.peetz.library.dal; - -import java.util.List; - -import javax.ejb.Local; - -import com.peetz.library.entity.BookshelfEntity; - - -@Local -public interface BookshelfDao { - public BookshelfEntity getById(Long id); - - public List findByIds(List ids); - - public List findByTitle(String title); - - public BookshelfEntity store(BookshelfEntity entity); - - public void delete(BookshelfEntity entity); - -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/FileDao.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/FileDao.java deleted file mode 100644 index b9e2e31..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/FileDao.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.peetz.library.dal; - -import java.util.Collection; - -import javax.ejb.Local; - -import com.peetz.library.entity.FileEntity; - -@Local -public interface FileDao { - public FileEntity findById(Long id); - public Collection findByIds(Collection ids); - public FileEntity store(FileEntity entity); - public void delete(FileEntity entity); -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/MagazineDao.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/MagazineDao.java deleted file mode 100644 index 2df143e..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/MagazineDao.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.peetz.library.dal; - -import java.util.Collection; - -import javax.ejb.Local; - -import com.peetz.library.entity.MagazineEntity; - -@Local -public interface MagazineDao { - public MagazineEntity findById(Long id); - public Collection findByIds(Collection ids); - public MagazineEntity store(MagazineEntity entity); - public void delete(MagazineEntity entity); -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/ShelfObjectDao.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/ShelfObjectDao.java deleted file mode 100644 index 2028863..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/ShelfObjectDao.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.peetz.library.dal; - -import java.util.Collection; - -import javax.ejb.Local; - -import com.peetz.library.entity.ShelfObjectEntity; - -@Local -public interface ShelfObjectDao { - public ShelfObjectEntity getById(Long id); - public Collection getByIds(Collection ids); - public ShelfObjectEntity store(ShelfObjectEntity entity); - public void delete(ShelfObjectEntity entity); -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/ShelfboardDao.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/ShelfboardDao.java deleted file mode 100644 index ce326a7..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/ShelfboardDao.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.peetz.library.dal; - -import java.util.Collection; - -import javax.ejb.Local; - -import com.peetz.library.entity.ShelfboardEntity; - -@Local -public interface ShelfboardDao { - public ShelfboardEntity getById(Long id); - public Collection getByIds(Collection ids); - public ShelfboardEntity store(ShelfboardEntity entity); - public void delete(ShelfboardEntity entity); -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/package-info.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/package-info.java deleted file mode 100644 index 2c24b31..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/dal/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * - */ -/** - * @author TPEETZ - * - */ -package com.peetz.library.dal; \ No newline at end of file diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/ArticleEntity.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/ArticleEntity.java deleted file mode 100644 index 0348e2b..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/ArticleEntity.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.peetz.library.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Article.findAll", query="SELECT a from ArticleEntity as a") -}) - -@Entity -@Table(name="ARTICLE") -public class ArticleEntity { - private Long id; - - private String title; - - private Collection relatedArticles = new ArrayList(); - - private Collection originArticles = new ArrayList(); - - private FileEntity file; - - private MagazineEntity magazine; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - @ManyToMany - public Collection getRelatedArticles() { - return relatedArticles; - } - - public void setRelatedArticles(Collection relatedArticles) { - this.relatedArticles = relatedArticles; - } - - @ManyToMany - public Collection getOriginArticles() { - return originArticles; - } - - public void setOriginArticles(Collection originArticles) { - this.originArticles = originArticles; - } - - @ManyToOne - public FileEntity getFile() { - return file; - } - - public void setFile(FileEntity file) { - this.file = file; - } - - @ManyToOne - public MagazineEntity getMagazine() { - return magazine; - } - - public void setMagazine(MagazineEntity magazine) { - this.magazine = magazine; - } -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/BookEntity.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/BookEntity.java deleted file mode 100644 index 1f86ba0..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/BookEntity.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.peetz.library.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Book.findAll", query="SELECT a from BookEntity as a") -}) - -@Entity -@Table(name="BOOK") -public class BookEntity { - private Long id; - - private String title; - - private String author; - - private String publisher; - - private String isbn; - - private Long page; - - private String edition; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - @Column - public String getAuthor() { - return author; - } - - public void setAuthor(String author) { - this.author = author; - } - - @Column - public String getPublisher() { - return publisher; - } - - public void setPublisher(String publisher) { - this.publisher = publisher; - } - - @Column - public String getIsbn() { - return isbn; - } - - public void setIsbn(String isbn) { - this.isbn = isbn; - } - - @Column - public Long getPage() { - return page; - } - - public void setPage(Long page) { - this.page = page; - } - - @Column - public String getEdition() { - return edition; - } - - public void setEdition(String edition) { - this.edition = edition; - } -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/BookshelfEntity.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/BookshelfEntity.java deleted file mode 100644 index 521a9bf..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/BookshelfEntity.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.peetz.library.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Bookshelf.findAll", query="SELECT b from BookshelfEntity as b"), - @NamedQuery(name="Bookshelf.findById", query="SELECT b from BookshelfEntity as b WHERE b.id = :id"), - @NamedQuery(name="Bookshelf.findByTitle", query="SELECT b from BookshelfEntity as b WHERE b.title = :title") -}) - -@Entity -@Table(name="BOOKSHELF") -public class BookshelfEntity { - - private Long id; - - private String title; - - private Collection shelfBoards = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } - - @OneToMany(mappedBy="bookshelf", cascade=CascadeType.REMOVE) - public Collection getShelfBoards() { - return shelfBoards; - } - - public void setShelfBoards(Collection shelfBoards) { - this.shelfBoards = shelfBoards; - } -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/FileEntity.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/FileEntity.java deleted file mode 100644 index 6f31553..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/FileEntity.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.peetz.library.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@Entity -@Table(name="FILE") -public class FileEntity { - private Long id; - - private String title; - - private Collection articles = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - @OneToMany(mappedBy="file", cascade=CascadeType.REMOVE) - public Collection getArticles() { - return articles; - } - - public void setArticles(Collection articles) { - this.articles = articles; - } - -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/MagazineEntity.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/MagazineEntity.java deleted file mode 100644 index 6bed864..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/MagazineEntity.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.peetz.library.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@Entity -@Table(name="MAGAZINE") -public class MagazineEntity { - private Long id; - - private String title; - - private Collection articles = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - @OneToMany(mappedBy="magazine", cascade=CascadeType.REMOVE) - public Collection getArticles() { - return articles; - } - - public void setArticles(Collection articles) { - this.articles = articles; - } - -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/ShelfObjectEntity.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/ShelfObjectEntity.java deleted file mode 100644 index 98a5cd1..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/ShelfObjectEntity.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.peetz.library.entity; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -@Entity -@Table(name="SHELFOBJECT") -public class ShelfObjectEntity { - private Long id; - - private ShelfboardEntity shelfboard; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @ManyToOne - public ShelfboardEntity getShelfboard() { - return shelfboard; - } - - public void setShelfboard(ShelfboardEntity shelfboard) { - this.shelfboard = shelfboard; - } -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/ShelfboardEntity.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/ShelfboardEntity.java deleted file mode 100644 index d6e4edd..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/ShelfboardEntity.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.peetz.library.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@Entity -@Table(name="SHELFBOARD") -public class ShelfboardEntity { - private Long id; - - private String title; - - private BookshelfEntity bookshelf; - - private Collection objects = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } - - @ManyToOne - public BookshelfEntity getBookshelf() { - return bookshelf; - } - - public void setBookshelf(BookshelfEntity bookshelf) { - this.bookshelf = bookshelf; - } - - @OneToMany(mappedBy="shelfboard", cascade=CascadeType.REMOVE) - public Collection getObjects() { - return objects; - } - - public void setObjects(Collection objects) { - this.objects = objects; - } - -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/package-info.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/package-info.java deleted file mode 100644 index 94536f3..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/entity/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * - */ -/** - * @author TPEETZ - * - */ -package com.peetz.library.entity; \ No newline at end of file diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/service/LibraryService.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/service/LibraryService.java deleted file mode 100644 index 7ac294f..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/service/LibraryService.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.peetz.library.service; - -import java.util.Collection; - -import javax.ejb.Local; - -import com.peetz.library.entity.ArticleEntity; -import com.peetz.library.entity.BookEntity; -import com.peetz.library.entity.BookshelfEntity; - -@Local -public interface LibraryService { - - Collection getAllBooks(); - - Collection getAllBookshelfs(); - - Collection getAllArticles(); - - void addBookshelf(String title); - - void addArticle(String title); - - BookEntity addBook(String title); - - void saveBook(BookEntity book); - -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/service/LibraryServiceImpl.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/service/LibraryServiceImpl.java deleted file mode 100644 index 62baae8..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/service/LibraryServiceImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.peetz.library.service; - -import java.util.Collection; - -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; - -import com.peetz.library.entity.ArticleEntity; -import com.peetz.library.entity.BookEntity; -import com.peetz.library.entity.BookshelfEntity; -import java.util.ArrayList; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -@Stateless(name="LibraryService") -@TransactionAttribute(TransactionAttributeType.REQUIRED) -public class LibraryServiceImpl implements LibraryService { - - @PersistenceContext(unitName = "kontor") - private EntityManager em; - - @SuppressWarnings("unchecked") - @Override - public Collection getAllBooks() { - Query query = em.createNamedQuery("Book.findAll"); - ArrayList bookList = new ArrayList(query.getResultList()); - return bookList; - } - - @SuppressWarnings("unchecked") - @Override - public Collection getAllBookshelfs() { - Query query = em.createNamedQuery("Bookshelf.findAll"); - ArrayList bookshelfList = new ArrayList(query.getResultList()); - return bookshelfList; - } - - @SuppressWarnings("unchecked") - @Override - public Collection getAllArticles() { - Query query = em.createNamedQuery("Article.findAll"); - ArrayList articleList = new ArrayList(query.getResultList()); - return articleList; - } - - @Override - public void addBookshelf(String title) { - } - - @Override - public void addArticle(String title) { - } - - @Override - public BookEntity addBook(String title) { - return null; - } - - @Override - public void saveBook(BookEntity book) { - } -} diff --git a/java-ee/LibraryImpl/src/main/java/com/peetz/library/service/package-info.java b/java-ee/LibraryImpl/src/main/java/com/peetz/library/service/package-info.java deleted file mode 100644 index 4a56b54..0000000 --- a/java-ee/LibraryImpl/src/main/java/com/peetz/library/service/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * - */ -/** - * @author TPEETZ - * - */ -package com.peetz.library.service; \ No newline at end of file diff --git a/java-ee/LibraryWeb/build.gradle b/java-ee/LibraryWeb/build.gradle deleted file mode 100644 index 9a41aae..0000000 --- a/java-ee/LibraryWeb/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -apply plugin: 'war' - -version = '0.0.1' - -dependencies { - compile project(':LibraryImpl') -} diff --git a/java-ee/LibraryWeb/src/main/java/com/peetz/library/view/LibraryView.java b/java-ee/LibraryWeb/src/main/java/com/peetz/library/view/LibraryView.java deleted file mode 100644 index 9a566a0..0000000 --- a/java-ee/LibraryWeb/src/main/java/com/peetz/library/view/LibraryView.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package com.peetz.library.view; - -import com.peetz.library.service.LibraryService; -import java.io.Serializable; -import java.util.logging.Logger; -import javax.ejb.EJB; -import javax.faces.bean.ManagedBean; -import javax.faces.bean.RequestScoped; - -/** - * - * @author tpeetz - */ -@ManagedBean(name="LibraryView") -@RequestScoped -public class LibraryView implements Serializable { - - private static final long serialVersionUID = -6251848426914654974L; - - private static final Logger LOG = Logger.getLogger(LibraryView.class.getName()); - - @EJB - private LibraryService libraryService; - - public LibraryView() { - LOG.info("LibraryView created"); - } - - public Integer getBookNumber() { - return libraryService.getAllBooks().size(); - } - - public Integer getArticleNumber() { - return libraryService.getAllArticles().size(); - } -} diff --git a/java-ee/LibraryWeb/src/main/webapp/index.jsp b/java-ee/LibraryWeb/src/main/webapp/index.jsp deleted file mode 100644 index 9e061a7..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/index.jsp +++ /dev/null @@ -1,33 +0,0 @@ - - Library Application - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
Kontor -

Library Manager

- Show the book list -
 
-

Ingenieurbüro Thomas Peetz

-
- - diff --git a/java-ee/LibraryWeb/src/main/webapp/jsp/articleAdd.jsp b/java-ee/LibraryWeb/src/main/webapp/jsp/articleAdd.jsp deleted file mode 100644 index 63f9266..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/jsp/articleAdd.jsp +++ /dev/null @@ -1,67 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Library Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.library.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - -
Title:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/LibraryWeb/src/main/webapp/jsp/articleEdit.jsp b/java-ee/LibraryWeb/src/main/webapp/jsp/articleEdit.jsp deleted file mode 100644 index d3ae5e5..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/jsp/articleEdit.jsp +++ /dev/null @@ -1,69 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Library Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.library.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - -
Titel:
- <%-- hidden fields for id and userId --%> - - <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/LibraryWeb/src/main/webapp/jsp/articleList.jsp b/java-ee/LibraryWeb/src/main/webapp/jsp/articleList.jsp deleted file mode 100644 index d8570ba..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/jsp/articleList.jsp +++ /dev/null @@ -1,90 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Library Application - - - - - - - - - - - - - - - - - - - - - - - - -
Show article list
- <% out.println(com.peetz.library.navigation.MenuLinks.getInstance().toString()); %> - - - - <%-- set the header --%> - - - - - - <%-- check if article exists and display message or iterate over articles --%> - - - - - - - - - <%-- print out the article informations --%> - - <%-- print out the edit and delete link for each article --%> - - - - - - <%-- end interate --%> - - <%-- if articles cannot be found display a text --%> - - - - - - - -
Article Title  
No articles available
EditDelete
No articles found.
-
- <%-- add and back to menu button --%> - Add a new article - -   - Back to menu - - -
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/LibraryWeb/src/main/webapp/jsp/boardAdd.jsp b/java-ee/LibraryWeb/src/main/webapp/jsp/boardAdd.jsp deleted file mode 100644 index e1bc491..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/jsp/boardAdd.jsp +++ /dev/null @@ -1,68 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Library Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.library.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - - -
Shelf:
Title:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/LibraryWeb/src/main/webapp/jsp/boardEdit.jsp b/java-ee/LibraryWeb/src/main/webapp/jsp/boardEdit.jsp deleted file mode 100644 index 7221317..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/jsp/boardEdit.jsp +++ /dev/null @@ -1,67 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Library Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.library.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - -
Title:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/LibraryWeb/src/main/webapp/jsp/bookAdd.jsp b/java-ee/LibraryWeb/src/main/webapp/jsp/bookAdd.jsp deleted file mode 100644 index d3fb02b..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/jsp/bookAdd.jsp +++ /dev/null @@ -1,67 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Library Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.library.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - -
Title:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/LibraryWeb/src/main/webapp/jsp/bookEdit.jsp b/java-ee/LibraryWeb/src/main/webapp/jsp/bookEdit.jsp deleted file mode 100644 index 8d54239..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/jsp/bookEdit.jsp +++ /dev/null @@ -1,85 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Library Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.library.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - - - - - - - - - - - - - - - - - -
Titel:
Autor:
Verlag:
ISBN:
Seiten:
- <%-- hidden fields for id and userId --%> - - <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/LibraryWeb/src/main/webapp/jsp/bookList.jsp b/java-ee/LibraryWeb/src/main/webapp/jsp/bookList.jsp deleted file mode 100644 index 9c1d40d..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/jsp/bookList.jsp +++ /dev/null @@ -1,33 +0,0 @@ - - Library Application - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
Kontor -

Library Manager

- -
 
-

Ingenieurbüro Thomas Peetz

-
- - diff --git a/java-ee/LibraryWeb/src/main/webapp/jsp/index.jsp b/java-ee/LibraryWeb/src/main/webapp/jsp/index.jsp deleted file mode 100644 index e75087a..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/jsp/index.jsp +++ /dev/null @@ -1,58 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" - pageEncoding="ISO-8859-1"%> -<%@taglib uri="http://java.sun.com/jstl/core" prefix="c"%> -<%@taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %> - - - - - - - - - Library Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.library.navigation.MenuLinks.getInstance().toString()); %> - -

Library Manager

- Show the booklist -
- Import CD List -
- - - Import Books - -
- Show the bookshelfs -
- Show the articles -
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/LibraryWeb/src/main/webapp/jsp/shelfAdd.jsp b/java-ee/LibraryWeb/src/main/webapp/jsp/shelfAdd.jsp deleted file mode 100644 index 30b7e3b..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/jsp/shelfAdd.jsp +++ /dev/null @@ -1,67 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Library Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.library.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - -
Title:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/LibraryWeb/src/main/webapp/jsp/shelfEdit.jsp b/java-ee/LibraryWeb/src/main/webapp/jsp/shelfEdit.jsp deleted file mode 100644 index a7c56af..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/jsp/shelfEdit.jsp +++ /dev/null @@ -1,92 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Library Application - - - - - - - - - - - - - - - - - - - - - - - - -
Library Manager
- <% out.println(com.peetz.library.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - -
Title:
- <%-- hidden fields for id and userId --%> - - <%-- set the parameter for the dispatch action --%> - - -
- - - - - - - - - - - - - - - - - - - -
Shelfboard  
No boards available
EditDelete
No boards available
Add board
-
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/LibraryWeb/src/main/webapp/jsp/shelfList.jsp b/java-ee/LibraryWeb/src/main/webapp/jsp/shelfList.jsp deleted file mode 100644 index 3313853..0000000 --- a/java-ee/LibraryWeb/src/main/webapp/jsp/shelfList.jsp +++ /dev/null @@ -1,91 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Library Application - - - - - - - - - - - - - - - - - - - - - - - - -
Show shelf list
- <% out.println(com.peetz.library.navigation.MenuLinks.getInstance().toString()); %> - - - - <%-- set the header --%> - - - - - - - <%-- check if bookshelf exists and display message or iterate over bookshelfs --%> - - - - - - - - - <%-- print out the book informations --%> - - - <%-- print out the edit and delete link for each book --%> - - - - - - <%-- end interate --%> - - <%-- if books cannot be found display a text --%> - - - - - - - -
Bookshelf name# Shelfs  
No shelfs available
EditDelete
No shelfs found.
-
- <%-- add and back to menu button --%> - Add a new book shelf -   - Back to menu - - -
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/MedienImpl/build.gradle b/java-ee/MedienImpl/build.gradle deleted file mode 100644 index a08e29c..0000000 --- a/java-ee/MedienImpl/build.gradle +++ /dev/null @@ -1,5 +0,0 @@ -jar { - manifest { - attributes 'Implementation-Title': 'Medien', 'Implementation-Version': version - } -} diff --git a/java-ee/MedienImpl/config/checkstyle/checkstyle.xml b/java-ee/MedienImpl/config/checkstyle/checkstyle.xml deleted file mode 100644 index 7c682c3..0000000 --- a/java-ee/MedienImpl/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java-ee/MedienImpl/config/checkstyle/checkstyle.xsl b/java-ee/MedienImpl/config/checkstyle/checkstyle.xsl deleted file mode 100644 index 393a01b..0000000 --- a/java-ee/MedienImpl/config/checkstyle/checkstyle.xsl +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -

CheckStyle Audit

Designed for use with CheckStyle and Ant.
-
- - - -
- - - -
- - - - - -

-

- -


- - - - -
- - - - -

Files

- - - - - - - - - - - - - - -
NameErrors
-
- - - - -

File

- - - - - - - - - - - - - -
Error DescriptionLine
- Back to top -
- - - -

Summary

- - - - - - - - - - - - -
FilesErrors
-
- - - - a - b - - -
- - diff --git a/java-ee/MedienImpl/config/findbugs/findbugs.xml b/java-ee/MedienImpl/config/findbugs/findbugs.xml deleted file mode 100644 index 34a6e01..0000000 --- a/java-ee/MedienImpl/config/findbugs/findbugs.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/java-ee/MedienImpl/src/main/java/com/peetz/medien/dal/package-info.java b/java-ee/MedienImpl/src/main/java/com/peetz/medien/dal/package-info.java deleted file mode 100644 index a144dbc..0000000 --- a/java-ee/MedienImpl/src/main/java/com/peetz/medien/dal/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * - */ -/** - * @author TPEETZ - * - */ -package com.peetz.medien.dal; \ No newline at end of file diff --git a/java-ee/MedienImpl/src/main/java/com/peetz/medien/entity/AudioCDEntity.java b/java-ee/MedienImpl/src/main/java/com/peetz/medien/entity/AudioCDEntity.java deleted file mode 100644 index 63cadc8..0000000 --- a/java-ee/MedienImpl/src/main/java/com/peetz/medien/entity/AudioCDEntity.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.peetz.medien.entity; - -import java.util.Collection; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="AudioCD.findAll", query="SELECT c from AudioCDEntity as c"), - @NamedQuery(name="AudioCD.findByAlbum", query="SELECT c from AudioCDEntity as c WHERE c.album = :album") -}) - -@Entity -@Table(name="AUDIOCD") -public class AudioCDEntity -{ - private Long id; - private String album; - private String artist; - private String category; - private String releaseYear; - private Boolean wantList; - private Collection songs; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getAlbum() { - return album; - } - - public void setAlbum(String album) { - this.album = album; - } - - @Column - public String getArtist() { - return artist; - } - - public void setArtist(String artist) { - this.artist = artist; - } - - @Column - public String getCategory() { - return category; - } - - public void setCategory(String category) { - this.category = category; - } - - @Column - public String getReleaseYear() { - return releaseYear; - } - - public void setReleaseYear(String releaseYear) { - this.releaseYear = releaseYear; - } - - @Column - public Boolean getWantList() { - return wantList; - } - - public void setWantList(Boolean wantList) { - this.wantList = wantList; - } - - @Column - public Collection getSongs() { - return songs; - } - - public void setSongs(Collection songs) { - this.songs = songs; - } -} diff --git a/java-ee/MedienImpl/src/main/java/com/peetz/medien/entity/BoxSetEntity.java b/java-ee/MedienImpl/src/main/java/com/peetz/medien/entity/BoxSetEntity.java deleted file mode 100644 index ad3bba9..0000000 --- a/java-ee/MedienImpl/src/main/java/com/peetz/medien/entity/BoxSetEntity.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.peetz.medien.entity; - -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@Entity -@Table(name="BOXSET") -public class BoxSetEntity -{ - private Long id; - private String title; - private Collection films; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } - - @OneToMany(mappedBy="boxSet", cascade=CascadeType.REMOVE) - public Collection getFilms() { - return films; - } - - public void setFilms(Collection films) { - this.films = films; - } - -} diff --git a/java-ee/MedienImpl/src/main/java/com/peetz/medien/entity/FilmEntity.java b/java-ee/MedienImpl/src/main/java/com/peetz/medien/entity/FilmEntity.java deleted file mode 100644 index 7be93e0..0000000 --- a/java-ee/MedienImpl/src/main/java/com/peetz/medien/entity/FilmEntity.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.peetz.medien.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Film.findAll", query="SELECT f from FilmEntity as f"), - @NamedQuery(name="Film.findByTitle", query="SELECT f from FilmEntity as f WHERE f.title = :title") -}) - -@Entity -@Table(name="FILM") -public class FilmEntity -{ - private Long id; - private String title; - private BoxSetEntity boxSet; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - @ManyToOne - public BoxSetEntity getBoxSet() { - return boxSet; - } - - public void setBoxSet(BoxSetEntity boxSet) { - this.boxSet = boxSet; - } -} diff --git a/java-ee/MedienImpl/src/main/java/com/peetz/medien/entity/package-info.java b/java-ee/MedienImpl/src/main/java/com/peetz/medien/entity/package-info.java deleted file mode 100644 index 803ef9c..0000000 --- a/java-ee/MedienImpl/src/main/java/com/peetz/medien/entity/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * - */ -/** - * @author TPEETZ - * - */ -package com.peetz.medien.entity; \ No newline at end of file diff --git a/java-ee/MedienImpl/src/main/java/com/peetz/medien/service/MedienService.java b/java-ee/MedienImpl/src/main/java/com/peetz/medien/service/MedienService.java deleted file mode 100644 index a1fc92a..0000000 --- a/java-ee/MedienImpl/src/main/java/com/peetz/medien/service/MedienService.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.peetz.medien.service; - -import java.util.Collection; - -import javax.ejb.Local; - -import com.peetz.medien.entity.AudioCDEntity; -import com.peetz.medien.entity.BoxSetEntity; -import com.peetz.medien.entity.FilmEntity; - -@Local -public interface MedienService -{ - public Collection getAllCDs(); - public AudioCDEntity addCD(String title); - public Collection getAllDVDs(); - public FilmEntity addDVD(String title); - public Collection getAllBoxSets(); - public BoxSetEntity addBoxSet(String title); - public BoxSetEntity assignBoxSet(BoxSetEntity boxSet, FilmEntity film); - public void saveCD(AudioCDEntity audioCD); -} diff --git a/java-ee/MedienImpl/src/main/java/com/peetz/medien/service/MedienServiceImpl.java b/java-ee/MedienImpl/src/main/java/com/peetz/medien/service/MedienServiceImpl.java deleted file mode 100644 index 9e08e58..0000000 --- a/java-ee/MedienImpl/src/main/java/com/peetz/medien/service/MedienServiceImpl.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.peetz.medien.service; - -import java.util.Collection; - -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; - -import com.peetz.medien.entity.AudioCDEntity; -import com.peetz.medien.entity.BoxSetEntity; -import com.peetz.medien.entity.FilmEntity; -import java.util.ArrayList; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -@Stateless(name="MedienService") -@TransactionAttribute(TransactionAttributeType.REQUIRED) -public class MedienServiceImpl implements MedienService { - - @PersistenceContext(unitName = "kontor") - private EntityManager em; - - @SuppressWarnings("unchecked") - @Override - public Collection getAllCDs() { - Query query = em.createNamedQuery("AudioCD.findAll"); - ArrayList cdList = new ArrayList(query.getResultList()); - return cdList; - } - - @Override - public AudioCDEntity addCD(String title) { - // TODO Auto-generated method stub - return null; - } - - @SuppressWarnings("unchecked") - @Override - public Collection getAllDVDs() { - Query query = em.createNamedQuery("Film.findAll"); - ArrayList filmList = new ArrayList(query.getResultList()); - return filmList; - } - - @Override - public FilmEntity addDVD(String title) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Collection getAllBoxSets() { - // TODO Auto-generated method stub - return null; - } - - @Override - public BoxSetEntity addBoxSet(String title) { - // TODO Auto-generated method stub - return null; - } - - @Override - public BoxSetEntity assignBoxSet(BoxSetEntity boxSet, FilmEntity film) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void saveCD(AudioCDEntity audioCD) { - // TODO Auto-generated method stub - - } -} diff --git a/java-ee/MedienImpl/src/main/java/com/peetz/medien/service/package-info.java b/java-ee/MedienImpl/src/main/java/com/peetz/medien/service/package-info.java deleted file mode 100644 index ab20de0..0000000 --- a/java-ee/MedienImpl/src/main/java/com/peetz/medien/service/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * - */ -/** - * @author TPEETZ - * - */ -package com.peetz.medien.service; \ No newline at end of file diff --git a/java-ee/MedienWeb/build.gradle b/java-ee/MedienWeb/build.gradle deleted file mode 100644 index 73a53fa..0000000 --- a/java-ee/MedienWeb/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -apply plugin: 'war' - -version = '0.0.1' - -dependencies { - compile project(':MedienImpl') -} diff --git a/java-ee/MedienWeb/src/main/java/com/peetz/medien/view/MedienView.java b/java-ee/MedienWeb/src/main/java/com/peetz/medien/view/MedienView.java deleted file mode 100644 index ef14235..0000000 --- a/java-ee/MedienWeb/src/main/java/com/peetz/medien/view/MedienView.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.peetz.medien.view; - -import com.peetz.medien.service.MedienService; -import java.io.Serializable; -import java.util.logging.Logger; -import javax.ejb.EJB; -import javax.faces.bean.ManagedBean; -import javax.faces.bean.RequestScoped; - -/** - * - * @author TPEETZ - */ -@ManagedBean(name="MedienView") -@RequestScoped -public class MedienView implements Serializable { - - private static final Logger LOG = Logger.getLogger(MedienView.class.getName()); - - @EJB - private MedienService medienService; - - private static final long serialVersionUID = -8261128991042235283L; - - public MedienView() { - LOG.info("MedienView created"); - } - - public Integer getCdNumber() { - return medienService.getAllCDs().size(); - } - - public Integer getDvdNumber() { - return medienService.getAllDVDs().size(); - } -} diff --git a/java-ee/MedienWeb/src/main/webapp/index.jsp b/java-ee/MedienWeb/src/main/webapp/index.jsp deleted file mode 100644 index 3e682f8..0000000 --- a/java-ee/MedienWeb/src/main/webapp/index.jsp +++ /dev/null @@ -1,33 +0,0 @@ - - Medien Application - - - - - - - - - - - - - - - - - - - - - - - -
Medien Manager
test -

Medien Manager

- Show the media list -
 
-

Ingenieurbüro Thomas Peetz

-
- - diff --git a/java-ee/MedienWeb/src/main/webapp/jsp/cdAdd.jsp b/java-ee/MedienWeb/src/main/webapp/jsp/cdAdd.jsp deleted file mode 100644 index f61357f..0000000 --- a/java-ee/MedienWeb/src/main/webapp/jsp/cdAdd.jsp +++ /dev/null @@ -1,75 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Medien Application - - - - - - - - - - - - - - - - - - - - - - - - -
Show CD list
- <% out.println(com.peetz.medien.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - - - - - - - - - -
Category:
Album:
Artist:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/MedienWeb/src/main/webapp/jsp/cdEdit.jsp b/java-ee/MedienWeb/src/main/webapp/jsp/cdEdit.jsp deleted file mode 100644 index f61357f..0000000 --- a/java-ee/MedienWeb/src/main/webapp/jsp/cdEdit.jsp +++ /dev/null @@ -1,75 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Medien Application - - - - - - - - - - - - - - - - - - - - - - - - -
Show CD list
- <% out.println(com.peetz.medien.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - - - - - - - - - -
Category:
Album:
Artist:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/MedienWeb/src/main/webapp/jsp/cdList.jsp b/java-ee/MedienWeb/src/main/webapp/jsp/cdList.jsp deleted file mode 100644 index ad936ab..0000000 --- a/java-ee/MedienWeb/src/main/webapp/jsp/cdList.jsp +++ /dev/null @@ -1,94 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Medien Application - - - - - - - - - - - - - - - - - - - - - - - - -
Show CD list
- <% out.println(com.peetz.medien.navigation.MenuLinks.getInstance().toString()); %> - - - - <%-- set the header --%> - - - - - - - - <%-- check if book exists and display message or iterate over cds --%> - - - - - - - - - <%-- print out the book informations --%> - - - - <%-- print out the edit and delete link for each CD --%> - - - - - - <%-- end interate --%> - - <%-- if cds cannot be found display a text --%> - - - - - - - -
CategoryAlbum titleArtist  
No CDs available
EditDelete
No CDs found.
-
- <%-- add and back to menu button --%> - Add a new CD - -   - Back to menu - - -
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/MedienWeb/src/main/webapp/jsp/dvdAdd.jsp b/java-ee/MedienWeb/src/main/webapp/jsp/dvdAdd.jsp deleted file mode 100644 index e9d6617..0000000 --- a/java-ee/MedienWeb/src/main/webapp/jsp/dvdAdd.jsp +++ /dev/null @@ -1,67 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Medien Application - - - - - - - - - - - - - - - - - - - - - - - - -
Show CD list
- <% out.println(com.peetz.medien.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - -
Film:
- <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/MedienWeb/src/main/webapp/jsp/dvdEdit.jsp b/java-ee/MedienWeb/src/main/webapp/jsp/dvdEdit.jsp deleted file mode 100644 index 9044d68..0000000 --- a/java-ee/MedienWeb/src/main/webapp/jsp/dvdEdit.jsp +++ /dev/null @@ -1,69 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Medien Application - - - - - - - - - - - - - - - - - - - - - - - - -
Show CD list
- <% out.println(com.peetz.medien.navigation.MenuLinks.getInstance().toString()); %> - - <%-- create a html form --%> - - <%-- print out the form data --%> - - - - - - - -
Film:
- <%-- hidden fields for id and userId --%> - - <%-- set the parameter for the dispatch action --%> - - -
- <%-- submit and back button --%> - - Back - -   - Save -
-
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/MedienWeb/src/main/webapp/jsp/dvdList.jsp b/java-ee/MedienWeb/src/main/webapp/jsp/dvdList.jsp deleted file mode 100644 index 6853fcd..0000000 --- a/java-ee/MedienWeb/src/main/webapp/jsp/dvdList.jsp +++ /dev/null @@ -1,90 +0,0 @@ -<%@ page language="java"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> -<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> - - - - - - - - Medien Application - - - - - - - - - - - - - - - - - - - - - - - - -
Show DVD list
- <% out.println(com.peetz.medien.navigation.MenuLinks.getInstance().toString()); %> - - - - <%-- set the header --%> - - - - - - <%-- check if book exists and display message or iterate over books --%> - - - - - - - - - <%-- print out the DVD informations --%> - - <%-- print out the edit and delete link for each DVD --%> - - - - - - <%-- end interate --%> - - <%-- if dvds cannot be found display a text --%> - - - - - - - -
DVD title  
No DVDs available
EditDelete
No DVDs found.
-
- <%-- add and back to menu button --%> - Add a new DVD - -   - Back to menu - - -
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/MedienWeb/src/main/webapp/jsp/index.jsp b/java-ee/MedienWeb/src/main/webapp/jsp/index.jsp deleted file mode 100644 index 2b8b61f..0000000 --- a/java-ee/MedienWeb/src/main/webapp/jsp/index.jsp +++ /dev/null @@ -1,58 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" - pageEncoding="ISO-8859-1"%> -<%@taglib uri="http://java.sun.com/jstl/core" prefix="c"%> -<%@taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %> - - - - - - - - - Medien Application - - - - - - - - - - - - - - - - - - - - - - - - -
Medien Manager (CD, DVD)
- <% out.println(com.peetz.medien.navigation.MenuLinks.getInstance().toString()); %> - -

Medien Manager

-

CD Liste

-

Import CD List

- - - Import CDs - -

DVD Liste

-

Import DVD List

- - - Import DVDs - -
 
-

Ingenieurbüro Thomas Peetz

-
- -
diff --git a/java-ee/README.md b/java-ee/README.md deleted file mode 100644 index 91ce4c6..0000000 --- a/java-ee/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# Kontor Java Enterprise Edition - diff --git a/java-ee/TradingCardsImpl/build.gradle b/java-ee/TradingCardsImpl/build.gradle deleted file mode 100644 index 6e6daf4..0000000 --- a/java-ee/TradingCardsImpl/build.gradle +++ /dev/null @@ -1,5 +0,0 @@ -jar { - manifest { - attributes 'Implementation-Title': 'TradingCards', 'Implementation-Version': version - } -} diff --git a/java-ee/TradingCardsImpl/config/checkstyle/checkstyle.xml b/java-ee/TradingCardsImpl/config/checkstyle/checkstyle.xml deleted file mode 100644 index 7c682c3..0000000 --- a/java-ee/TradingCardsImpl/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java-ee/TradingCardsImpl/config/checkstyle/checkstyle.xsl b/java-ee/TradingCardsImpl/config/checkstyle/checkstyle.xsl deleted file mode 100644 index 393a01b..0000000 --- a/java-ee/TradingCardsImpl/config/checkstyle/checkstyle.xsl +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -

CheckStyle Audit

Designed for use with CheckStyle and Ant.
-
- - - -
- - - -
- - - - - -

-

- -


- - - - -
- - - - -

Files

- - - - - - - - - - - - - - -
NameErrors
-
- - - - -

File

- - - - - - - - - - - - - -
Error DescriptionLine
- Back to top -
- - - -

Summary

- - - - - - - - - - - - -
FilesErrors
-
- - - - a - b - - -
- - diff --git a/java-ee/TradingCardsImpl/config/findbugs/findbugs.xml b/java-ee/TradingCardsImpl/config/findbugs/findbugs.xml deleted file mode 100644 index 34a6e01..0000000 --- a/java-ee/TradingCardsImpl/config/findbugs/findbugs.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/dal/ManufacturerDao.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/dal/ManufacturerDao.java deleted file mode 100644 index e216bb2..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/dal/ManufacturerDao.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package com.peetz.tradingcards.dal; - -import com.peetz.tradingcards.entity.BaseSetEntity; -import com.peetz.tradingcards.entity.ManufacturerEntity; -import java.util.List; -import javax.ejb.Local; - -/** - * - * @author tpeetz - */ -@Local -public interface ManufacturerDao { - public ManufacturerEntity getById(Long id); - - public List findByIds(List ids); - - public List findByName(String name); - - public ManufacturerEntity assignBaseSet(ManufacturerEntity comic, BaseSetEntity baseSet); - - public ManufacturerEntity store(ManufacturerEntity entity); - - public void delete(ManufacturerEntity entity); -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/dal/ManufacturerImpl.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/dal/ManufacturerImpl.java deleted file mode 100644 index a072a99..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/dal/ManufacturerImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package com.peetz.tradingcards.dal; - -import com.peetz.tradingcards.entity.BaseSetEntity; -import com.peetz.tradingcards.entity.ManufacturerEntity; -import java.util.List; -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -/** - * - * @author tpeetz - */ -@Stateless(name = "ManufacturerDao") -@TransactionAttribute(TransactionAttributeType.REQUIRED) -public class ManufacturerImpl implements ManufacturerDao { - - @PersistenceContext(unitName = "kontor") - private EntityManager em; - - @Override - public ManufacturerEntity getById(Long id) { - Query q = em.createNamedQuery("Manufacturer.findById"); - q.setParameter("id", id); - ManufacturerEntity entity = (ManufacturerEntity)q.getSingleResult(); - return entity; - } - - @Override - public List findByIds(List ids) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @SuppressWarnings("unchecked") - @Override - public List findByName(String name) { - Query q = em.createNamedQuery("Manufacturer.findByName"); - q.setParameter("name", name); - List resultList = q.getResultList(); - return resultList; - } - - @Override - public ManufacturerEntity assignBaseSet(ManufacturerEntity comic, BaseSetEntity baseSet) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public ManufacturerEntity store(ManufacturerEntity entity) { - em.persist(entity); - return entity; - } - - @Override - public void delete(ManufacturerEntity entity) { - em.remove(entity); - } -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/dal/SportDao.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/dal/SportDao.java deleted file mode 100644 index badd03c..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/dal/SportDao.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package com.peetz.tradingcards.dal; - -import com.peetz.tradingcards.entity.SportEntity; -import java.util.List; -import javax.ejb.Local; - -/** - * - * @author tpeetz - */ -@Local -public interface SportDao { - public SportEntity getById(Long id); - - public List findByIds(List ids); - - public List findByName(String name); - - public SportEntity store(SportEntity entity); - - public void delete(SportEntity entity); -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/dal/SportImpl.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/dal/SportImpl.java deleted file mode 100644 index 059f52f..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/dal/SportImpl.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package com.peetz.tradingcards.dal; - -import com.peetz.tradingcards.entity.SportEntity; -import java.util.List; -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -/** - * - * @author tpeetz - */ -@Stateless(name = "SportDao") -@TransactionAttribute(TransactionAttributeType.REQUIRED) -public class SportImpl implements SportDao { - - @PersistenceContext(unitName = "kontor") - private EntityManager em; - - @Override - public SportEntity getById(Long id) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public List findByIds(List ids) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @SuppressWarnings("unchecked") - @Override - public List findByName(String name) { - Query query = em.createNamedQuery("Sport.findByName"); - query.setParameter("name", name); - List resultList = query.getResultList(); - return resultList; - } - - @Override - public SportEntity store(SportEntity entity) { - em.persist(entity); - return entity; - } - - @Override - public void delete(SportEntity entity) { - em.remove(entity); - } -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/BaseSetEntity.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/BaseSetEntity.java deleted file mode 100644 index 30a23ac..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/BaseSetEntity.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.peetz.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@Entity -@Table(name="BASESET") -public class BaseSetEntity { - private Long id; - private String name; - private ManufacturerEntity manufacturer; - private Collection parallelSets = new ArrayList(); - private Collection inserts = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @ManyToOne - public ManufacturerEntity getManufacturer() { - return manufacturer; - } - - public void setManufacturer(ManufacturerEntity manufacturer) { - this.manufacturer = manufacturer; - } - - @OneToMany(mappedBy="baseSet", cascade=CascadeType.REMOVE) - public Collection getParallelSets() { - return parallelSets; - } - - public void setParallelSets(Collection parallelSets) { - this.parallelSets = parallelSets; - } - - @OneToMany(mappedBy="baseSet", cascade=CascadeType.REMOVE) - public Collection getInserts() { - return inserts; - } - - public void setInserts(Collection inserts) { - this.inserts = inserts; - } -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/InsertEntity.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/InsertEntity.java deleted file mode 100644 index 7c44c92..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/InsertEntity.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.peetz.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="InsertSet.findAll", query="SELECT i from InsertEntity as i"), - @NamedQuery(name="InsertSet.findById", query="SELECT i from InsertEntity as i WHERE i.id = :id"), - @NamedQuery(name="InsertSet.findByName", query="SELECT i from InsertEntity as i WHERE i.name = :name") -}) - -@Entity -@Table(name="INSERTSET") -public class InsertEntity { - private Long id; - private String name; - private ManufacturerEntity manufacturer; - private BaseSetEntity baseSet; - private Collection sportCard = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @ManyToOne - public ManufacturerEntity getManufacturer() { - return manufacturer; - } - - public void setManufacturer(ManufacturerEntity manufacturer) { - this.manufacturer = manufacturer; - } - - @ManyToOne - public BaseSetEntity getBaseSet() { - return baseSet; - } - - public void setBaseSet(BaseSetEntity baseSet) { - this.baseSet = baseSet; - } - - @OneToMany(mappedBy="insert", cascade=CascadeType.REMOVE) - public Collection getSportCard() { - return sportCard; - } - - public void setSportCard(Collection sportCard) { - this.sportCard = sportCard; - } -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/ManufacturerEntity.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/ManufacturerEntity.java deleted file mode 100644 index 4d73b06..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/ManufacturerEntity.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.peetz.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Manufacturer.findAll", query="SELECT m from ManufacturerEntity as m"), - @NamedQuery(name="Manufacturer.findByName", query="SELECT m from ManufacturerEntity as m WHERE m.name = :name") -}) - -@Entity -@Table(name="MANUFACTURER") -public class ManufacturerEntity { - - private Long id; - private String name; - private Collection baseSets = new ArrayList(); - private Collection parallelSets = new ArrayList(); - private Collection inserts = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @OneToMany(mappedBy="manufacturer", cascade=CascadeType.REMOVE) - public Collection getBaseSets() { - return baseSets; - } - - public void setBaseSets(Collection baseSets) { - this.baseSets = baseSets; - } - - @OneToMany(mappedBy="manufacturer", cascade=CascadeType.REMOVE) - public Collection getParallelSets() { - return parallelSets; - } - - public void setParallelSets(Collection parallelSets) { - this.parallelSets = parallelSets; - } - - @OneToMany(mappedBy="manufacturer", cascade=CascadeType.REMOVE) - public Collection getInserts() { - return inserts; - } - - public void setInserts(Collection inserts) { - this.inserts = inserts; - } -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/ParallelSetEntity.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/ParallelSetEntity.java deleted file mode 100644 index 2057456..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/ParallelSetEntity.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.peetz.tradingcards.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -@Entity -@Table(name="PARALLELSET") -public class ParallelSetEntity { - private Long id; - private String name; - private ManufacturerEntity manufacturer; - - private BaseSetEntity baseSet; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - @ManyToOne - public ManufacturerEntity getManufacturer() { - return manufacturer; - } - - public void setManufacturer(ManufacturerEntity manufacturer) { - this.manufacturer = manufacturer; - } - - public void setName(String name) { - this.name = name; - } - - @ManyToOne - public BaseSetEntity getBaseSet() { - return baseSet; - } - - public void setBaseSet(BaseSetEntity baseSet) { - this.baseSet = baseSet; - } -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/PlayerEntity.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/PlayerEntity.java deleted file mode 100644 index 2d34b16..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/PlayerEntity.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.peetz.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@Entity -@Table(name="PLAYER") -public class PlayerEntity { - private Long id; - private TeamEntity team; - private Collection cards = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @ManyToOne - public TeamEntity getTeam() { - return team; - } - - public void setTeam(TeamEntity team) { - this.team = team; - } - - @OneToMany(mappedBy="player", cascade=CascadeType.REMOVE) - public Collection getCards() { - return cards; - } - - public void setCards(Collection cards) { - this.cards = cards; - } -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/PositionEntity.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/PositionEntity.java deleted file mode 100644 index b4e1a0b..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/PositionEntity.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.peetz.tradingcards.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -@Entity -@Table(name="POSITION") -public class PositionEntity { - - private Long id; - private String name; - private String shortName; - private SportEntity sport; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Column - public String getShortName() { - return shortName; - } - - public void setShortName(String shortName) { - this.shortName = shortName; - } - - @ManyToOne - public SportEntity getSport() { - return sport; - } - - public void setSport(SportEntity sport) { - this.sport = sport; - } -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/SportCardEntity.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/SportCardEntity.java deleted file mode 100644 index fd0e5e4..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/SportCardEntity.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.peetz.tradingcards.entity; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="SportCard.findAll", query="SELECT s from SportCardEntity as s") -}) - -@Entity -@Table(name = "SPORTCARD") -public class SportCardEntity { - private Long id; - private PlayerEntity player; - private BaseSetEntity baseSet; - private ParallelSetEntity parallelSet; - private InsertEntity insert; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @ManyToOne - public PlayerEntity getPlayer() { - return player; - } - - public void setPlayer(PlayerEntity player) { - this.player = player; - } - - @ManyToOne - public BaseSetEntity getBaseSet() { - return baseSet; - } - - public void setBaseSet(BaseSetEntity baseSet) { - this.baseSet = baseSet; - } - - @ManyToOne - public ParallelSetEntity getParallelSet() { - return parallelSet; - } - - public void setParallelSet(ParallelSetEntity parallelSet) { - this.parallelSet = parallelSet; - } - - @ManyToOne - public InsertEntity getInsert() { - return insert; - } - - public void setInsert(InsertEntity insert) { - this.insert = insert; - } - -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/SportEntity.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/SportEntity.java deleted file mode 100644 index 7574a2d..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/SportEntity.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.peetz.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Sport.findAll", query="SELECT s from SportEntity as s"), - @NamedQuery(name="Sport.findByName", query="SELECT s from SportEntity as s WHERE s.name = :name") -}) - -@Entity -@Table(name="SPORT") -public class SportEntity { - - private Long id; - private String name; - private Collection teams = new ArrayList(); - private Collection positions = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @OneToMany(mappedBy="sport", cascade=CascadeType.REMOVE) - public Collection getTeams() { - return teams; - } - - public void setTeams(Collection teams) { - this.teams = teams; - } - - @OneToMany(mappedBy="sport", cascade=CascadeType.REMOVE) - public Collection getPositions() { - return positions; - } - - public void setPositions(Collection positions) { - this.positions = positions; - } -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/TeamEntity.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/TeamEntity.java deleted file mode 100644 index a0863ea..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/entity/TeamEntity.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.peetz.tradingcards.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Team.findAll", query="SELECT t from TeamEntity as t"), - @NamedQuery(name="Team.findByName", query="SELECT t from TeamEntity as t WHERE t.name = :name") -}) - -@Entity -@Table(name="TEAM") -public class TeamEntity { - - private Long id; - private String name; - private SportEntity sport; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { return name; } - - public void setName(String name) { this.name = name; } - - @ManyToOne - public SportEntity getSport() { return sport; } - - public void setSport(SportEntity sport) { this.sport = sport; } -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/SportService.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/SportService.java deleted file mode 100644 index 805101a..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/SportService.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.peetz.tradingcards.service; - -import java.util.Collection; - -import javax.ejb.Local; - -import com.peetz.tradingcards.entity.PositionEntity; -import com.peetz.tradingcards.entity.SportEntity; -import com.peetz.tradingcards.entity.TeamEntity; - -@Local -public interface SportService { - - Collection getAllSports(); - - Collection getAllTeams(); - - void addSport(String name); - - Collection getTeams(SportEntity sport); - - Collection getPositions(SportEntity sport); - -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/SportServiceImpl.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/SportServiceImpl.java deleted file mode 100644 index 1a348ef..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/SportServiceImpl.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.peetz.tradingcards.service; - -import com.peetz.tradingcards.dal.SportDao; -import java.util.Collection; - -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; - -import com.peetz.tradingcards.entity.PositionEntity; -import com.peetz.tradingcards.entity.SportEntity; -import com.peetz.tradingcards.entity.TeamEntity; -import java.util.ArrayList; -import javax.ejb.EJB; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -@Stateless(name="SportService") -@TransactionAttribute(TransactionAttributeType.REQUIRED) -public class SportServiceImpl implements SportService { - - @PersistenceContext(unitName = "kontor") - private EntityManager em; - - @EJB - SportDao sportDao; - - @SuppressWarnings("unchecked") - @Override - public Collection getAllSports() { - Query query = em.createNamedQuery("Sport.findAll"); - ArrayList sportList = new ArrayList(query.getResultList()); - return sportList; - } - - @SuppressWarnings("unchecked") - @Override - public Collection getAllTeams() { - Query query = em.createNamedQuery("Team.findAll"); - ArrayList teamList = new ArrayList(query.getResultList()); - return teamList; - } - - - @Override - public void addSport(String name) { - SportEntity entity = new SportEntity(); - entity.setName(name); - sportDao.store(entity); - } - - @Override - public Collection getTeams(SportEntity sport) { - return null; - } - - @Override - public Collection getPositions(SportEntity sport) { - // TODO Auto-generated method stub - return null; - } -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/TradingcardService.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/TradingcardService.java deleted file mode 100644 index 9d5b0eb..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/TradingcardService.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.peetz.tradingcards.service; - -import java.util.Collection; - -import javax.ejb.Local; - -import com.peetz.tradingcards.entity.BaseSetEntity; -import com.peetz.tradingcards.entity.InsertEntity; -import com.peetz.tradingcards.entity.ManufacturerEntity; -import com.peetz.tradingcards.entity.ParallelSetEntity; -import com.peetz.tradingcards.entity.SportCardEntity; - -@Local -public interface TradingcardService { - - Collection getAllManufacturers(); - - void addManufacturer(String name); - - Collection getAllSportCards(); - - Collection getBaseSetsByManufacturer(ManufacturerEntity manufacturer); - - Collection getParallelSetsByManufacturer(ManufacturerEntity manufacturer); - - Collection getInsertsByManufacturer(ManufacturerEntity manufacturer); - -} diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/TradingcardServiceImpl.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/TradingcardServiceImpl.java deleted file mode 100644 index b8703a4..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/TradingcardServiceImpl.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.peetz.tradingcards.service; - -import com.peetz.tradingcards.dal.ManufacturerDao; -import java.util.Collection; - -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; - -import com.peetz.tradingcards.entity.BaseSetEntity; -import com.peetz.tradingcards.entity.InsertEntity; -import com.peetz.tradingcards.entity.ManufacturerEntity; -import com.peetz.tradingcards.entity.ParallelSetEntity; -import com.peetz.tradingcards.entity.SportCardEntity; -import java.util.ArrayList; -import java.util.List; -import javax.ejb.EJB; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; - -@Stateless(name="TradingcardService") -@TransactionAttribute(TransactionAttributeType.REQUIRED) -public class TradingcardServiceImpl implements TradingcardService { - - @PersistenceContext(unitName = "kontor") - private EntityManager em; - - @EJB - ManufacturerDao manufacturerDao; - - @SuppressWarnings("unchecked") - @Override - public Collection getAllManufacturers() { - Query query = em.createNamedQuery("Manufacturer.findAll"); - ArrayList manufacturerList = new ArrayList(query.getResultList()); - return manufacturerList; - } - - @Override - public void addManufacturer(String name) { - List resultList = manufacturerDao.findByName(name); - if (resultList.isEmpty()) { - ManufacturerEntity manufacturer = new ManufacturerEntity(); - manufacturer.setName(name); - manufacturerDao.store(manufacturer); - } - } - - @SuppressWarnings("unchecked") - @Override - public Collection getAllSportCards() { - Query query = em.createNamedQuery("SportCard.findAll"); - ArrayList sportCardList = new ArrayList(query.getResultList()); - return sportCardList; - } - - @Override - public Collection getBaseSetsByManufacturer(ManufacturerEntity manufacturer) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Collection getParallelSetsByManufacturer(ManufacturerEntity manufacturer) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Collection getInsertsByManufacturer(ManufacturerEntity manufacturer) { - // TODO Auto-generated method stub - return null; - } -} \ No newline at end of file diff --git a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/package-info.java b/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/package-info.java deleted file mode 100644 index f0eb37b..0000000 --- a/java-ee/TradingCardsImpl/src/main/java/com/peetz/tradingcards/service/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * @author TPEETZ - * - */ -package com.peetz.tradingcards.service; \ No newline at end of file diff --git a/java-ee/TradingCardsImpl/src/test/java/com/peetz/tradingcards/dal/ManufacturerImplTest.java b/java-ee/TradingCardsImpl/src/test/java/com/peetz/tradingcards/dal/ManufacturerImplTest.java deleted file mode 100644 index 2e5b5e1..0000000 --- a/java-ee/TradingCardsImpl/src/test/java/com/peetz/tradingcards/dal/ManufacturerImplTest.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package com.peetz.tradingcards.dal; - -import com.peetz.tradingcards.entity.BaseSetEntity; -import com.peetz.tradingcards.entity.ManufacturerEntity; -import java.util.Collection; -import java.util.List; -import javax.ejb.embeddable.EJBContainer; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import static org.junit.Assert.*; - -/** - * - * @author tpeetz - */ -public class ManufacturerImplTest { - - public ManufacturerImplTest() { - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } - - /** - * Test of getById method, of class ManufacturerImpl. - */ - @Test - public void testGetById() throws Exception { - System.out.println("getById"); - Long id = null; - EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer(); - ManufacturerDao instance = (ManufacturerDao)container.getContext().lookup("java:global/main/ManufacturerDao"); - ManufacturerEntity expResult = null; - ManufacturerEntity result = instance.getById(id); - assertEquals(expResult, result); - container.close(); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of findByIds method, of class ManufacturerImpl. - */ - @Test - public void testFindByIds() throws Exception { - System.out.println("findByIds"); - List ids = null; - EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer(); - ManufacturerDao instance = (ManufacturerDao)container.getContext().lookup("java:global/classes/ManufacturerImpl"); - Collection expResult = null; - Collection result = instance.findByIds(ids); - assertEquals(expResult, result); - container.close(); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of findByName method, of class ManufacturerImpl. - */ - @Test - public void testFindByName() throws Exception { - System.out.println("findByName"); - String name = ""; - EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer(); - ManufacturerDao instance = (ManufacturerDao)container.getContext().lookup("java:global/classes/ManufacturerImpl"); - Collection expResult = null; - Collection result = instance.findByName(name); - assertEquals(expResult, result); - container.close(); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of assignBaseSet method, of class ManufacturerImpl. - */ - @Test - public void testAssignBaseSet() throws Exception { - System.out.println("assignBaseSet"); - ManufacturerEntity comic = null; - BaseSetEntity baseSet = null; - EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer(); - ManufacturerDao instance = (ManufacturerDao)container.getContext().lookup("java:global/classes/ManufacturerImpl"); - ManufacturerEntity expResult = null; - ManufacturerEntity result = instance.assignBaseSet(comic, baseSet); - assertEquals(expResult, result); - container.close(); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of store method, of class ManufacturerImpl. - */ - @Test - public void testStore() throws Exception { - System.out.println("store"); - ManufacturerEntity entity = null; - EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer(); - ManufacturerDao instance = (ManufacturerDao)container.getContext().lookup("java:global/classes/ManufacturerImpl"); - ManufacturerEntity expResult = null; - ManufacturerEntity result = instance.store(entity); - assertEquals(expResult, result); - container.close(); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - - /** - * Test of delete method, of class ManufacturerImpl. - */ - @Test - public void testDelete() throws Exception { - System.out.println("delete"); - ManufacturerEntity entity = null; - EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer(); - ManufacturerDao instance = (ManufacturerDao)container.getContext().lookup("java:global/classes/ManufacturerImpl"); - instance.delete(entity); - container.close(); - // TODO review the generated test code and remove the default call to fail. - fail("The test case is a prototype."); - } - -} diff --git a/java-ee/TradingCardsWeb/build.gradle b/java-ee/TradingCardsWeb/build.gradle deleted file mode 100644 index baa6136..0000000 --- a/java-ee/TradingCardsWeb/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -apply plugin: 'war' - -version = '0.0.1' - -dependencies { - compile project(':TradingCardsImpl') -} diff --git a/java-ee/TradingCardsWeb/src/main/java/com/peetz/tradingcards/view/SportView.java b/java-ee/TradingCardsWeb/src/main/java/com/peetz/tradingcards/view/SportView.java deleted file mode 100644 index b95ca0b..0000000 --- a/java-ee/TradingCardsWeb/src/main/java/com/peetz/tradingcards/view/SportView.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.peetz.tradingcards.view; - -import com.peetz.tradingcards.dal.SportDao; -import com.peetz.tradingcards.service.SportService; -import java.io.Serializable; -import java.util.logging.Logger; -import javax.ejb.EJB; -import javax.faces.bean.ManagedBean; -import javax.faces.bean.RequestScoped; - -/** - * - * @author tpeetz - */ -@ManagedBean(name="TradingCardsView") -@RequestScoped -public class SportView implements Serializable { - - private static final long serialVersionUID = 1399103334723066025L; - - private static final Logger LOG = Logger.getLogger(SportView.class.getName()); - - private String name; - - @EJB - private SportService sportService; - - public SportView() { - LOG.info("SportView created"); - } - - public Integer getSportNumber() { - LOG.info("SportView#getSportNumber"); - return sportService.getAllSports().size(); - } - - public Integer getTeamNumber() { - LOG.info("SportView#getTeamNumber"); - return sportService.getAllTeams().size(); - } - - public String getName() { - LOG.info("SportView#getName"); - return name; - } - - public void setName(String name) { - this.name = name; - sportService.addSport(name); - LOG.info("SportView#setName"); - } -} diff --git a/java-ee/TradingCardsWeb/src/main/java/com/peetz/tradingcards/view/TradingCardsView.java b/java-ee/TradingCardsWeb/src/main/java/com/peetz/tradingcards/view/TradingCardsView.java deleted file mode 100644 index e1d5879..0000000 --- a/java-ee/TradingCardsWeb/src/main/java/com/peetz/tradingcards/view/TradingCardsView.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.peetz.tradingcards.view; - -import com.peetz.tradingcards.service.TradingcardService; -import java.io.Serializable; -import java.util.logging.Logger; -import javax.ejb.EJB; -import javax.faces.bean.ManagedBean; -import javax.faces.bean.RequestScoped; - -/** - * - * @author TPEETZ - */ -@ManagedBean(name="TradingCardsView") -@RequestScoped -public class TradingCardsView implements Serializable { - - private static final Logger LOG = Logger.getLogger(TradingCardsView.class.getName()); - - @EJB - private TradingcardService tradingcardService; - - private static final long serialVersionUID = -8261128991042235283L; - - public TradingCardsView() { - LOG.info("TradingCardsView created"); - } - - public Integer getManufacturerNumber() { - return tradingcardService.getAllManufacturers().size(); - } - - public Integer getSportCardNumber() { - return tradingcardService.getAllSportCards().size(); - } -} diff --git a/java-ee/TradingCardsWeb/src/main/webapp/index.jsp b/java-ee/TradingCardsWeb/src/main/webapp/index.jsp deleted file mode 100644 index d085601..0000000 --- a/java-ee/TradingCardsWeb/src/main/webapp/index.jsp +++ /dev/null @@ -1,33 +0,0 @@ - - TradingCards Application - - - - - - - - - - - - - - - - - - - - - - - -
TradingCards Manager
test -

TradingCards Manager

- Show the card list -
 
-

Ingenieurbüro Thomas Peetz

-
- - diff --git a/java-ee/build.gradle b/java-ee/build.gradle deleted file mode 100644 index e8b1bd8..0000000 --- a/java-ee/build.gradle +++ /dev/null @@ -1,69 +0,0 @@ -allprojects { - apply plugin: 'java' - apply plugin: 'build-dashboard' - - repositories { - mavenLocal() - mavenCentral() - } - version = '0.0.1' -} - -repositories { - mavenLocal() - mavenCentral() -} - -group = 'com.ibtp.kontor' - -dependencies { - compile 'org.jboss.spec.javax.faces:jboss-jsf-api_2.2_spec:+' - compile 'org.hibernate.ogm:hibernate-ogm-mongodb:4.2.+' - compile "ch.qos.logback:logback-classic:1.1.3" - compile "org.slf4j:log4j-over-slf4j:1.7.13" - compile "javax:javaee-api:7.0" -} - -subprojects { project -> - if (project.name.endsWith('Impl')) { - apply plugin: 'checkstyle' - apply plugin: 'findbugs' - apply plugin: 'pmd' - apply plugin: 'jacoco' - dependencies { - compile 'org.glassfish.main.ejb:javax.ejb:3.1.2.2' - compile 'org.glassfish.main.transaction:javax.transaction:3.1.2.2' - compile 'org.glassfish:javax.faces:2.1.6' - compile 'org.eclipse.persistence:javax.persistence:2.1.0' - compile 'org.eclipse.persistence:eclipselink:2.5.1' - compile 'org.hibernate:hibernate-core:4.3.8.Final' - compile 'org.hibernate:hibernate-entitymanager:4.3.8.Final' - compile 'org.hsqldb:hsqldb:2.3.0' - compile 'ch.qos.logback:logback-core:1.1.2' - compile 'ch.qos.logback:logback-classic:1.1.2' - testCompile 'org.glassfish.main.extras:glassfish-embedded-all:3.1.2.2' - testCompile group: 'junit', name: 'junit', version: '4.11' - } - tasks.withType(Checkstyle) { - ignoreFailures = true - showViolations = false - reports { - xml.enabled true - } - } - tasks.withType(FindBugs) { - reports { - xml.enabled true - } - } - pmd { - ignoreFailures = true - } - build.dependsOn(['jacocoTestReport']) - } -} - -wrapper { - gradleVersion = '3.3' -} - diff --git a/java-ee/comics.xml b/java-ee/comics.xml deleted file mode 100644 index 730fdeb..0000000 --- a/java-ee/comics.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/java-ee/config/checkstyle/checkstyle.xml b/java-ee/config/checkstyle/checkstyle.xml deleted file mode 100644 index 7c682c3..0000000 --- a/java-ee/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java-ee/config/checkstyle/checkstyle.xsl b/java-ee/config/checkstyle/checkstyle.xsl deleted file mode 100644 index 393a01b..0000000 --- a/java-ee/config/checkstyle/checkstyle.xsl +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -

CheckStyle Audit

Designed for use with CheckStyle and Ant.
-
- - - -
- - - -
- - - - - -

-

- -


- - - - -
- - - - -

Files

- - - - - - - - - - - - - - -
NameErrors
-
- - - - -

File

- - - - - - - - - - - - - -
Error DescriptionLine
- Back to top -
- - - -

Summary

- - - - - - - - - - - - -
FilesErrors
-
- - - - a - b - - -
- - diff --git a/java-ee/config/findbugs/findbugs.xml b/java-ee/config/findbugs/findbugs.xml deleted file mode 100644 index 34a6e01..0000000 --- a/java-ee/config/findbugs/findbugs.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/java-ee/gradle/wrapper/gradle-wrapper.jar b/java-ee/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 8ba921d..0000000 Binary files a/java-ee/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/java-ee/gradle/wrapper/gradle-wrapper.properties b/java-ee/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e054162..0000000 --- a/java-ee/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Sep 17 17:39:14 CEST 2021 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip diff --git a/java-ee/gradlew b/java-ee/gradlew deleted file mode 100755 index 4453cce..0000000 --- a/java-ee/gradlew +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env sh - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -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 - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save ( ) { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/java-ee/gradlew.bat b/java-ee/gradlew.bat deleted file mode 100755 index e95643d..0000000 --- a/java-ee/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java-ee/settings.gradle b/java-ee/settings.gradle deleted file mode 100755 index 50ec7b4..0000000 --- a/java-ee/settings.gradle +++ /dev/null @@ -1,13 +0,0 @@ -include ':KontorEJB' -include ':KontorWeb' -include ':ComicsImpl' -include ':ComicsWeb' -include ':LibraryImpl' -include ':LibraryWeb' -include ':MedienImpl' -include ':MedienWeb' -include ':TradingCardsImpl' -include ':TradingCardsWeb' -include ':KontorImpl' -include ':KontorWeb' -include ':KontorApp' diff --git a/java-quarkus/.gitignore b/java-quarkus/.gitignore deleted file mode 100644 index cec4d77..0000000 --- a/java-quarkus/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -build/ -.settings/ -.gradle/ -.classpath -.project -.vscode/ -bin/ -.idea/ -/.eclipse-pmd diff --git a/java-quarkus/.gitlab-ci.yml b/java-quarkus/.gitlab-ci.yml deleted file mode 100644 index ed4caf6..0000000 --- a/java-quarkus/.gitlab-ci.yml +++ /dev/null @@ -1,38 +0,0 @@ -variables: - GRADLE_OPTS: "-Dorg.gradle.daemon=false" - -before_script: - - source "/home/gitlab-runner/.sdkman/bin/sdkman-init.sh" - - sdk u java 11.0.12-open - - chmod +x ./gradlew - -stages: - - build - - test - - analysis - - publish - -Build Application: - stage: build - script: ./gradlew --build-cache compileJava - -Create Documentation: - stage: build - script: ./gradlew asciidoctorPdf - -Test Application: - stage: test - script: ./gradlew check - -sonarqube-check: - stage: analysis - variables: - SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache - GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task - script: ./gradlew sonarqube - allow_failure: true - -Publish Artifacts: - stage: publish - script: ./gradlew publish - diff --git a/java-quarkus/README.md b/java-quarkus/README.md deleted file mode 100644 index 11ec472..0000000 --- a/java-quarkus/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# kontor-quarkus Project - -This project uses Quarkus, the Supersonic Subatomic Java Framework. - -If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ . - -## Running the application in dev mode - -You can run your application in dev mode that enables live coding using: -```shell script -./gradlew quarkusDev -``` - -> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/. - -## Packaging and running the application - -The application can be packaged using: -```shell script -./gradlew build -``` -It produces the `quarkus-run.jar` file in the `build/quarkus-app/` directory. -Be aware that it’s not an _über-jar_ as the dependencies are copied into the `build/quarkus-app/lib/` directory. - -The application is now runnable using `java -jar build/quarkus-app/quarkus-run.jar`. - -If you want to build an _über-jar_, execute the following command: -```shell script -./gradlew build -Dquarkus.package.type=uber-jar -``` - -The application, packaged as an _über-jar_, is now runnable using `java -jar build/*-runner.jar`. - -## Creating a native executable - -You can create a native executable using: -```shell script -./gradlew build -Dquarkus.package.type=native -``` - -Or, if you don't have GraalVM installed, you can run the native executable build in a container using: -```shell script -./gradlew build -Dquarkus.package.type=native -Dquarkus.native.container-build=true -``` - -You can then execute your native executable with: `./build/kontor-quarkus-1.0.0-SNAPSHOT-runner` - -If you want to learn more about building native executables, please consult https://quarkus.io/guides/gradle-tooling. - -## Related Guides - -- RESTEasy Reactive ([guide](https://quarkus.io/guides/resteasy-reactive)): A JAX-RS implementation utilizing build time processing and Vert.x. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it. - -## Provided Code - -### RESTEasy Reactive - -Easily start your Reactive RESTful Web Services - -[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources) diff --git a/java-quarkus/build.gradle b/java-quarkus/build.gradle deleted file mode 100644 index 57e8102..0000000 --- a/java-quarkus/build.gradle +++ /dev/null @@ -1,158 +0,0 @@ -plugins { - id 'java' - id 'maven-publish' - id 'jacoco' - id 'jacoco-report-aggregation' - id 'pmd' - id 'checkstyle' - id 'jvm-test-suite' - id 'io.quarkus' - id "org.sonarqube" version "3.3" - alias(versionsLibs.plugins.asciidoctorConvert) - alias(versionsLibs.plugins.asciidoctorPdf) - alias(versionsLibs.plugins.asciidoctorGems) -} - -repositories { - ruby.gems() - maven { - url "https://nexus.thpeetz.de/nexus/content/groups/public/" - } - mavenCentral() - mavenLocal() -} - -dependencies { - implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}") - implementation 'io.quarkus:quarkus-resteasy-reactive' - implementation 'io.quarkus:quarkus-resteasy-reactive-jackson' - implementation 'io.quarkus:quarkus-arc' - testImplementation 'io.quarkus:quarkus-junit5' - testImplementation 'io.rest-assured:rest-assured' - testImplementation("io.quarkus:quarkus-jacoco") -} - -final BUILD_DATE = new Date().format('dd.MM.yyyy').toString() -def pdfFile = layout.buildDirectory.file("docs/asciidocPdf/" + project.name + ".pdf") -def pdfArtifact = artifacts.add('archives', pdfFile.get().asFile) { - type 'pdf' - builtBy asciidoctorPdf -} - -tasks.withType(GenerateModuleMetadata).configureEach { - suppressedValidationErrors.add('enforced-platform') -} - -publishing { - publications { - quarkusApp(MavenPublication){ - from components.java - } - docs(MavenPublication) { - groupId = group + '.docs' - artifactId = project.name - artifact pdfArtifact - } - } - repositories { - maven { - name = 'nexusPeetz' - def releasesRepoUrl = "https://nexus.thpeetz.de/nexus/content/repositories/releases/" - def snapshotsRepoUrl = "https://nexus.thpeetz.de/nexus/content/repositories/snapshots/" - url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl - credentials(PasswordCredentials) - } - } -} - -java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 -} - -tasks.withType(GenerateModuleMetadata).configureEach { - suppressedValidationErrors.add('enforced-platform') -} - -compileJava { - options.encoding = 'UTF-8' - options.compilerArgs << '-parameters' -} - -compileTestJava { - options.encoding = 'UTF-8' -} - -jacocoTestReport { - reports { - xml.required = true - } -} - -test.finalizedBy jacocoTestReport - - -pmd { - //ruleSetFiles = files("custom-pmd-ruleset.xml") - ruleSets = ["category/java/errorprone.xml", "category/java/bestpractices.xml"] - ignoreFailures = true -} - -tasks.withType(Checkstyle) { - reports { - xml.required = true - html.required = true - } -} - -testing { - suites { - test { - useJUnitJupiter() - } - } -} - -pmdTest.dependsOn("compileQuarkusTestGeneratedSourcesJava") -checkstyleTest.dependsOn("compileQuarkusTestGeneratedSourcesJava") -jacocoTestReport.dependsOn("compileQuarkusGeneratedSourcesJava") -pmdMain.dependsOn("compileQuarkusGeneratedSourcesJava") - -sonarqube { - properties { - property "sonar.host.url", "https://sonar.thpeetz.de" - property "sonar.qualitygate.wait", true - property "sonar.sourceEncoding", "UTF-8" - property "sonar.projectKey", "kontor_kontor-quarkus_AYQek8Mxz0hBjLSV8I8O" - property "sonar.login", "5ecd90dee57806857e07443a9b0efd3cd7774a81" - } -} - -tasks.named('sonarqube').configure { - dependsOn 'test', 'pmdMain', 'checkstyleMain', 'jacocoTestReport' -} - -asciidoctorPdf { - baseDirFollowsSourceFile() - - asciidoctorj { - attributes 'build-gradle': file('build.gradle'), - 'endpoint-url': 'https://www.thpeetz.de', - 'source-highlighter': 'rouge', - 'imagesdir': './images', - 'toc': 'left', - 'toc-title': 'Inhaltsverzeichnis', - 'revdate': BUILD_DATE, - 'revnumber': { project.version.toString() }, - 'revremark': 'Entwurf', - 'chapter-label': '', - 'icons': 'font', - 'idprefix': 'id_', - 'idseparator': '-', - 'docinfo1': '' - } -} - -wrapper { - gradleVersion = "7.5" -} diff --git a/java-quarkus/config/checkstyle/checkstyle.xml b/java-quarkus/config/checkstyle/checkstyle.xml deleted file mode 100644 index 2574b06..0000000 --- a/java-quarkus/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/java-quarkus/gradle.properties b/java-quarkus/gradle.properties deleted file mode 100644 index c30b39f..0000000 --- a/java-quarkus/gradle.properties +++ /dev/null @@ -1,9 +0,0 @@ -#Gradle properties -group=de.thpeetz.kontor -version=1.0.0-SNAPSHOT - -quarkusPluginId=io.quarkus -quarkusPluginVersion=2.13.2.Final -quarkusPlatformGroupId=io.quarkus.platform -quarkusPlatformArtifactId=quarkus-bom -quarkusPlatformVersion=2.13.2.Final \ No newline at end of file diff --git a/java-quarkus/gradle/wrapper/gradle-wrapper.jar b/java-quarkus/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 62d4c05..0000000 Binary files a/java-quarkus/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/java-quarkus/gradle/wrapper/gradle-wrapper.properties b/java-quarkus/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index ae04661..0000000 --- a/java-quarkus/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/java-quarkus/gradlew b/java-quarkus/gradlew deleted file mode 100644 index fbd7c51..0000000 --- a/java-quarkus/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed 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. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -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 - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/java-quarkus/gradlew.bat b/java-quarkus/gradlew.bat deleted file mode 100644 index a9f778a..0000000 --- a/java-quarkus/gradlew.bat +++ /dev/null @@ -1,104 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem 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, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java-quarkus/settings.gradle b/java-quarkus/settings.gradle deleted file mode 100644 index 0ab2682..0000000 --- a/java-quarkus/settings.gradle +++ /dev/null @@ -1,11 +0,0 @@ -pluginManagement { - repositories { - mavenCentral() - gradlePluginPortal() - mavenLocal() - } - plugins { - id "${quarkusPluginId}" version "${quarkusPluginVersion}" - } -} -rootProject.name='kontor-quarkus' diff --git a/java-quarkus/src/docs/asciidoc/kontor-quarkus.adoc b/java-quarkus/src/docs/asciidoc/kontor-quarkus.adoc deleted file mode 100644 index d5d7ac4..0000000 --- a/java-quarkus/src/docs/asciidoc/kontor-quarkus.adoc +++ /dev/null @@ -1,84 +0,0 @@ -= Projektbeschreibung kontor-quarkus: Pflichtenheft und Projekthandbuch -:author: Thomas Peetz -:email: -:doctype: article -:sectnums: -:sectnumlevels: 4 -:toc: -:toclevels: 4 -:table-caption!: -:counter: table-number: 0 - -//[title="Dokumenthistorie", caption="Tabelle {counter:table-number} ", id="Tabelle-{counter:table-number}", options="header"] -//[title="Dokumenthistorie", id="Table-{counter:table-number}", options="header", cols="4"] -[title="Dokumenthistorie", id="Table-{counter:table-number}", options="header"] -|=== -| Version | Datum | Autor | Änderungsgrund / Bemerkungen -| 0.0.1 | 16.05.2022 | Thomas Peetz | Ersterstellung -|=== - -== Einführung - -=== Zweck - -=== Stakeholder des Systems - -=== Systemumfang - -==== Zielsetzung des Systems - -=== Systemübersicht - -==== Systemkontext - -==== Systemarchitektur - -==== Systemschnittstellen - -===== Realisierte Schnittstellen - -===== Verwendete Schnittstellen - -==== Logisches Datenmodell - -==== Einschränkungen - -== Anforderungen der Domäne - -=== Systemfunktionen - -==== Anwendungsfälle - -==== Akteure - -==== Zielgruppen - -=== Anforderungen - -==== Anforderungen an externe Schnittstellen - -==== Funktionale Anforderungen - -==== Qualitätsanforderungen - -==== Randbedingungen - -==== Weitere Anforderungen - -==== Wartungs- und Supportinformationen - -=== Verifikation - -[bibliography] -== Referenzen - -[glossary] -== Glossar - -== Verzeichnisse - -=== Abbildungsverzeichnis - -=== Tabellenverzeichnis - -<> <> diff --git a/java-quarkus/src/main/docker/Dockerfile.jvm b/java-quarkus/src/main/docker/Dockerfile.jvm deleted file mode 100644 index 476b644..0000000 --- a/java-quarkus/src/main/docker/Dockerfile.jvm +++ /dev/null @@ -1,94 +0,0 @@ -#### -# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode -# -# Before building the container image run: -# -# ./gradlew build -# -# Then, build the image with: -# -# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/kontor-quarkus-jvm . -# -# Then run the container using: -# -# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus-jvm -# -# If you want to include the debug port into your docker image -# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005 -# -# Then run the container using : -# -# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus-jvm -# -# This image uses the `run-java.sh` script to run the application. -# This scripts computes the command line to execute your Java application, and -# includes memory/GC tuning. -# You can configure the behavior using the following environment properties: -# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") -# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options -# in JAVA_OPTS (example: "-Dsome.property=foo") -# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is -# used to calculate a default maximal heap memory based on a containers restriction. -# If used in a container without any memory constraints for the container then this -# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio -# of the container available memory as set here. The default is `50` which means 50% -# of the available memory is used as an upper boundary. You can skip this mechanism by -# setting this value to `0` in which case no `-Xmx` option is added. -# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This -# is used to calculate a default initial heap memory based on the maximum heap memory. -# If used in a container without any memory constraints for the container then this -# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio -# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` -# is used as the initial heap size. You can skip this mechanism by setting this value -# to `0` in which case no `-Xms` option is added (example: "25") -# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. -# This is used to calculate the maximum value of the initial heap memory. If used in -# a container without any memory constraints for the container then this option has -# no effect. If there is a memory constraint then `-Xms` is limited to the value set -# here. The default is 4096MB which means the calculated value of `-Xms` never will -# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") -# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output -# when things are happening. This option, if set to true, will set -# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). -# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: -# true"). -# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). -# - CONTAINER_CORE_LIMIT: A calculated core limit as described in -# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") -# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). -# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. -# (example: "20") -# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. -# (example: "40") -# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. -# (example: "4") -# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus -# previous GC times. (example: "90") -# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") -# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") -# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should -# contain the necessary JRE command-line options to specify the required GC, which -# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). -# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") -# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") -# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be -# accessed directly. (example: "foo.example.com,bar.example.com") -# -### -FROM registry.access.redhat.com/ubi8/openjdk-11:1.14 - -ENV LANGUAGE='en_US:en' - - -# We make four distinct layers so if there are application changes the library layers can be re-used -COPY --chown=185 build/quarkus-app/lib/ /deployments/lib/ -COPY --chown=185 build/quarkus-app/*.jar /deployments/ -COPY --chown=185 build/quarkus-app/app/ /deployments/app/ -COPY --chown=185 build/quarkus-app/quarkus/ /deployments/quarkus/ - -EXPOSE 8080 -USER 185 -ENV AB_JOLOKIA_OFF="" -ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" -ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" - diff --git a/java-quarkus/src/main/docker/Dockerfile.legacy-jar b/java-quarkus/src/main/docker/Dockerfile.legacy-jar deleted file mode 100644 index 8f309c6..0000000 --- a/java-quarkus/src/main/docker/Dockerfile.legacy-jar +++ /dev/null @@ -1,90 +0,0 @@ -#### -# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode -# -# Before building the container image run: -# -# ./gradlew build -Dquarkus.package.type=legacy-jar -# -# Then, build the image with: -# -# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/kontor-quarkus-legacy-jar . -# -# Then run the container using: -# -# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus-legacy-jar -# -# If you want to include the debug port into your docker image -# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005 -# -# Then run the container using : -# -# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus-legacy-jar -# -# This image uses the `run-java.sh` script to run the application. -# This scripts computes the command line to execute your Java application, and -# includes memory/GC tuning. -# You can configure the behavior using the following environment properties: -# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") -# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options -# in JAVA_OPTS (example: "-Dsome.property=foo") -# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is -# used to calculate a default maximal heap memory based on a containers restriction. -# If used in a container without any memory constraints for the container then this -# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio -# of the container available memory as set here. The default is `50` which means 50% -# of the available memory is used as an upper boundary. You can skip this mechanism by -# setting this value to `0` in which case no `-Xmx` option is added. -# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This -# is used to calculate a default initial heap memory based on the maximum heap memory. -# If used in a container without any memory constraints for the container then this -# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio -# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` -# is used as the initial heap size. You can skip this mechanism by setting this value -# to `0` in which case no `-Xms` option is added (example: "25") -# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. -# This is used to calculate the maximum value of the initial heap memory. If used in -# a container without any memory constraints for the container then this option has -# no effect. If there is a memory constraint then `-Xms` is limited to the value set -# here. The default is 4096MB which means the calculated value of `-Xms` never will -# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") -# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output -# when things are happening. This option, if set to true, will set -# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). -# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: -# true"). -# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). -# - CONTAINER_CORE_LIMIT: A calculated core limit as described in -# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") -# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). -# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. -# (example: "20") -# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. -# (example: "40") -# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. -# (example: "4") -# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus -# previous GC times. (example: "90") -# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") -# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") -# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should -# contain the necessary JRE command-line options to specify the required GC, which -# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). -# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") -# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") -# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be -# accessed directly. (example: "foo.example.com,bar.example.com") -# -### -FROM registry.access.redhat.com/ubi8/openjdk-11:1.14 - -ENV LANGUAGE='en_US:en' - - -COPY build/lib/* /deployments/lib/ -COPY build/*-runner.jar /deployments/quarkus-run.jar - -EXPOSE 8080 -USER 185 -ENV AB_JOLOKIA_OFF="" -ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" -ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" diff --git a/java-quarkus/src/main/docker/Dockerfile.native b/java-quarkus/src/main/docker/Dockerfile.native deleted file mode 100644 index d5a28b2..0000000 --- a/java-quarkus/src/main/docker/Dockerfile.native +++ /dev/null @@ -1,27 +0,0 @@ -#### -# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. -# -# Before building the container image run: -# -# ./gradlew build -Dquarkus.package.type=native -# -# Then, build the image with: -# -# docker build -f src/main/docker/Dockerfile.native -t quarkus/kontor-quarkus . -# -# Then run the container using: -# -# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus -# -### -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6 -WORKDIR /work/ -RUN chown 1001 /work \ - && chmod "g+rwX" /work \ - && chown 1001:root /work -COPY --chown=1001:root build/*-runner /work/application - -EXPOSE 8080 -USER 1001 - -CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/java-quarkus/src/main/docker/Dockerfile.native-micro b/java-quarkus/src/main/docker/Dockerfile.native-micro deleted file mode 100644 index 55df6f9..0000000 --- a/java-quarkus/src/main/docker/Dockerfile.native-micro +++ /dev/null @@ -1,30 +0,0 @@ -#### -# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. -# It uses a micro base image, tuned for Quarkus native executables. -# It reduces the size of the resulting container image. -# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. -# -# Before building the container image run: -# -# ./gradlew build -Dquarkus.package.type=native -# -# Then, build the image with: -# -# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/kontor-quarkus . -# -# Then run the container using: -# -# docker run -i --rm -p 8080:8080 quarkus/kontor-quarkus -# -### -FROM quay.io/quarkus/quarkus-micro-image:1.0 -WORKDIR /work/ -RUN chown 1001 /work \ - && chmod "g+rwX" /work \ - && chown 1001:root /work -COPY --chown=1001:root build/*-runner /work/application - -EXPOSE 8080 -USER 1001 - -CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/java-quarkus/src/main/java/de/thpeetz/kontor/comics/ComicsResource.java b/java-quarkus/src/main/java/de/thpeetz/kontor/comics/ComicsResource.java deleted file mode 100644 index f6518b9..0000000 --- a/java-quarkus/src/main/java/de/thpeetz/kontor/comics/ComicsResource.java +++ /dev/null @@ -1,95 +0,0 @@ -package de.thpeetz.kontor.comics; - -import javax.inject.Inject; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import de.thpeetz.kontor.comics.service.ArtistService; -import de.thpeetz.kontor.comics.service.ComicsService; -import de.thpeetz.kontor.comics.service.PublisherService; - -@Path("/kontor/comics") -public class ComicsResource { - - @Inject - transient ComicsService comicsService; - - @Inject - transient ArtistService artistService; - - @Inject - transient PublisherService publisherService; - - @GET - @Produces(MediaType.TEXT_HTML) - @Path("/") - public String showComicList() { - return comicsService.showComicList(); - } - - @GET - @Produces(MediaType.TEXT_HTML) - @Path("/artist") - public String showArtistList() { - return artistService.showArtistList(); - } - - @GET - @Produces(MediaType.APPLICATION_JSON) - @Path("/artist") - public String showArtistListJson() { - return artistService.showArtistList(); - } - - @GET - @Produces(MediaType.TEXT_HTML) - @Path("/artist/view/{artist_id}") - public String showArtist(String artist_id) { - return artistService.showArtist(artist_id); - } - - @GET - @Produces(MediaType.TEXT_HTML) - @Path("/artist/create") - public String showArtistCreation() { - return artistService.showArtistCreation(); - } - - @POST - @Produces(MediaType.TEXT_HTML) - @Path("/artist/create") - public String validateArtistDetails() { - return artistService.validateArtistDetails(); - } - - @GET - @Produces(MediaType.TEXT_HTML) - @Path("/publisher") - public String showPublisherList() { - return publisherService.showPublisherList(); - } - - @GET - @Produces(MediaType.TEXT_HTML) - @Path("/publisher/view/{publisher_id}") - public String showPublisher(String publisher_id) { - return publisherService.showPublisher(publisher_id); - } - - @GET - @Produces(MediaType.TEXT_HTML) - @Path("/publisher/create") - public String showPublisherCreation() { - return publisherService.showPublisherCreation(); - } - - @POST - @Produces(MediaType.TEXT_HTML) - @Path("/publisher/create") - public String validatePublisherDetails() { - return publisherService.validatePublisherDetails(); - } -} diff --git a/java-quarkus/src/main/java/de/thpeetz/kontor/comics/service/ArtistService.java b/java-quarkus/src/main/java/de/thpeetz/kontor/comics/service/ArtistService.java deleted file mode 100644 index cdef9aa..0000000 --- a/java-quarkus/src/main/java/de/thpeetz/kontor/comics/service/ArtistService.java +++ /dev/null @@ -1,28 +0,0 @@ -package de.thpeetz.kontor.comics.service; - -import javax.enterprise.context.ApplicationScoped; - -@ApplicationScoped -public class ArtistService { - - public String showArtistList() { - // TODO Auto-generated method stub - return null; - } - - public String showArtist(String artist_id) { - // TODO Auto-generated method stub - return null; - } - - public String showArtistCreation() { - // TODO Auto-generated method stub - return null; - } - - public String validateArtistDetails() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/java-quarkus/src/main/java/de/thpeetz/kontor/comics/service/ComicsService.java b/java-quarkus/src/main/java/de/thpeetz/kontor/comics/service/ComicsService.java deleted file mode 100644 index ee58e17..0000000 --- a/java-quarkus/src/main/java/de/thpeetz/kontor/comics/service/ComicsService.java +++ /dev/null @@ -1,12 +0,0 @@ -package de.thpeetz.kontor.comics.service; - -import javax.enterprise.context.ApplicationScoped; - -@ApplicationScoped -public class ComicsService { - - public String showComicList() { - return "comics"; - } - -} diff --git a/java-quarkus/src/main/java/de/thpeetz/kontor/comics/service/PublisherService.java b/java-quarkus/src/main/java/de/thpeetz/kontor/comics/service/PublisherService.java deleted file mode 100644 index d3414b1..0000000 --- a/java-quarkus/src/main/java/de/thpeetz/kontor/comics/service/PublisherService.java +++ /dev/null @@ -1,28 +0,0 @@ -package de.thpeetz.kontor.comics.service; - -import javax.enterprise.context.ApplicationScoped; - -@ApplicationScoped -public class PublisherService { - - public String showPublisherList() { - // TODO Auto-generated method stub - return null; - } - - public String showPublisher(String publisher_id) { - // TODO Auto-generated method stub - return null; - } - - public String showPublisherCreation() { - // TODO Auto-generated method stub - return null; - } - - public String validatePublisherDetails() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/java-quarkus/src/main/resources/META-INF/resources/index.html b/java-quarkus/src/main/resources/META-INF/resources/index.html deleted file mode 100644 index 609ae3a..0000000 --- a/java-quarkus/src/main/resources/META-INF/resources/index.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - kontor-quarkus - 1.0.0-SNAPSHOT - - - -
-
-
- - - - - quarkus_logo_horizontal_rgb_1280px_reverse - - - - - - - - - - - - - - - - - - -
-
-
- -
-
-
-

You just made a Quarkus application.

-

This page is served by Quarkus.

- Visit the Dev UI -

This page: src/main/resources/META-INF/resources/index.html

-

App configuration: src/main/resources/application.properties

-

Static assets: src/main/resources/META-INF/resources/

-

Code: src/main/java

-

Generated starter code:

-
    -
  • - RESTEasy Reactive Easily start your Reactive RESTful Web Services -
    @Path: /hello -
    Related guide -
  • - -
-
-
-

Selected extensions

-
    -
  • RESTEasy Reactive (guide)
  • -
  • RESTEasy Reactive Jackson
  • -
-
Documentation
-

Practical step-by-step guides to help you achieve a specific goal. Use them to help get your work - done.

-
Set up your IDE
-

Everyone has a favorite IDE they like to use to code. Learn how to configure yours to maximize your - Quarkus productivity.

-
-
-
- - diff --git a/java-quarkus/src/main/resources/application.properties b/java-quarkus/src/main/resources/application.properties deleted file mode 100644 index 21328a1..0000000 --- a/java-quarkus/src/main/resources/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -# Your configuration properties -quarkus.http.test-port=8083 -quarkus.http.test-ssl-port=8446 diff --git a/java-quarkus/src/native-test/java/de/thpeetz/kontor/comics/ComicsResourceIT.java b/java-quarkus/src/native-test/java/de/thpeetz/kontor/comics/ComicsResourceIT.java deleted file mode 100644 index 230d951..0000000 --- a/java-quarkus/src/native-test/java/de/thpeetz/kontor/comics/ComicsResourceIT.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.thpeetz.kontor.comics; - -import io.quarkus.test.junit.QuarkusIntegrationTest; - -@QuarkusIntegrationTest -public class ComicsResourceIT extends ComicsResourceTest { - -} diff --git a/java-quarkus/src/test/java/de/thpeetz/kontor/comics/ComicsResourceTest.java b/java-quarkus/src/test/java/de/thpeetz/kontor/comics/ComicsResourceTest.java deleted file mode 100644 index 25dcd49..0000000 --- a/java-quarkus/src/test/java/de/thpeetz/kontor/comics/ComicsResourceTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.thpeetz.kontor.comics; - -import org.junit.jupiter.api.Test; -import static io.restassured.RestAssured.given; -import static org.hamcrest.CoreMatchers.is; - -import io.quarkus.test.junit.QuarkusTest; - -@QuarkusTest -class ComicsResourceTest { - - @Test - void testComicsEndpoint() { - given().when().get("/kontor/comics") - .then() - .statusCode(200) - .body(is("comics")); - } -} diff --git a/java/README.md b/java/README.md deleted file mode 100644 index 65ed57c..0000000 --- a/java/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# Kontor Java - diff --git a/java/build.gradle b/java/build.gradle deleted file mode 100644 index 1a683be..0000000 --- a/java/build.gradle +++ /dev/null @@ -1,87 +0,0 @@ -plugins { - id 'application' - id 'jacoco' - id "org.sonarqube" version "3.3" -} - -repositories { - mavenLocal() - mavenCentral() -} - -dependencies { - implementation 'ch.qos.logback:logback-core:1.1.2' - implementation 'ch.qos.logback:logback-classic:1.1.2' - implementation 'org.mongodb.morphia:morphia:1.1.0' - //compile 'org.mongodb:mongodb-driver:3.2.2' - implementation 'org.hibernate:hibernate-core:4.3.8.Final' - implementation 'org.hibernate:hibernate-entitymanager:4.3.8.Final' - implementation 'org.hsqldb:hsqldb:2.3.0' - implementation 'ch.qos.logback:logback-core:1.1.2' - implementation 'ch.qos.logback:logback-classic:1.1.2' - testImplementation("org.junit.jupiter:junit-jupiter:5.8.2") -} - -def MAIN_CLASS_NAME = 'com.ibtp.kontor.KontorApp' - -application { - mainClassName = MAIN_CLASS_NAME -} - -jar { - manifest { - attributes('Implementation-Title': 'Kontor Application', 'Implementation-Version': version, 'Main-Class': MAIN_CLASS_NAME) - } -} - -tasks.named('test') { - useJUnitPlatform() -} - -jacocoTestReport { - reports { - xml.enabled true - } -} - -test.finalizedBy jacocoTestReport - -sonarqube { - properties { - property "sonar.projectKey", "kontor_kontor-java_AX-dd-w3rXuu6JVRvr_g" - property "sonar.host.url", "https://sonar.thpeetz.de" - property "sonar.login", "d39622f640a91f501b1e8a73d7d78c4fc412fc98" - property "sonar.qualitygate.wait", true - property "sonar.sourceEncoding", "UTF-8" - } -} - -tasks.named('sonarqube').configure { - dependsOn test -} - -//tasks.withType(Checkstyle) { -// ignoreFailures = true -// showViolations = false -// configFile = rootProject.file("config/checkstyle/checkstyle.xml") -// reports { -// xml.enabled true -// } -//} - -//tasks.withType(FindBugs) { -// ignoreFailures = true -// reports { -// xml.enabled true -// } -//} - -//pmd { -// ignoreFailures = true -//} - -//build.dependsOn(['jacocoTestReport']) - -wrapper { - gradleVersion = "6.3" -} diff --git a/java/comics.xml b/java/comics.xml deleted file mode 100644 index 730fdeb..0000000 --- a/java/comics.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/java/config/checkstyle/checkstyle.xml b/java/config/checkstyle/checkstyle.xml deleted file mode 100644 index 7c682c3..0000000 --- a/java/config/checkstyle/checkstyle.xml +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java/config/checkstyle/checkstyle.xsl b/java/config/checkstyle/checkstyle.xsl deleted file mode 100644 index 393a01b..0000000 --- a/java/config/checkstyle/checkstyle.xsl +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -

CheckStyle Audit

Designed for use with CheckStyle and Ant.
-
- - - -
- - - -
- - - - - -

-

- -


- - - - -
- - - - -

Files

- - - - - - - - - - - - - - -
NameErrors
-
- - - - -

File

- - - - - - - - - - - - - -
Error DescriptionLine
- Back to top -
- - - -

Summary

- - - - - - - - - - - - -
FilesErrors
-
- - - - a - b - - -
- - diff --git a/java/config/findbugs/findbugs.xml b/java/config/findbugs/findbugs.xml deleted file mode 100644 index 34a6e01..0000000 --- a/java/config/findbugs/findbugs.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/java/gradle.properties b/java/gradle.properties deleted file mode 100644 index 4facf35..0000000 --- a/java/gradle.properties +++ /dev/null @@ -1,2 +0,0 @@ -description = 'Application kontor-java' -version = '1.0.0-SNAPSHOT' diff --git a/java/gradle/wrapper/gradle-wrapper.jar b/java/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index e708b1c..0000000 Binary files a/java/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/java/gradle/wrapper/gradle-wrapper.properties b/java/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index a4b4429..0000000 --- a/java/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/java/gradlew b/java/gradlew deleted file mode 100755 index 4f906e0..0000000 --- a/java/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed 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. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -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 - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/java/gradlew.bat b/java/gradlew.bat deleted file mode 100644 index ac1b06f..0000000 --- a/java/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem 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, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/settings.gradle b/java/settings.gradle deleted file mode 100644 index d7360d1..0000000 --- a/java/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name='kontor-java' diff --git a/java/src/main/java/com/ibtp/kontor/Database.java b/java/src/main/java/com/ibtp/kontor/Database.java deleted file mode 100644 index 8d97843..0000000 --- a/java/src/main/java/com/ibtp/kontor/Database.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.ibtp.kontor; - -import com.mongodb.MongoClient; -import org.mongodb.morphia.Datastore; -import org.mongodb.morphia.Morphia; - -import java.util.HashMap; - -/** - * Created by thomas on 01.03.16. - */ -public class Database { - - private static Database instance = null; - - private HashMap dbMap; - private Morphia morphia; - - private Database() { - dbMap = new HashMap(); - initMorphia(); - } - - private final void initMorphia() { - morphia = new Morphia(); - morphia.mapPackage("com.ibtp.kontor.comics.entity"); - } - - public void registerDatastore(String databaseName) { - if (!dbMap.containsKey(databaseName)) { - Datastore store = morphia.createDatastore(new MongoClient("127.0.0.1"), databaseName); - dbMap.put(databaseName, store); - } - } - - public Datastore getDatastore(String databaseName) { - return dbMap.get(databaseName); - } - - public static Database init() { - if (instance == null) { - instance = new Database(); - } - return instance; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/DumpComics.java b/java/src/main/java/com/ibtp/kontor/DumpComics.java deleted file mode 100644 index 6ee56b1..0000000 --- a/java/src/main/java/com/ibtp/kontor/DumpComics.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.ibtp.kontor; - -import com.ibtp.kontor.comics.entity.Artist; -import com.ibtp.kontor.comics.entity.Comic; -import com.ibtp.kontor.comics.entity.Publisher; -import com.mongodb.MongoClient; -import org.mongodb.morphia.Datastore; -import org.mongodb.morphia.Morphia; -import org.mongodb.morphia.query.Query; - -import java.util.Iterator; -import java.util.List; - -/** - * Created by thomas on 29.02.16. - */ -public class DumpComics { - - public static void main(String[] args) { - final Database database = Database.init(); - database.registerDatastore("kontor"); - database.registerDatastore("comics"); - Datastore kontor = database.getDatastore("kontor"); - Datastore comics = database.getDatastore("comics"); - final Query query = kontor.createQuery(Artist.class); - final List artists = query.asList(); - System.out.println(artists); - for (Artist artist: artists) { - String artistName = artist.getName(); - System.out.println("Artist(" + artist.getId() + ": " + artistName + ")"); - if (comics.createQuery(Artist.class).field("name").equal(artistName).asList().isEmpty()) { - Artist comicsArtist = new Artist(artistName); - comics.save(comicsArtist); - } - } - final List publishers = kontor.createQuery(Publisher.class).asList(); - for (Publisher publisher: publishers) { - String publisherName = publisher.getName(); - System.out.println("Publisher(" + publisher.getId() + ": " + publisherName + ")"); - if (comics.createQuery(Publisher.class).field("name").equal(publisherName).asList().isEmpty()) { - Publisher comicsPublisher = new Publisher(publisherName); - comics.save(comicsPublisher); - } - } - final List comicList = comics.createQuery(Comic.class).asList(); - System.out.println(comicList); - for (Comic comic: comicList ) { - System.out.println(comic); - } - } -} diff --git a/java/src/main/java/com/ibtp/kontor/KontorApp.java b/java/src/main/java/com/ibtp/kontor/KontorApp.java deleted file mode 100644 index b87a849..0000000 --- a/java/src/main/java/com/ibtp/kontor/KontorApp.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ibtp.kontor; - -/** - * Created by TPEETZ on 10.02.2015. - */ -public class KontorApp { - - private KontorGUI mainframe; - - public KontorApp() { - mainframe = new KontorGUI(this); - - mainframe.setVisible(true); - } - - public void exitApplication() { - System.exit(0); - } - - public static void main(String[] args) { - new KontorApp(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/KontorGUI.java b/java/src/main/java/com/ibtp/kontor/KontorGUI.java deleted file mode 100644 index 40a4b2d..0000000 --- a/java/src/main/java/com/ibtp/kontor/KontorGUI.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.ibtp.kontor; - - -import com.ibtp.kontor.comics.view.ComicsMenu; -import com.ibtp.kontor.library.view.LibraryMenu; -import com.ibtp.kontor.tradingcards.view.TradingCardsMenu; - -import javax.swing.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -/** - * Created by TPEETZ on 11.02.2015. - */ -public class KontorGUI extends javax.swing.JFrame { - - KontorApp application; - JMenuBar menuBar; - JMenu menuFile; - JMenuItem menuFileExit; - - JMenuItem menuFileStart = new JMenuItem(); - - JMenu menuHelp; - JMenuItem menuHelpAbout; - - public KontorGUI(KontorApp kontorApp) { - application = kontorApp; - initComponents(); - } - - private void initComponents() { - setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - GroupLayout layout = new GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 400, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 300, Short.MAX_VALUE) - ); - pack(); - setTitle("Kontor Application"); - createMainMenu(); - //createToolBar(); - } - - private void createMainMenu() { - menuBar = new JMenuBar(); - menuFile = new JMenu("File"); - menuFileExit = new JMenuItem("Exit"); - menuHelp = new JMenu("Help"); - menuHelpAbout = new JMenuItem("About"); - setJMenuBar(menuBar); - menuBar.add(menuFile); - menuFile.add(menuFileExit); - menuBar.add(new ComicsMenu()); - menuBar.add(new LibraryMenu()); - menuBar.add(new TradingCardsMenu()); - menuBar.add(menuHelp); - menuHelp.add(menuHelpAbout); - menuFileExit.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - application.exitApplication(); - } - }); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/dal/ArtistDao.java b/java/src/main/java/com/ibtp/kontor/comics/dal/ArtistDao.java deleted file mode 100644 index 00c4b01..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/dal/ArtistDao.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.ArtistEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 16.01.2015. - */ -interface ArtistDao { - - public ArtistEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public Collection findAll(); - - public ArtistEntity addArtist(String name); - - public ArtistEntity store(ArtistEntity entity); - - public void delete(ArtistEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/dal/ArtistImpl.java b/java/src/main/java/com/ibtp/kontor/comics/dal/ArtistImpl.java deleted file mode 100644 index d01b987..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/dal/ArtistImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.ArtistEntity; -import com.ibtp.kontor.dal.BaseImpl; - -import javax.persistence.EntityManager; -import javax.persistence.Query; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 16.01.2015. - */ -public class ArtistImpl extends BaseImpl implements ArtistDao { - - public ArtistImpl() {} - - @Override - public ArtistEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Artist.findById"); - query.setParameter("id", id); - return (ArtistEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Artist.findAll"); - return query.getResultList(); - - } - - @Override - public Collection findByName(String name) { - Query query = getEntityManager().createNamedQuery("Artist.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public ArtistEntity addArtist(String name) { - ArtistEntity artist = new ArtistEntity(name); - artist = store(artist); - return artist; - } - - @Override - public ArtistEntity store(ArtistEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(ArtistEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/dal/ComicDao.java b/java/src/main/java/com/ibtp/kontor/comics/dal/ComicDao.java deleted file mode 100644 index c77fb89..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/dal/ComicDao.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.ComicEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by thomas on 17.01.15. - */ -interface ComicDao { - - public ComicEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByTitle(String title); - - public Collection findAll(); - - public ComicEntity addComic(String title); - - public ComicEntity store(ComicEntity entity); - - public void delete(ComicEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/dal/ComicImpl.java b/java/src/main/java/com/ibtp/kontor/comics/dal/ComicImpl.java deleted file mode 100644 index ecbad88..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/dal/ComicImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.ComicEntity; -import com.ibtp.kontor.dal.BaseImpl; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class ComicImpl extends BaseImpl implements ComicDao { - - @Override - public ComicEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Comic.findById"); - query.setParameter("id", id); - return (ComicEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByTitle(String title) { - Query query = getEntityManager().createNamedQuery("Comic.findByTitle"); - query.setParameter("title", title); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Comic.findAll"); - return query.getResultList(); - } - - @Override - public ComicEntity addComic(String title) { - ComicEntity comicEntity = new ComicEntity(); - comicEntity.setTitle(title); - store(comicEntity); - return comicEntity; - } - - @Override - public ComicEntity store(ComicEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(ComicEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/dal/IssueDao.java b/java/src/main/java/com/ibtp/kontor/comics/dal/IssueDao.java deleted file mode 100644 index 49a5ab2..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/dal/IssueDao.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.IssueEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -interface IssueDao { - public IssueEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByNumber(String number); - - public Collection findAll(); - - public IssueEntity store(IssueEntity entity); - - public void delete(IssueEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/dal/IssueImpl.java b/java/src/main/java/com/ibtp/kontor/comics/dal/IssueImpl.java deleted file mode 100644 index 8f70845..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/dal/IssueImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.IssueEntity; -import com.ibtp.kontor.dal.BaseImpl; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class IssueImpl extends BaseImpl implements IssueDao { - - @Override - public IssueEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Issue.findById"); - query.setParameter("id", id); - return (IssueEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByNumber(String number) { - Query query = getEntityManager().createNamedQuery("Issue.findByNumber"); - query.setParameter("number", number); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Issue.findAll"); - return query.getResultList(); - } - - @Override - public IssueEntity store(IssueEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(IssueEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/dal/PublisherDao.java b/java/src/main/java/com/ibtp/kontor/comics/dal/PublisherDao.java deleted file mode 100644 index 0722522..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/dal/PublisherDao.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.PublisherEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by thomas on 17.01.15. - */ -interface PublisherDao { - - public PublisherEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public Collection findAll(); - - public PublisherEntity addPublisher(String name); - - public PublisherEntity store(PublisherEntity entity); - - public void delete(PublisherEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/dal/PublisherImpl.java b/java/src/main/java/com/ibtp/kontor/comics/dal/PublisherImpl.java deleted file mode 100644 index d911c4d..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/dal/PublisherImpl.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.PublisherEntity; -import com.ibtp.kontor.dal.BaseImpl; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 20.01.2015. - */ -public class PublisherImpl extends BaseImpl implements PublisherDao { - - @Override - public PublisherEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - Query query = getEntityManager().createNamedQuery("Publisher.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Publisher.findAll"); - return query.getResultList(); - } - - @Override - public PublisherEntity addPublisher(String name) { - PublisherEntity publisher = new PublisherEntity(name); - store(publisher); - return publisher; - } - - @Override - public PublisherEntity store(PublisherEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(PublisherEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/dal/StoryArcDao.java b/java/src/main/java/com/ibtp/kontor/comics/dal/StoryArcDao.java deleted file mode 100644 index 40761fe..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/dal/StoryArcDao.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.StoryArcEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -interface StoryArcDao { - - public StoryArcEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByTitle(String title); - - public Collection findAll(); - - public StoryArcEntity store(StoryArcEntity entity); - - public void delete(StoryArcEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/dal/StoryArcImpl.java b/java/src/main/java/com/ibtp/kontor/comics/dal/StoryArcImpl.java deleted file mode 100644 index 3a39271..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/dal/StoryArcImpl.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.StoryArcEntity; -import com.ibtp.kontor.dal.BaseImpl; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class StoryArcImpl extends BaseImpl implements StoryArcDao { - - @Override - public StoryArcEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByTitle(String title) { - Query query = getEntityManager().createNamedQuery("StoryArc.findByTitle"); - query.setParameter("title", title); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("StoryArc.findAll"); - return query.getResultList(); - } - - @Override - public StoryArcEntity store(StoryArcEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(StoryArcEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/dal/VolumeDao.java b/java/src/main/java/com/ibtp/kontor/comics/dal/VolumeDao.java deleted file mode 100644 index 26759bd..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/dal/VolumeDao.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.VolumeEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -interface VolumeDao { - - public VolumeEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByTitle(String title); - - public Collection findAll(); - - public VolumeEntity store(VolumeEntity entity); - - public void delete(VolumeEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/dal/VolumeImpl.java b/java/src/main/java/com/ibtp/kontor/comics/dal/VolumeImpl.java deleted file mode 100644 index bb20a4a..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/dal/VolumeImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.VolumeEntity; -import com.ibtp.kontor.dal.BaseImpl; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class VolumeImpl extends BaseImpl implements VolumeDao { - - @Override - public VolumeEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Volume.findById"); - query.setParameter("id", id); - return (VolumeEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByTitle(String title) { - Query query = getEntityManager().createNamedQuery("Volume.findByTitle"); - query.setParameter("title", title); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Volume.findAll"); - return query.getResultList(); - } - - @Override - public VolumeEntity store(VolumeEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(VolumeEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/Artist.java b/java/src/main/java/com/ibtp/kontor/comics/entity/Artist.java deleted file mode 100644 index a7c09b9..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/Artist.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Property; - -/** - * Created by thomas on 29.02.16. - */ -@Entity("artist") -public class Artist { - - public Artist() {} - - public Artist(String name) { - setName(name); - } - - @Id - private ObjectId id; - - @Property - private String name; - - public ObjectId getId() { - return id; - } - - public void setId(ObjectId id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public String toString() { - return name; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/ArtistEntity.java b/java/src/main/java/com/ibtp/kontor/comics/entity/ArtistEntity.java deleted file mode 100644 index 50ede83..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/ArtistEntity.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Created by TPEETZ on 16.01.2015. - */ -@NamedQueries({ - @NamedQuery(name="Artist.findAll", query="SELECT a from ArtistEntity as a"), - @NamedQuery(name="Artist.findByName", query="SELECT a from ArtistEntity as a WHERE a.name = :name") -}) - -@Entity -@Table(name="ARTIST") -public class ArtistEntity { - - private Long id; - - private String name; - - private Collection writtenIssues = new ArrayList(); - - private Collection inkedIssues = new ArrayList(); - - private Collection penciledIssues = new ArrayList(); - - public ArtistEntity(String name) { - setName(name); - } - - public ArtistEntity() {} - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - String getName() { return name; } - - void setName(String name) { this.name = name; } - - public void setWrittenIssues(Collection writtenIssues) { this.writtenIssues = writtenIssues; } - - @OneToMany(mappedBy="writer", cascade=CascadeType.REMOVE) - public Collection getWrittenIssues() { - return writtenIssues; - } - - public void setInkedIssues(Collection inkedIssues) { this.inkedIssues = inkedIssues; } - - @OneToMany(mappedBy="inker", cascade=CascadeType.REMOVE) - public Collection getInkedIssues() { - return inkedIssues; - } - - public void setPenciledIssues(Collection penciledIssues) { this.penciledIssues = penciledIssues; } - - @OneToMany(mappedBy="penciler", cascade=CascadeType.REMOVE) - public Collection getPenciledIssues() { - return penciledIssues; - } - - @Override - public String toString() { - return "Artist[" + "id=" + getId() + ",name=" + getName() + "]"; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/Comic.java b/java/src/main/java/com/ibtp/kontor/comics/entity/Comic.java deleted file mode 100644 index c6ac7b6..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/Comic.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Property; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by thomas on 01.03.16. - */ -@Entity("comic") -public class Comic { - - @Id - private ObjectId id; - - @Property - private String title; - - @Property - private ObjectId publisher; - - @Property - private Boolean current_order; - - @Property - private Boolean completed; - - @Property - private List issues = new ArrayList(); - - @Property - private List stories = new ArrayList(); - - public ObjectId getId() { - return id; - } - - public void setId(ObjectId id) { - this.id = id; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public ObjectId getPublisher() { - return publisher; - } - - public void setPublisher(ObjectId publisher) { - this.publisher = publisher; - } - - public Boolean getCurrent_order() { - return current_order; - } - - public void setCurrent_order(Boolean current_order) { - this.current_order = current_order; - } - - public Boolean getCompleted() { - return completed; - } - - public void setCompleted(Boolean completed) { - this.completed = completed; - } - - public List getIssues() { - return issues; - } - - public void setIssues(List issues) { - this.issues = issues; - } - - public List getStories() { - return stories; - } - - public void setStories(List stories) { - this.stories = stories; - } - - @Override - public String toString() { - return title + " - " + Publisher.getById(publisher); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/ComicEntity.java b/java/src/main/java/com/ibtp/kontor/comics/entity/ComicEntity.java deleted file mode 100644 index 2d21c10..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/ComicEntity.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Created by thomas on 17.01.15. - */ -@NamedQueries({ - @NamedQuery(name="Comic.findAll", query="SELECT c from ComicEntity as c"), - @NamedQuery(name="Comic.findByTitle", query="SELECT c from ComicEntity as c WHERE c.title = :title") -}) -@Entity -@Table(name = "COMIC") -public class ComicEntity { - - private Long id; - - private String title; - - private Boolean completed; - - private Boolean currentOrder; - - private Collection issues = new ArrayList(); - - private Collection storyArc = new ArrayList(); - - private Collection volumes = new ArrayList(); - - private PublisherEntity publisher; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } - - @Column - public Boolean getCompleted() { return completed; } - - public Boolean isCompleted() { return completed; } - - public void setCompleted(Boolean completed) { this.completed = completed; } - - @Column - public Boolean getCurrentOrder() { return currentOrder; } - - public Boolean isCurrentOrder() { return currentOrder; } - - public void setCurrentOrder(Boolean currentOrder) { this.currentOrder = currentOrder; } - - public void setIssues(Collection issues) { this.issues = issues; } - - @OneToMany(mappedBy="comic", cascade=CascadeType.REMOVE) - public Collection getIssues() { return issues; } - - public void setStoryArc(Collection storyArc) { this.storyArc = storyArc; } - - @OneToMany(mappedBy="comic", cascade=CascadeType.REMOVE) - public Collection getStoryArc() { return storyArc; } - - public void setVolumes(Collection volumes) { this.volumes = volumes; } - - @OneToMany(mappedBy="comic", cascade=CascadeType.REMOVE) - public Collection getVolumes() { return volumes; } - - @ManyToOne - public PublisherEntity getPublisher() { return publisher; } - - public void setPublisher(PublisherEntity publisher) { - this.publisher = publisher; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/Issue.java b/java/src/main/java/com/ibtp/kontor/comics/entity/Issue.java deleted file mode 100644 index 9821134..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/Issue.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Property; - -/** - * Created by thomas on 01.03.16. - */ -public class Issue { - - @Id - private ObjectId id; - - @Property - private String number; - - //@Reference - private Comic comic; - - @Property - private Boolean is_read; - - @Property - private Boolean is_stock; - - public ObjectId getId() { - return id; - } - - public void setId(ObjectId id) { - this.id = id; - } - - public String getNumber() { - return number; - } - - public void setNumber(String number) { - this.number = number; - } - - public Comic getComic() { - return comic; - } - - public void setComic(Comic comic) { - this.comic = comic; - } - - public Boolean getIs_read() { - return is_read; - } - - public void setIs_read(Boolean is_read) { - this.is_read = is_read; - } - - public Boolean getIs_stock() { - return is_stock; - } - - public void setIs_stock(Boolean is_stock) { - this.is_stock = is_stock; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/IssueEntity.java b/java/src/main/java/com/ibtp/kontor/comics/entity/IssueEntity.java deleted file mode 100644 index 93a7662..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/IssueEntity.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import javax.persistence.*; - -/** - * Created by thomas on 18.01.15. - */ -@NamedQueries({ - @NamedQuery(name="Issue.findAll", query="SELECT i from IssueEntity as i"), - @NamedQuery(name="Issue.findByNumber", query="SELECT i from IssueEntity as i WHERE i.number = :number") -}) - -@Entity -@Table(name = "ISSUE") -public class IssueEntity { - - private Long id; - - private String number; - - private Boolean completed; - - private ComicEntity comic; - - private ArtistEntity writer; - - private ArtistEntity inker; - - private ArtistEntity penciler; - - private StoryArcEntity storyArc; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getNumber() { return number; } - - public void setNumber(String number) { this.number = number; } - - @Column - public Boolean getCompleted() { return completed; } - public Boolean isCompleted() { return completed; } - - public void setCompleted(Boolean completed) { this.completed = completed; } - - public void setComic(ComicEntity comic) { this.comic = comic; } - - @ManyToOne - public ComicEntity getComic() { return comic; } - - public void setWriter(ArtistEntity writer) { this.writer = writer; } - - @ManyToOne - public ArtistEntity getWriter() { return writer; } - - public void setInker(ArtistEntity inker) { this.inker = inker; } - - @ManyToOne - public ArtistEntity getInker() { return inker; } - - public void setPenciler(ArtistEntity penciler) { this.penciler = penciler; } - - @ManyToOne - public ArtistEntity getPenciler() { return penciler; } - - public void setStoryArc(StoryArcEntity storyArc) { this.storyArc = storyArc; } - - @ManyToOne - public StoryArcEntity getStoryArc() { return storyArc; } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/Publisher.java b/java/src/main/java/com/ibtp/kontor/comics/entity/Publisher.java deleted file mode 100644 index e147d59..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/Publisher.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import com.ibtp.kontor.Database; -import org.bson.types.ObjectId; -import org.mongodb.morphia.Datastore; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Property; - -import java.util.List; - -/** - * Created by thomas on 01.03.16. - */ -@Entity("publisher") -public class Publisher { - - public Publisher() {} - - public Publisher(String name) { - setName(name); - } - - @Id - private ObjectId id; - - @Property - private String name; - - public ObjectId getId() { - return id; - } - - public void setId(ObjectId id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public String toString() { - return name; - } - - public static Publisher getById(ObjectId publisherId) { - Datastore store = Database.init().getDatastore("comics"); - List results = store.createQuery(Publisher.class).field("id").equal(publisherId).asList(); - if (results.size() > 0) { - return results.get(0); - } else { - return null; - } - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/PublisherEntity.java b/java/src/main/java/com/ibtp/kontor/comics/entity/PublisherEntity.java deleted file mode 100644 index 9aec40e..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/PublisherEntity.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Created by thomas on 17.01.15. - */ -@NamedQueries({ - @NamedQuery(name="Publisher.findAll", query="SELECT p from PublisherEntity as p"), - @NamedQuery(name="Publisher.findByName", query="SELECT p from PublisherEntity as p WHERE p.name = :name") -}) - -@Entity -@Table(name = "PUBLISHER") -public class PublisherEntity { - - private Long id; - - private String name; - - private Collection comic = new ArrayList(); - - public PublisherEntity() {} - - public PublisherEntity(String name) { - setName(name); - } - - @Id - @GeneratedValue(strategy= GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { return name; } - - void setName(String name) { this.name = name; } - - public void setComic(Collection comic) { this.comic = comic; } - - @OneToMany(mappedBy="publisher", cascade=CascadeType.REMOVE) - public Collection getComic() { return comic; } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/StoryArc.java b/java/src/main/java/com/ibtp/kontor/comics/entity/StoryArc.java deleted file mode 100644 index 4a4812b..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/StoryArc.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Property; -import org.mongodb.morphia.annotations.Reference; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by thomas on 01.03.16. - */ -public class StoryArc { - - @Id - private ObjectId id; - - @Property - private String name; - - @Reference - private Comic comic; - - @Reference - private List issues = new ArrayList(); - - public ObjectId getId() { - return id; - } - - public void setId(ObjectId id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Comic getComic() { - return comic; - } - - public void setComic(Comic comic) { - this.comic = comic; - } - - public List getIssues() { - return issues; - } - - public void setIssues(List issues) { - this.issues = issues; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/StoryArcEntity.java b/java/src/main/java/com/ibtp/kontor/comics/entity/StoryArcEntity.java deleted file mode 100644 index e3ea22b..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/StoryArcEntity.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Created by thomas on 17.01.15. - */ -@NamedQueries({ - @NamedQuery(name="StoryArc.findAll", query="SELECT s from StoryArcEntity as s"), - @NamedQuery(name="StoryArc.findByTitle", query="SELECT s from StoryArcEntity as s WHERE s.title = :title") -}) - -@Entity -@Table(name = "STORYARC") -public class StoryArcEntity { - - private Long id; - - private String title; - - private Collection issues = new ArrayList(); - - private ComicEntity comic; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } - - public void setIssues(Collection issues) { this.issues = issues; } - - @OneToMany(mappedBy="storyArc", cascade=CascadeType.REMOVE) - public Collection getIssues() { return issues; } - - public void setComic(ComicEntity comic) { this.comic = comic; } - - @ManyToOne - public ComicEntity getComic() { return comic; } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/TradePaperback.java b/java/src/main/java/com/ibtp/kontor/comics/entity/TradePaperback.java deleted file mode 100644 index 161afd7..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/TradePaperback.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ibtp.kontor.comics.entity; - - -import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Reference; - -/** - * Created by thomas on 01.03.16. - */ -public class TradePaperback { - - @Id - private ObjectId id; - - @Reference - private Comic comic; - - @Reference - private String issue_start; - - @Reference - private String issue_end; - - public ObjectId getId() { - return id; - } - - public void setId(ObjectId id) { - this.id = id; - } - - public Comic getComic() { - return comic; - } - - public void setComic(Comic comic) { - this.comic = comic; - } - - public String getIssue_start() { - return issue_start; - } - - public void setIssue_start(String issue_start) { - this.issue_start = issue_start; - } - - public String getIssue_end() { - return issue_end; - } - - public void setIssue_end(String issue_end) { - this.issue_end = issue_end; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/Volume.java b/java/src/main/java/com/ibtp/kontor/comics/entity/Volume.java deleted file mode 100644 index 7191824..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/Volume.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.ibtp.kontor.comics.entity; - -import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Property; -import org.mongodb.morphia.annotations.Reference; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by thomas on 01.03.16. - */ -public class Volume { - - public Volume() {} - - public Volume(String name) { - setName(name); - } - - @Id - private ObjectId id; - - @Property - private String name; - - @Reference - private Comic comic; - - @Reference - private List issues = new ArrayList(); - - public ObjectId getId() { - return id; - } - - public void setId(ObjectId id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Comic getComic() { - return comic; - } - - public void setComic(Comic comic) { - this.comic = comic; - } - - public List getIssues() { - return issues; - } - - public void setIssues(List issues) { - this.issues = issues; - } - - @Override - public String toString() { - return name; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/entity/VolumeEntity.java b/java/src/main/java/com/ibtp/kontor/comics/entity/VolumeEntity.java deleted file mode 100644 index 6f896ad..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/entity/VolumeEntity.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.ibtp.kontor.comics.entity; - - -import javax.persistence.*; - -/** - * Created by TPEETZ on 19.01.2015. - */ -@NamedQueries({ - @NamedQuery(name="Volume.findAll", query="SELECT v from VolumeEntity as v"), - @NamedQuery(name="Volume.findByTitle", query="SELECT v from VolumeEntity as v WHERE v.title = :title") -}) - -@Entity -@Table(name = "VOLUME") -public class VolumeEntity { - - private Long id; - - private String title; - - private ComicEntity comic; - - @Id - @GeneratedValue(strategy= GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } - - @ManyToOne - public ComicEntity getComic() { return comic; } - - public void setComic(ComicEntity comic) { this.comic = comic; } -} diff --git a/java/src/main/java/com/ibtp/kontor/comics/view/ComicsMenu.java b/java/src/main/java/com/ibtp/kontor/comics/view/ComicsMenu.java deleted file mode 100644 index 5201a11..0000000 --- a/java/src/main/java/com/ibtp/kontor/comics/view/ComicsMenu.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.ibtp.kontor.comics.view; - -import javax.swing.*; - -/** - * Created by tpeetz on 12.02.2015. - */ -public class ComicsMenu extends JMenu { - - public ComicsMenu() { - super("Comics"); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/dal/BaseImpl.java b/java/src/main/java/com/ibtp/kontor/dal/BaseImpl.java deleted file mode 100644 index fa22722..0000000 --- a/java/src/main/java/com/ibtp/kontor/dal/BaseImpl.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.ibtp.kontor.dal; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.persistence.EntityManager; - -/** - * Created by TPEETZ on 16.01.2015. - */ -public class BaseImpl { - - protected BaseImpl() { - Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - logger.info("BaseImpl started"); - } - - protected EntityManager getEntityManager() { - return DatabaseManager.getDatabase().getEntityManager(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/dal/Database.java b/java/src/main/java/com/ibtp/kontor/dal/Database.java deleted file mode 100644 index 67dbda9..0000000 --- a/java/src/main/java/com/ibtp/kontor/dal/Database.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.ibtp.kontor.dal; - -import javax.persistence.EntityManager; - -/** - * Created by TPEETZ on 21.01.2015. - */ -public interface Database { - - public EntityManager getEntityManager(); -} diff --git a/java/src/main/java/com/ibtp/kontor/dal/DatabaseManager.java b/java/src/main/java/com/ibtp/kontor/dal/DatabaseManager.java deleted file mode 100644 index 0ccc25d..0000000 --- a/java/src/main/java/com/ibtp/kontor/dal/DatabaseManager.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ibtp.kontor.dal; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Created by TPEETZ on 22.01.2015. - */ -public class DatabaseManager { - - private static Database database; - private static Logger logger = LoggerFactory.getLogger(DatabaseManager.class.getName()); - - public static Database getDatabase() { - logger.info("return " + database.toString()); - return database; - } - - public static void setDatabase(Database database) { - logger.info("set " + database.toString()); - DatabaseManager.database = database; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/dal/LocalDatabase.java b/java/src/main/java/com/ibtp/kontor/dal/LocalDatabase.java deleted file mode 100644 index e0ec9c1..0000000 --- a/java/src/main/java/com/ibtp/kontor/dal/LocalDatabase.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.ibtp.kontor.dal; - -import org.hibernate.jpa.HibernatePersistenceProvider; -import org.hsqldb.Server; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import javax.persistence.spi.PersistenceProvider; -import javax.persistence.spi.PersistenceProviderResolver; -import javax.persistence.spi.PersistenceProviderResolverHolder; -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -public class LocalDatabase implements Database { - - private static Server server; - private static EntityManagerFactory factory; - private static EntityManager em; - private static Logger logger = LoggerFactory.getLogger(LocalDatabase.class.getName()); - - private LocalDatabase() { - logger.info("LocalDatabase started"); - } - - private static void assureDatabaseRunning() { - if (LocalDatabase.server == null) { - LocalDatabase.startDatabase(); - } - } - - private static void startDatabase() { - Logger logger = LoggerFactory.getLogger(LocalDatabase.class.getName()); - logger.info("startDatabase as kontor in hsqldb_databases/kontor"); - LocalDatabase.server = new Server(); - LocalDatabase.server.setAddress("localhost"); - LocalDatabase.server.setDatabaseName(0, "kontor"); - LocalDatabase.server.setDatabasePath(0, "file:hsqldb_databases/kontor"); - LocalDatabase.server.setPort(2345); - LocalDatabase.server.setTrace(true); - LocalDatabase.server.setLogWriter(new PrintWriter(System.out)); - LocalDatabase.server.start(); - } - - private static void stopDatabase() { - server.shutdown(); - } - - private static EntityManagerFactory getFactory() { - if (LocalDatabase.factory == null) { - LocalDatabase.assureDatabaseRunning(); - PersistenceProviderResolverHolder.setPersistenceProviderResolver(new PersistenceProviderResolver() { - private final List providers_ = Arrays.asList((PersistenceProvider) new HibernatePersistenceProvider()); - - @Override - public void clearCachedProviders() { - // Auto-generated method stub - } - - @Override - public List getPersistenceProviders() { - return providers_; - } - }); - LocalDatabase.factory = Persistence.createEntityManagerFactory("com.ibtp.kontor"); - logger.info("EntityManagerFactory(com.ibtp.kontor) created"); - } - return LocalDatabase.factory; - } - - private static EntityManager getSingleEntityManager() { - return LocalDatabase.em; - } - - private static void setSingleEntityManager(EntityManager manager) { - LocalDatabase.em = manager; - } - - @Override - public EntityManager getEntityManager() { - if (getSingleEntityManager() == null) { - setSingleEntityManager(getFactory().createEntityManager()); - logger.info("EntityManager created"); - } - return getSingleEntityManager(); - } - - @Override - public String toString() { - String serverMessage; - if (LocalDatabase.server == null) { - serverMessage = "server:null"; - } else { - serverMessage = LocalDatabase.server.toString(); - } - return LocalDatabase.class.getName() + " " + serverMessage; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/library/dal/ArticleDao.java b/java/src/main/java/com/ibtp/kontor/library/dal/ArticleDao.java deleted file mode 100644 index f9cd144..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/dal/ArticleDao.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.library.entity.ArticleEntity; - -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -interface ArticleDao { - - public ArticleEntity getById(Long id); - - public List findByIds(List ids); - - public List findAll(); - - public List findByTitle(String title); - - public ArticleEntity store(ArticleEntity entity); - - public void delete(ArticleEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/library/dal/ArticleImpl.java b/java/src/main/java/com/ibtp/kontor/library/dal/ArticleImpl.java deleted file mode 100644 index ada92d9..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/dal/ArticleImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.library.entity.ArticleEntity; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -public class ArticleImpl extends BaseImpl implements ArticleDao { - - @Override - public ArticleEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Article.findById"); - query.setParameter("id", id); - return (ArticleEntity)query.getSingleResult(); - } - - @Override - public List findByIds(List ids) { - return null; - } - - @Override - public List findAll() { - Query query = getEntityManager().createNamedQuery("Article.findAll"); - //noinspection unchecked - return query.getResultList(); - } - - @Override - public List findByTitle(String title) { - Query query = getEntityManager().createNamedQuery("Article.findByTitle"); - query.setParameter("title", title); - //noinspection unchecked - return query.getResultList(); - } - - public ArticleEntity addArticle(String title) { - ArticleEntity entity = new ArticleEntity(title); - store(entity); - return entity; - } - - @Override - public ArticleEntity store(ArticleEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(ArticleEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/library/dal/AuthorDao.java b/java/src/main/java/com/ibtp/kontor/library/dal/AuthorDao.java deleted file mode 100644 index 85f4c83..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/dal/AuthorDao.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.library.entity.AuthorEntity; - -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -interface AuthorDao { - - public AuthorEntity getById(Long id); - - public List findByIds(List ids); - - public List findByName(String name); - - public List findAll(); - - public AuthorEntity addAuthor(String name); - - public AuthorEntity store(AuthorEntity entity); - - public void delete(AuthorEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/library/dal/AuthorImpl.java b/java/src/main/java/com/ibtp/kontor/library/dal/AuthorImpl.java deleted file mode 100644 index 573d7d9..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/dal/AuthorImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.library.entity.AuthorEntity; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.List; - -/** - * Created by thomas on 23.01.15. - */ -public class AuthorImpl extends BaseImpl implements AuthorDao { - - public AuthorImpl() {} - - @Override - public AuthorEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Author.findById"); - query.setParameter("id", id); - return (AuthorEntity)query.getSingleResult(); - } - - @Override - public List findByIds(List ids) { - return null; - } - - @Override - public List findByName(String name) { - Query query = getEntityManager().createNamedQuery("Author.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public List findAll() { - Query query = getEntityManager().createNamedQuery("Author.findAll"); - return query.getResultList(); - } - - @Override - public AuthorEntity addAuthor(String name) { - AuthorEntity author = new AuthorEntity(name); - store(author); - return author; - } - - @Override - public AuthorEntity store(AuthorEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(AuthorEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/library/dal/BookDao.java b/java/src/main/java/com/ibtp/kontor/library/dal/BookDao.java deleted file mode 100644 index d89a1b7..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/dal/BookDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.library.entity.BookEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -interface BookDao { - - public BookEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public BookEntity store(BookEntity entity); - - public void delete(BookEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/library/dal/BookImpl.java b/java/src/main/java/com/ibtp/kontor/library/dal/BookImpl.java deleted file mode 100644 index 63f0ab1..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/dal/BookImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.library.entity.BookEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class BookImpl extends BaseImpl implements BookDao { - - @Override - public BookEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public BookEntity store(BookEntity entity) { - return null; - } - - @Override - public void delete(BookEntity entity) { - - } -} diff --git a/java/src/main/java/com/ibtp/kontor/library/dal/FileDao.java b/java/src/main/java/com/ibtp/kontor/library/dal/FileDao.java deleted file mode 100644 index f123e69..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/dal/FileDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.library.entity.FileEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -interface FileDao { - - public FileEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public FileEntity store(FileEntity entity); - - public void delete(FileEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/library/dal/FileImpl.java b/java/src/main/java/com/ibtp/kontor/library/dal/FileImpl.java deleted file mode 100644 index 1af2900..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/dal/FileImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.library.entity.FileEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class FileImpl extends BaseImpl implements FileDao { - - @Override - public FileEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public FileEntity store(FileEntity entity) { - return null; - } - - @Override - public void delete(FileEntity entity) { - - } -} diff --git a/java/src/main/java/com/ibtp/kontor/library/dal/TitleDao.java b/java/src/main/java/com/ibtp/kontor/library/dal/TitleDao.java deleted file mode 100644 index 81da92b..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/dal/TitleDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.library.entity.TitleEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -interface TitleDao { - - public TitleEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public TitleEntity store(TitleEntity entity); - - public void delete(TitleEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/library/dal/TitleImpl.java b/java/src/main/java/com/ibtp/kontor/library/dal/TitleImpl.java deleted file mode 100644 index 410c2c5..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/dal/TitleImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.library.entity.TitleEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class TitleImpl extends BaseImpl implements TitleDao { - - @Override - public TitleEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public TitleEntity store(TitleEntity entity) { - return null; - } - - @Override - public void delete(TitleEntity entity) { - - } -} diff --git a/java/src/main/java/com/ibtp/kontor/library/entity/ArticleEntity.java b/java/src/main/java/com/ibtp/kontor/library/entity/ArticleEntity.java deleted file mode 100644 index d61eda5..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/entity/ArticleEntity.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ibtp.kontor.library.entity; - -import javax.persistence.*; - -/** - * Created by TPEETZ on 23.01.2015. - */ -@NamedQueries({ - @NamedQuery(name="Article.findAll", query="SELECT a from ArticleEntity as a"), - @NamedQuery(name="Article.findByTitle", query="SELECT a from ArticleEntity as a WHERE a.title = :title") -}) - -@Entity -@Table(name = "ARTICLE") -public class ArticleEntity { - - private Long id; - - private String title; - - private AuthorEntity author; - - public ArticleEntity() {} - - public ArticleEntity(String title) { - setTitle(title); - } - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - @Column - public String getTitle() { - return title; - } - - void setTitle(String title) { - this.title = title; - } - - @ManyToOne - public AuthorEntity getAuthor() { - return author; - } - - public void setAuthor(AuthorEntity author) { - this.author = author; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/library/entity/AuthorEntity.java b/java/src/main/java/com/ibtp/kontor/library/entity/AuthorEntity.java deleted file mode 100644 index 63a6f4b..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/entity/AuthorEntity.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.ibtp.kontor.library.entity; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Created by TPEETZ on 23.01.2015. - */ -@NamedQueries({ - @NamedQuery(name="Author.findAll", query="SELECT a from AuthorEntity as a"), - @NamedQuery(name="Author.findById", query="SELECT a from AuthorEntity as a WHERE a.id = :id"), - @NamedQuery(name="Author.findByName", query="SELECT a from AuthorEntity as a WHERE a.name = :name") -}) -@Entity -@Table(name="AUTHOR") -public class AuthorEntity { - - private Long id; - - private String name; - - private Collection books = new ArrayList(); - - private Collection articles = new ArrayList(); - - public AuthorEntity() {} - - public AuthorEntity(String name) { - setName(name); - } - - @Id - @GeneratedValue(strategy= GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { return name; } - - void setName(String name) { this.name = name; } - - @OneToMany(mappedBy="author", cascade=CascadeType.REMOVE) - public Collection getBooks() { - return books; - } - - public void setBooks(Collection books) { - this.books = books; - } - - @OneToMany(mappedBy="author", cascade=CascadeType.REMOVE) - public Collection getArticles() { - return articles; - } - - public void setArticles(Collection articles) { - this.articles = articles; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/library/entity/BookEntity.java b/java/src/main/java/com/ibtp/kontor/library/entity/BookEntity.java deleted file mode 100644 index b57705c..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/entity/BookEntity.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.ibtp.kontor.library.entity; - -import javax.persistence.*; - -/** - * Created by TPEETZ on 23.01.2015. - */ -@Entity -@Table(name = "BOOK") -public class BookEntity { - - private Long id; - - private String title; - - private AuthorEntity author; - - private String publisher; - - private String isbn; - - private Long page; - - private String edition; - - public BookEntity() {} - - public BookEntity(String title) { - setTitle(title); - } - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - public Long getId() { - return id; - } - - /* unused */ - public void setId(Long id) { - this.id = id; - } - - @Column - public String getTitle() { - return title; - } - - void setTitle(String title) { - this.title = title; - } - - @ManyToOne - public AuthorEntity getAuthor() { - return author; - } - - public void setAuthor(AuthorEntity author) { - this.author = author; - } - - @Column - public String getIsbn() { - return isbn; - } - - public void setIsbn(String isbn) { - this.isbn = isbn; - } - - @Column - public Long getPage() { - return page; - } - - public void setPage(Long page) { - this.page = page; - } - - @Column - public String getEdition() { - return edition; - } - - public void setEdition(String edition) { - this.edition = edition; - } - - @Column - public String getPublisher() { - return publisher; - } - - public void setPublisher(String publisher) { - this.publisher = publisher; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/library/entity/FileEntity.java b/java/src/main/java/com/ibtp/kontor/library/entity/FileEntity.java deleted file mode 100644 index 05f4577..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/entity/FileEntity.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.ibtp.kontor.library.entity; - -import javax.persistence.*; - -/** - * Created by TPEETZ on 23.01.2015. - */ -@Entity -@Table(name = "FILE") -public class FileEntity { - - private Long id; - - private String title; - - public FileEntity() {} - - public FileEntity(String title) { - setTitle(title); - } - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - public Long getId() { - return id; - } - - /* unused */ - public void setId(Long id) { - this.id = id; - } - - @Column - public String getTitle() { - return title; - } - - void setTitle(String title) { - this.title = title; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/library/entity/TitleEntity.java b/java/src/main/java/com/ibtp/kontor/library/entity/TitleEntity.java deleted file mode 100644 index ba25eb9..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/entity/TitleEntity.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.ibtp.kontor.library.entity; - -import javax.persistence.*; - -/** - * Created by TPEETZ on 23.01.2015. - */ -@Entity -@Table(name = "TITLE") -public class TitleEntity { - - private Long id; - - private String title; - - @Id - @GeneratedValue(strategy= GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getTitle() { return title; } - - public void setTitle(String title) { this.title = title; } -} diff --git a/java/src/main/java/com/ibtp/kontor/library/view/LibraryMenu.java b/java/src/main/java/com/ibtp/kontor/library/view/LibraryMenu.java deleted file mode 100644 index 0b97e27..0000000 --- a/java/src/main/java/com/ibtp/kontor/library/view/LibraryMenu.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.ibtp.kontor.library.view; - -import javax.swing.*; - -/** - * Created by tpeetz on 12.02.2015. - */ -public class LibraryMenu extends JMenu { - - public LibraryMenu() { - super("Library"); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/BaseSetDao.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/BaseSetDao.java deleted file mode 100644 index 29692d4..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/BaseSetDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.BaseSetEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -interface BaseSetDao { - - public BaseSetEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public BaseSetEntity store(BaseSetEntity entity); - - public void delete(BaseSetEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/BaseSetImpl.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/BaseSetImpl.java deleted file mode 100644 index 9e584a4..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/BaseSetImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.BaseSetEntity; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class BaseSetImpl extends BaseImpl implements BaseSetDao { - - @Override - public BaseSetEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("BaseSet.findById"); - query.setParameter("id", id); - return (BaseSetEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - Query query = getEntityManager().createNamedQuery("BaseSet.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public BaseSetEntity store(BaseSetEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(BaseSetEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/InsertDao.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/InsertDao.java deleted file mode 100644 index c68790f..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/InsertDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.InsertEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -interface InsertDao { - - public InsertEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public InsertEntity store(InsertEntity entity); - - public void delete(InsertEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/InsertImpl.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/InsertImpl.java deleted file mode 100644 index 598763c..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/InsertImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.InsertEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class InsertImpl extends BaseImpl implements InsertDao { - - @Override - public InsertEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public InsertEntity store(InsertEntity entity) { - return null; - } - - @Override - public void delete(InsertEntity entity) { - - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/ManufacturerDao.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/ManufacturerDao.java deleted file mode 100644 index 451d18b..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/ManufacturerDao.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - - -import com.ibtp.kontor.tradingcards.entity.BaseSetEntity; -import com.ibtp.kontor.tradingcards.entity.ManufacturerEntity; - -import java.util.Collection; -import java.util.List; - -/** - * - * @author tpeetz - */ -interface ManufacturerDao { - - public ManufacturerEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public ManufacturerEntity assignBaseSet(ManufacturerEntity manufacturer, BaseSetEntity baseSet); - - public ManufacturerEntity addManufacturer(String name); - - public ManufacturerEntity store(ManufacturerEntity entity); - - public void delete(ManufacturerEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/ManufacturerImpl.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/ManufacturerImpl.java deleted file mode 100644 index 58c2fd6..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/ManufacturerImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.BaseSetEntity; -import com.ibtp.kontor.tradingcards.entity.ManufacturerEntity; - -import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.Query; - -/** - * - * @author tpeetz - */ -public class ManufacturerImpl extends BaseImpl implements ManufacturerDao { - - @Override - public ManufacturerEntity getById(Long id) { - Query q = getEntityManager().createNamedQuery("Manufacturer.findById"); - q.setParameter("id", id); - return (ManufacturerEntity)q.getSingleResult(); - } - - @Override - public List findByIds(List ids) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @SuppressWarnings("unchecked") - @Override - public List findByName(String name) { - Query q = getEntityManager().createNamedQuery("Manufacturer.findByName"); - q.setParameter("name", name); - return q.getResultList(); - } - - @Override - public ManufacturerEntity assignBaseSet(ManufacturerEntity comic, BaseSetEntity baseSet) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public ManufacturerEntity addManufacturer(String name) { - ManufacturerEntity manufacturer = new ManufacturerEntity(name); - store(manufacturer); - return manufacturer; - } - - @Override - public ManufacturerEntity store(ManufacturerEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(ManufacturerEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/ParallelSetDao.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/ParallelSetDao.java deleted file mode 100644 index c4d36ba..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/ParallelSetDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.ParallelSetEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -interface ParallelSetDao { - - public ParallelSetEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public ParallelSetEntity store(ParallelSetEntity entity); - - public void delete(ParallelSetEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/ParallelSetImpl.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/ParallelSetImpl.java deleted file mode 100644 index cb604a0..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/ParallelSetImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.ParallelSetEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class ParallelSetImpl extends BaseImpl implements ParallelSetDao { - - @Override - public ParallelSetEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public ParallelSetEntity store(ParallelSetEntity entity) { - return null; - } - - @Override - public void delete(ParallelSetEntity entity) { - - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/PlayerDao.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/PlayerDao.java deleted file mode 100644 index 11d045e..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/PlayerDao.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.PlayerEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -interface PlayerDao { - - public PlayerEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public PlayerEntity addPlayer(String name); - - public PlayerEntity store(PlayerEntity entity); - - public void delete(PlayerEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/PlayerImpl.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/PlayerImpl.java deleted file mode 100644 index c3d5104..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/PlayerImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.PlayerEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class PlayerImpl extends BaseImpl implements PlayerDao { - - @Override - public PlayerEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public PlayerEntity addPlayer(String name) { - return null; - } - - @Override - public PlayerEntity store(PlayerEntity entity) { - return null; - } - - @Override - public void delete(PlayerEntity entity) { - - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/PositionDao.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/PositionDao.java deleted file mode 100644 index 9970491..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/PositionDao.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.PositionEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -interface PositionDao { - - public PositionEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public Collection findAll(); - - public PositionEntity addPosition(String name); - - public PositionEntity store(PositionEntity entity); - - public void delete(PositionEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/PositionImpl.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/PositionImpl.java deleted file mode 100644 index e2a22ae..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/PositionImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.PositionEntity; - -import java.util.Collection; -import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.Query; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class PositionImpl extends BaseImpl implements PositionDao { - - @Override - public PositionEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Position.findById"); - query.setParameter("id", id); - return (PositionEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - Query query = getEntityManager().createNamedQuery("Position.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Position.findAll"); - return query.getResultList(); - } - - @Override - public PositionEntity addPosition(String name) { - PositionEntity position = new PositionEntity(name); - store(position); - return position; - } - - @Override - public PositionEntity store(PositionEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(PositionEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/SportCardDao.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/SportCardDao.java deleted file mode 100644 index 25fb244..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/SportCardDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.SportCardEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 27.01.2015. - */ -interface SportCardDao { - - public SportCardEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public SportCardEntity store(SportCardEntity entity); - - public void delete(SportCardEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/SportCardImpl.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/SportCardImpl.java deleted file mode 100644 index 5939d2c..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/SportCardImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.SportCardEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class SportCardImpl extends BaseImpl implements SportCardDao { - - @Override - public SportCardEntity getById(Long id) { - return null; - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - return null; - } - - @Override - public SportCardEntity store(SportCardEntity entity) { - return null; - } - - @Override - public void delete(SportCardEntity entity) { - - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/SportDao.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/SportDao.java deleted file mode 100644 index f5ba51e..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/SportDao.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.SportEntity; - -import java.util.Collection; -import java.util.List; - -/** - * - * @author tpeetz - */ -interface SportDao { - public SportEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public Collection findAll(); - - public SportEntity addSport(String name); - - public SportEntity store(SportEntity entity); - - public void delete(SportEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/SportImpl.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/SportImpl.java deleted file mode 100644 index 223236d..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/SportImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.SportEntity; - -import java.util.Collection; -import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.Query; - -/** - * - * @author tpeetz - */ -public class SportImpl extends BaseImpl implements SportDao { - - @Override - public SportEntity getById(Long id) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public List findByIds(List ids) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @SuppressWarnings("unchecked") - @Override - public List findByName(String name) { - Query query = getEntityManager().createNamedQuery("Sport.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Sport.findAll"); - return query.getResultList(); - } - - @Override - public SportEntity addSport(String name) { - SportEntity sport = new SportEntity(name); - store(sport); - return sport; - } - - @Override - public SportEntity store(SportEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(SportEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/TeamDao.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/TeamDao.java deleted file mode 100644 index c2f9eff..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/TeamDao.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.tradingcards.entity.SportEntity; -import com.ibtp.kontor.tradingcards.entity.TeamEntity; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -interface TeamDao { - public TeamEntity getById(Long id); - - public Collection findByIds(List ids); - - public Collection findByName(String name); - - public Collection findAll(); - - public TeamEntity addTeam(String name, SportEntity sport); - - public TeamEntity store(TeamEntity entity); - - public void delete(TeamEntity entity); -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/TeamImpl.java b/java/src/main/java/com/ibtp/kontor/tradingcards/dal/TeamImpl.java deleted file mode 100644 index 7fb8244..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/dal/TeamImpl.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.BaseImpl; -import com.ibtp.kontor.tradingcards.entity.SportEntity; -import com.ibtp.kontor.tradingcards.entity.TeamEntity; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -public class TeamImpl extends BaseImpl implements TeamDao { - - @Override - public TeamEntity getById(Long id) { - Query query = getEntityManager().createNamedQuery("Team.findById"); - query.setParameter("id", id); - return (TeamEntity)query.getSingleResult(); - } - - @Override - public Collection findByIds(List ids) { - return null; - } - - @Override - public Collection findByName(String name) { - Query query = getEntityManager().createNamedQuery("Team.findByName"); - query.setParameter("name", name); - return query.getResultList(); - } - - @Override - public Collection findAll() { - Query query = getEntityManager().createNamedQuery("Team.findAll"); - return query.getResultList(); - } - - @Override - public TeamEntity addTeam(String name, SportEntity sport) { - TeamEntity team = new TeamEntity(name); - team.setSport(sport); - store(team); - return team; - } - - @Override - public TeamEntity store(TeamEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(entity); - em.getTransaction().commit(); - return entity; - } - - @Override - public void delete(TeamEntity entity) { - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.remove(entity); - em.getTransaction().commit(); - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/BaseSetEntity.java b/java/src/main/java/com/ibtp/kontor/tradingcards/entity/BaseSetEntity.java deleted file mode 100644 index 3111e98..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/BaseSetEntity.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@Entity -@Table(name="BASESET") -public class BaseSetEntity { - private Long id; - private String name; - private ManufacturerEntity manufacturer; - private Collection parallelSets = new ArrayList(); - private Collection inserts = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @ManyToOne - public ManufacturerEntity getManufacturer() { - return manufacturer; - } - - public void setManufacturer(ManufacturerEntity manufacturer) { - this.manufacturer = manufacturer; - } - - @OneToMany(mappedBy="baseSet", cascade=CascadeType.REMOVE) - public Collection getParallelSets() { - return parallelSets; - } - - public void setParallelSets(Collection parallelSets) { - this.parallelSets = parallelSets; - } - - @OneToMany(mappedBy="baseSet", cascade=CascadeType.REMOVE) - public Collection getInserts() { - return inserts; - } - - public void setInserts(Collection inserts) { - this.inserts = inserts; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/InsertEntity.java b/java/src/main/java/com/ibtp/kontor/tradingcards/entity/InsertEntity.java deleted file mode 100644 index ce59037..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/InsertEntity.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="InsertSet.findAll", query="SELECT i from InsertEntity as i"), - @NamedQuery(name="InsertSet.findById", query="SELECT i from InsertEntity as i WHERE i.id = :id"), - @NamedQuery(name="InsertSet.findByName", query="SELECT i from InsertEntity as i WHERE i.name = :name") -}) - -@Entity -@Table(name="INSERTSET") -public class InsertEntity { - private Long id; - private String name; - private ManufacturerEntity manufacturer; - private BaseSetEntity baseSet; - private Collection sportCard = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @ManyToOne - public ManufacturerEntity getManufacturer() { - return manufacturer; - } - - public void setManufacturer(ManufacturerEntity manufacturer) { - this.manufacturer = manufacturer; - } - - @ManyToOne - public BaseSetEntity getBaseSet() { - return baseSet; - } - - public void setBaseSet(BaseSetEntity baseSet) { - this.baseSet = baseSet; - } - - @OneToMany(mappedBy="insert", cascade=CascadeType.REMOVE) - public Collection getSportCard() { - return sportCard; - } - - public void setSportCard(Collection sportCard) { - this.sportCard = sportCard; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/ManufacturerEntity.java b/java/src/main/java/com/ibtp/kontor/tradingcards/entity/ManufacturerEntity.java deleted file mode 100644 index f83da2a..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/ManufacturerEntity.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Manufacturer.findAll", query="SELECT m from ManufacturerEntity as m"), - @NamedQuery(name="Manufacturer.findByName", query="SELECT m from ManufacturerEntity as m WHERE m.name = :name") -}) - -@Entity -@Table(name="MANUFACTURER") -public class ManufacturerEntity { - - private Long id; - private String name; - private Collection baseSets = new ArrayList(); - private Collection parallelSets = new ArrayList(); - private Collection inserts = new ArrayList(); - - public ManufacturerEntity(String name) { - setName(name); - } - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - void setName(String name) { - this.name = name; - } - - @OneToMany(mappedBy="manufacturer", cascade=CascadeType.REMOVE) - public Collection getBaseSets() { - return baseSets; - } - - public void setBaseSets(Collection baseSets) { - this.baseSets = baseSets; - } - - @OneToMany(mappedBy="manufacturer", cascade=CascadeType.REMOVE) - public Collection getParallelSets() { - return parallelSets; - } - - public void setParallelSets(Collection parallelSets) { - this.parallelSets = parallelSets; - } - - @OneToMany(mappedBy="manufacturer", cascade=CascadeType.REMOVE) - public Collection getInserts() { - return inserts; - } - - public void setInserts(Collection inserts) { - this.inserts = inserts; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/ParallelSetEntity.java b/java/src/main/java/com/ibtp/kontor/tradingcards/entity/ParallelSetEntity.java deleted file mode 100644 index 0ce0c69..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/ParallelSetEntity.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -@Entity -@Table(name="PARALLELSET") -public class ParallelSetEntity { - private Long id; - private String name; - private ManufacturerEntity manufacturer; - - private BaseSetEntity baseSet; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - @ManyToOne - public ManufacturerEntity getManufacturer() { - return manufacturer; - } - - public void setManufacturer(ManufacturerEntity manufacturer) { - this.manufacturer = manufacturer; - } - - public void setName(String name) { - this.name = name; - } - - @ManyToOne - public BaseSetEntity getBaseSet() { - return baseSet; - } - - public void setBaseSet(BaseSetEntity baseSet) { - this.baseSet = baseSet; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/PlayerEntity.java b/java/src/main/java/com/ibtp/kontor/tradingcards/entity/PlayerEntity.java deleted file mode 100644 index 7c19d70..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/PlayerEntity.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@Entity -@Table(name="PLAYER") -public class PlayerEntity { - private Long id; - private TeamEntity team; - private Collection cards = new ArrayList(); - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @ManyToOne - public TeamEntity getTeam() { - return team; - } - - public void setTeam(TeamEntity team) { - this.team = team; - } - - @OneToMany(mappedBy="player", cascade=CascadeType.REMOVE) - public Collection getCards() { - return cards; - } - - public void setCards(Collection cards) { - this.cards = cards; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/PositionEntity.java b/java/src/main/java/com/ibtp/kontor/tradingcards/entity/PositionEntity.java deleted file mode 100644 index 0e5c6b8..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/PositionEntity.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQuery; -import javax.persistence.NamedQueries; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Position.findAll", query="SELECT p from PositionEntity as p"), - @NamedQuery(name="Position.findByName", query="SELECT p from PositionEntity as p WHERE p.name = :name") -}) - -@Entity -@Table(name="POSITION") -public class PositionEntity { - - private Long id; - private String name; - private String shortName; - private SportEntity sport; - - public PositionEntity() {} - - public PositionEntity(String name) { - setName(name); - } - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Column - public String getShortName() { - return shortName; - } - - public void setShortName(String shortName) { - this.shortName = shortName; - } - - @ManyToOne - public SportEntity getSport() { - return sport; - } - - public void setSport(SportEntity sport) { - this.sport = sport; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/SportCardEntity.java b/java/src/main/java/com/ibtp/kontor/tradingcards/entity/SportCardEntity.java deleted file mode 100644 index f71f722..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/SportCardEntity.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="SportCard.findAll", query="SELECT s from SportCardEntity as s") -}) - -@Entity -@Table(name = "SPORTCARD") -public class SportCardEntity { - private Long id; - private PlayerEntity player; - private BaseSetEntity baseSet; - private ParallelSetEntity parallelSet; - private InsertEntity insert; - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @ManyToOne - public PlayerEntity getPlayer() { - return player; - } - - public void setPlayer(PlayerEntity player) { - this.player = player; - } - - @ManyToOne - public BaseSetEntity getBaseSet() { - return baseSet; - } - - public void setBaseSet(BaseSetEntity baseSet) { - this.baseSet = baseSet; - } - - @ManyToOne - public ParallelSetEntity getParallelSet() { - return parallelSet; - } - - public void setParallelSet(ParallelSetEntity parallelSet) { - this.parallelSet = parallelSet; - } - - @ManyToOne - public InsertEntity getInsert() { - return insert; - } - - public void setInsert(InsertEntity insert) { - this.insert = insert; - } - -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/SportEntity.java b/java/src/main/java/com/ibtp/kontor/tradingcards/entity/SportEntity.java deleted file mode 100644 index 8e2258e..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/SportEntity.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import java.util.ArrayList; -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Sport.findAll", query="SELECT s from SportEntity as s"), - @NamedQuery(name="Sport.findByName", query="SELECT s from SportEntity as s WHERE s.name = :name") -}) - -@Entity -@Table(name="SPORT") -public class SportEntity { - - private Long id; - private String name; - private Collection teams = new ArrayList(); - private Collection positions = new ArrayList(); - - public SportEntity() {} - - public SportEntity(String name) { - setName(name); - } - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - String getName() { - return name; - } - - void setName(String name) { - this.name = name; - } - - @OneToMany(mappedBy="sport", cascade=CascadeType.REMOVE) - public Collection getTeams() { - return teams; - } - - public void setTeams(Collection teams) { - this.teams = teams; - } - - @OneToMany(mappedBy="sport", cascade=CascadeType.REMOVE) - public Collection getPositions() { - return positions; - } - - public void setPositions(Collection positions) { - this.positions = positions; - } - - @Override - public String toString() { - return "Sport[" + "id=" + getId() + ",name=" + getName() + "]"; - } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/TeamEntity.java b/java/src/main/java/com/ibtp/kontor/tradingcards/entity/TeamEntity.java deleted file mode 100644 index 8dbcb77..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/entity/TeamEntity.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.ibtp.kontor.tradingcards.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.Table; - -@NamedQueries({ - @NamedQuery(name="Team.findAll", query="SELECT t from TeamEntity as t"), - @NamedQuery(name="Team.findByName", query="SELECT t from TeamEntity as t WHERE t.name = :name") -}) - -@Entity -@Table(name="TEAM") -public class TeamEntity { - - private Long id; - private String name; - private SportEntity sport; - - public TeamEntity() {} - - public TeamEntity(String name) { - setName(name); - } - - @Id - @GeneratedValue(strategy=GenerationType.AUTO) - public Long getId() { return id; } - - @SuppressWarnings("unused") - private void setId(Long id) { this.id = id; } - - @Column - public String getName() { return name; } - - void setName(String name) { this.name = name; } - - @ManyToOne - public SportEntity getSport() { return sport; } - - public void setSport(SportEntity sport) { this.sport = sport; } -} diff --git a/java/src/main/java/com/ibtp/kontor/tradingcards/view/TradingCardsMenu.java b/java/src/main/java/com/ibtp/kontor/tradingcards/view/TradingCardsMenu.java deleted file mode 100644 index f124056..0000000 --- a/java/src/main/java/com/ibtp/kontor/tradingcards/view/TradingCardsMenu.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.ibtp.kontor.tradingcards.view; - -import javax.swing.*; - -/** - * Created by TPEETZ on 13.02.2015. - */ -public class TradingCardsMenu extends JMenu { - - public TradingCardsMenu() { - super("TradingCards"); - } -} diff --git a/java/src/main/resources/META-INF/persistence.xml b/java/src/main/resources/META-INF/persistence.xml deleted file mode 100644 index 35d671b..0000000 --- a/java/src/main/resources/META-INF/persistence.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - org.hibernate.jpa.HibernatePersistenceProvider - com.ibtp.kontor.comics.entity.ArtistEntity - com.ibtp.kontor.comics.entity.ComicEntity - com.ibtp.kontor.comics.entity.IssueEntity - com.ibtp.kontor.comics.entity.StoryArcEntity - com.ibtp.kontor.comics.entity.VolumeEntity - com.ibtp.kontor.comics.entity.PublisherEntity - com.ibtp.kontor.library.entity.AuthorEntity - com.ibtp.kontor.library.entity.ArticleEntity - com.ibtp.kontor.library.entity.BookEntity - com.ibtp.kontor.library.entity.FileEntity - com.ibtp.kontor.library.entity.TitleEntity - com.ibtp.kontor.tradingcards.entity.SportEntity - com.ibtp.kontor.tradingcards.entity.TeamEntity - com.ibtp.kontor.tradingcards.entity.PositionEntity - com.ibtp.kontor.tradingcards.entity.PlayerEntity - com.ibtp.kontor.tradingcards.entity.ManufacturerEntity - com.ibtp.kontor.tradingcards.entity.BaseSetEntity - com.ibtp.kontor.tradingcards.entity.InsertEntity - com.ibtp.kontor.tradingcards.entity.ParallelSetEntity - com.ibtp.kontor.tradingcards.entity.SportCardEntity - - - - - - - - - - - - - diff --git a/java/src/main/resources/logback.xml b/java/src/main/resources/logback.xml deleted file mode 100644 index e8cff02..0000000 --- a/java/src/main/resources/logback.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - %d{yyyy-MM-dd_HH:mm:ss.SSS} %-5level %logger{36} - %msg%n - - - - - - c:/kontor.log - - %d{yyyy-MM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - c:/kontor.%i.log.zip - 1 - 10 - - - - 2MB - - - - - - - - - - - - - diff --git a/java/src/test/java/com/ibtp/kontor/comics/CollectionTest.java b/java/src/test/java/com/ibtp/kontor/comics/CollectionTest.java deleted file mode 100644 index 57d01a3..0000000 --- a/java/src/test/java/com/ibtp/kontor/comics/CollectionTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.ibtp.kontor.comics; - -import com.ibtp.kontor.comics.dal.PublisherImpl; -import com.ibtp.kontor.comics.entity.PublisherEntity; -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Collection; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class CollectionTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @AfterAll - public static void cleanup() { - PublisherImpl publisherImpl = new PublisherImpl(); - Collection publisherEntities = publisherImpl.findAll(); - for (PublisherEntity publisherEntity : publisherEntities) { - publisherImpl.delete(publisherEntity); - } - } - - @Test - public void testAddPublishers() { - String publisherName = "Bongo Comics"; - PublisherImpl publisherImpl = new PublisherImpl(); - publisherImpl.addPublisher(publisherName); - publisherImpl.addPublisher("Marvel"); - Collection publisherList = publisherImpl.findAll(); - assertEquals(2, publisherList.size()); - } -} diff --git a/java/src/test/java/com/ibtp/kontor/comics/dal/ArtistImplTest.java b/java/src/test/java/com/ibtp/kontor/comics/dal/ArtistImplTest.java deleted file mode 100644 index e78e77f..0000000 --- a/java/src/test/java/com/ibtp/kontor/comics/dal/ArtistImplTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.ArtistEntity; -import com.ibtp.kontor.dal.*; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.Collection; - -public class ArtistImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - tearDown(); - } - - @AfterAll - public static void tearDown() { - ArtistImpl artistImpl = new ArtistImpl(); - Collection artistList = artistImpl.findAll(); - for (ArtistEntity artistEntity : artistList) { - artistImpl.delete(artistEntity); - } - } - - @Test - public void testArtistAddAndDelete() { - String artistName = "testArtistAddAndDelete"; - ArtistImpl artistImpl = new ArtistImpl(); - artistImpl.addArtist(artistName); - Collection resultList = artistImpl.findByName(artistName); - assertNotNull(resultList); - assertTrue(resultList.size() > 0); - ArtistEntity artist = (ArtistEntity)(resultList.toArray()[0]); - artistImpl.delete(artist); - resultList = artistImpl.findByName(artistName); - assertNotNull(resultList); - assertEquals(0, resultList.size()); - } - - @Test - public void testArtistFindAll() { - ArtistImpl artistImpl = new ArtistImpl(); - Collection artistList = artistImpl.findAll(); - assertNotNull(artistList); - assertEquals(0, artistList.size()); - artistImpl.addArtist("testArtistFindAll1"); - artistImpl.addArtist("testArtistFindAll2"); - artistImpl.addArtist("testArtistFindAll3"); - artistList = artistImpl.findAll(); - assertNotNull(artistList); - assertEquals(3, artistList.size()); - for (ArtistEntity artistEntity : artistList) { - artistImpl.delete(artistEntity); - } - } -} diff --git a/java/src/test/java/com/ibtp/kontor/comics/dal/ComicImplTest.java b/java/src/test/java/com/ibtp/kontor/comics/dal/ComicImplTest.java deleted file mode 100644 index 76f2d00..0000000 --- a/java/src/test/java/com/ibtp/kontor/comics/dal/ComicImplTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.ComicEntity; -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.Collection; -import java.util.Iterator; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class ComicImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testComicAddAndDelete() { - String comicTitle = "Comic1"; - ComicImpl comicImpl = new ComicImpl(); - comicImpl.addComic(comicTitle); - Collection comicList = comicImpl.findByTitle(comicTitle); - assertNotNull(comicList); - assertEquals(1, comicList.size()); - comicImpl.delete((ComicEntity) comicList.toArray()[0]); - comicList = comicImpl.findByTitle(comicTitle); - assertNotNull(comicList); - assertEquals(0, comicList.size()); - } - - @Test - public void testComicFindAll() { - ComicImpl comicImpl = new ComicImpl(); - comicImpl.addComic("Comic1"); - comicImpl.addComic("Comic2"); - comicImpl.addComic("Comic3"); - Collection comicList = comicImpl.findAll(); - assertNotNull(comicList); - assertEquals(3, comicList.size()); - for (Iterator iterator = comicList.iterator(); iterator.hasNext(); ) { - ComicEntity next = iterator.next(); - comicImpl.delete(next); - } - comicList = comicImpl.findAll(); - assertNotNull(comicList); - assertEquals(0, comicList.size()); - } -} diff --git a/java/src/test/java/com/ibtp/kontor/comics/dal/IssueImplTest.java b/java/src/test/java/com/ibtp/kontor/comics/dal/IssueImplTest.java deleted file mode 100644 index 5797305..0000000 --- a/java/src/test/java/com/ibtp/kontor/comics/dal/IssueImplTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.IssueEntity; -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.Collection; -import java.util.Iterator; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class IssueImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testIssueAddAndDelete() { - String issueNumber = "42"; - IssueImpl issueImpl = new IssueImpl(); - IssueEntity issue = new IssueEntity(); - issue.setNumber(issueNumber); - issueImpl.store(issue); - Collection issueList = issueImpl.findByNumber(issueNumber); - assertNotNull(issueList); - assertEquals(1, issueList.size()); - issueImpl.delete(issue); - issueList = issueImpl.findByNumber(issueNumber); - assertNotNull(issueList); - assertEquals(0, issueList.size()); - } - - @Test - public void testIssueFindAll() { - IssueImpl issueImpl = new IssueImpl(); - IssueEntity issue1 = new IssueEntity(); - issue1.setNumber("issue1"); - IssueEntity issue2 = new IssueEntity(); - issue1.setNumber("issue2"); - IssueEntity issue3 = new IssueEntity(); - issue1.setNumber("issue3"); - issueImpl.store(issue1); - issueImpl.store(issue2); - issueImpl.store(issue3); - Collection issueList = issueImpl.findAll(); - assertNotNull(issueList); - assertEquals(3, issueList.size()); - for (IssueEntity issueEntity : issueList) { - issueImpl.delete(issueEntity); - } - issueList = issueImpl.findAll(); - assertNotNull(issueList); - assertEquals(0, issueList.size()); - } -} diff --git a/java/src/test/java/com/ibtp/kontor/comics/dal/PublisherImplTest.java b/java/src/test/java/com/ibtp/kontor/comics/dal/PublisherImplTest.java deleted file mode 100644 index b795e96..0000000 --- a/java/src/test/java/com/ibtp/kontor/comics/dal/PublisherImplTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.PublisherEntity; -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Collection; -import java.util.Iterator; - -/** - * Created by TPEETZ on 20.01.2015. - */ -public class PublisherImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @AfterEach - public void cleanUp() { - PublisherImpl publisherImpl = new PublisherImpl(); - Collection publisherList = publisherImpl.findAll(); - for (PublisherEntity publisherEntity : publisherList) { - publisherImpl.delete(publisherEntity); - } - } - - @Test - public void testPublisherAddAndDelete() { - String publisherName = "testPublisherAddAndDelete"; - PublisherImpl publisherImpl = new PublisherImpl(); - PublisherEntity publisher = publisherImpl.addPublisher(publisherName); - Collection publisherList = publisherImpl.findByName(publisherName); - assertEquals(1, publisherList.size()); - publisherImpl.delete(publisher); - publisherList = publisherImpl.findByName(publisherName); - assertEquals(0, publisherList.size()); - } - - @Test - public void testPublisherFindAll() { - PublisherImpl publisherImpl = new PublisherImpl(); - publisherImpl.addPublisher("testDeletePublisher1"); - publisherImpl.addPublisher("testDeletePublisher2"); - publisherImpl.addPublisher("testDeletePublisher3"); - Collection publisherList = publisherImpl.findAll(); - assertEquals(3, publisherList.size()); - } -} diff --git a/java/src/test/java/com/ibtp/kontor/comics/dal/StoryArcImplTest.java b/java/src/test/java/com/ibtp/kontor/comics/dal/StoryArcImplTest.java deleted file mode 100644 index 2768e32..0000000 --- a/java/src/test/java/com/ibtp/kontor/comics/dal/StoryArcImplTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.StoryArcEntity; -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.Collection; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class StoryArcImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - StoryArcImpl storyArcImpl = new StoryArcImpl(); - Collection storyArcEntityCollection = storyArcImpl.findAll(); - for (StoryArcEntity storyArcEntity : storyArcEntityCollection) { - storyArcImpl.delete(storyArcEntity); - } - } - - @Test - public void testStoryArcAddAndDelete() { - String storyArcTtitle = "testStoryArcAddAndDelete"; - StoryArcImpl storyArcImpl = new StoryArcImpl(); - StoryArcEntity storyArc = new StoryArcEntity(); - storyArc.setTitle(storyArcTtitle); - storyArcImpl.store(storyArc); - Collection storyArcEntityCollection = storyArcImpl.findByTitle(storyArcTtitle); - assertNotNull(storyArcEntityCollection); - assertEquals(1, storyArcEntityCollection.size()); - storyArcImpl.delete(storyArc); - storyArcEntityCollection = storyArcImpl.findByTitle(storyArcTtitle); - assertNotNull(storyArcEntityCollection); - assertEquals(0, storyArcEntityCollection.size()); - } - - @Test - public void testStoryArcFindAll() { - StoryArcImpl storyArcImpl = new StoryArcImpl(); - StoryArcEntity storyArc; - storyArc = new StoryArcEntity(); - storyArc.setTitle("testStoryArcFindAll1"); - storyArcImpl.store(storyArc); - storyArc = new StoryArcEntity(); - storyArc.setTitle("testStoryArcFindAll2"); - storyArcImpl.store(storyArc); - storyArc = new StoryArcEntity(); - storyArc.setTitle("testStoryArcFindAll3"); - storyArcImpl.store(storyArc); - Collection storyArcEntityCollection = storyArcImpl.findAll(); - assertNotNull(storyArcEntityCollection); - assertEquals(3, storyArcEntityCollection.size()); - } -} diff --git a/java/src/test/java/com/ibtp/kontor/comics/dal/VolumeImplTest.java b/java/src/test/java/com/ibtp/kontor/comics/dal/VolumeImplTest.java deleted file mode 100644 index fd34aa4..0000000 --- a/java/src/test/java/com/ibtp/kontor/comics/dal/VolumeImplTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.ibtp.kontor.comics.dal; - -import com.ibtp.kontor.comics.entity.VolumeEntity; -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.Collection; -import java.util.Iterator; - -/** - * Created by TPEETZ on 28.01.2015. - */ -public class VolumeImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @AfterEach - public void cleanUp() { - VolumeImpl volumeImpl = new VolumeImpl(); - Collection volumeList = volumeImpl.findAll(); - for (VolumeEntity volumeEntity : volumeList) { - volumeImpl.delete(volumeEntity); - } - } - - @Test - public void testVolumeAddAndDelete() { - String volumeTitle = "testVolumeAddAndDelete"; - VolumeImpl volumeImpl = new VolumeImpl(); - VolumeEntity volume = new VolumeEntity(); - volume.setTitle(volumeTitle); - VolumeEntity volumeEntity = volumeImpl.store(volume); - assertNotNull(volumeEntity); - assertEquals(volumeTitle, volumeEntity.getTitle()); - Collection volumeList = volumeImpl.findByTitle(volumeTitle); - assertNotNull(volumeList); - assertEquals(1, volumeList.size()); - VolumeEntity result = (VolumeEntity)volumeList.toArray()[0]; - assertEquals(volume, result); - volumeImpl.delete(result); - volumeList = volumeImpl.findByTitle(volumeTitle); - assertEquals(0, volumeList.size()); - } - - @Test - public void testVolumeFindAll() { - VolumeImpl volumeImpl = new VolumeImpl(); - VolumeEntity volume; - volume = new VolumeEntity(); - volume.setTitle("testVolumeFindAll1"); - volumeImpl.store(volume); - volume = new VolumeEntity(); - volume.setTitle("testVolumeFindAll2"); - volumeImpl.store(volume); - volume = new VolumeEntity(); - volume.setTitle("testVolumeFindAll3"); - volumeImpl.store(volume); - Collection volumeList = volumeImpl.findAll(); - assertNotNull(volumeList); - assertEquals(3, volumeList.size()); - } -} diff --git a/java/src/test/java/com/ibtp/kontor/dal/DataAccessLayerTest.java b/java/src/test/java/com/ibtp/kontor/dal/DataAccessLayerTest.java deleted file mode 100644 index a9737ac..0000000 --- a/java/src/test/java/com/ibtp/kontor/dal/DataAccessLayerTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.ibtp.kontor.dal; - -import static org.junit.jupiter.api.Assertions.fail; - -import java.lang.reflect.Method; - -import org.junit.jupiter.api.Test; - -/** - * Created by TPEETZ on 10.02.2015. - */ -public class DataAccessLayerTest { - - public void findTests(String packageName, String entityName) { - String testClassName = packageName + entityName + "ImplTest"; - Class testClass; - try { - testClass = Class.forName(testClassName); - Method addAndDelete = testClass.getMethod("test" + entityName + "AddAndDelete"); - Method findAll = testClass.getMethod("test" + entityName + "FindAll"); - } catch (ClassNotFoundException e) { - fail("Class " + testClassName + " missing"); - } catch (NoSuchMethodException e) { - fail("Test method for class " + testClassName + " missing"); - } - } - - @Test - public void testFindComicTests() { - /* - * Find all Tests - */ - String[] testClasses = new String[]{"Artist", "Comic", "Issue", "Publisher", "StoryArc", "Volume"}; - for (int i = 0; i < testClasses.length; i++) { - String testEntity = testClasses[i]; - findTests("com.ibtp.kontor.comics.dal.", testEntity); - } - } - - @Test - public void testFindLibraryTests() { - /* - * Find all Tests - */ - String[] testClasses = new String[]{"Article", "Author", "Book", "File", "Title"}; - for (int i = 0; i < testClasses.length; i++) { - String testEntity = testClasses[i]; - findTests("com.ibtp.kontor.library.dal.", testEntity); - } - } - - @Test - public void testFindTradingCardsTests() { - /* - * Find all Tests - */ - String[] testClasses = new String[]{"BaseSet", "Insert", "Manufacturer", "ParallelSet", "Player", "Position", "SportCard", "Sport", "Team"}; - for (int i = 0; i < testClasses.length; i++) { - String testEntity = testClasses[i]; - findTests("com.ibtp.kontor.tradingcards.dal." , testEntity); - } - } -} diff --git a/java/src/test/java/com/ibtp/kontor/library/BookshelfTest.java b/java/src/test/java/com/ibtp/kontor/library/BookshelfTest.java deleted file mode 100644 index f6609fb..0000000 --- a/java/src/test/java/com/ibtp/kontor/library/BookshelfTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ibtp.kontor.library; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class BookshelfTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testAddAuthors() { - - } -} diff --git a/java/src/test/java/com/ibtp/kontor/library/dal/ArticleImplTest.java b/java/src/test/java/com/ibtp/kontor/library/dal/ArticleImplTest.java deleted file mode 100644 index 3fc8772..0000000 --- a/java/src/test/java/com/ibtp/kontor/library/dal/ArticleImplTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import com.ibtp.kontor.library.entity.ArticleEntity; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.Collection; -import java.util.List; - -/** - * Created by tpeetz on 23.01.2015. - */ -public class ArticleImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - cleanUp(); - } - - @AfterAll - public static void cleanUp() { - ArticleImpl articleImpl = new ArticleImpl(); - Collection articleList = articleImpl.findAll(); - for (ArticleEntity articleEntity : articleList) { - articleImpl.delete(articleEntity); - } - } - - @Test - public void testAddArticle() { - String articleTitle = "testAddArticle"; - ArticleImpl articleImpl = new ArticleImpl(); - ArticleEntity article = articleImpl.addArticle(articleTitle); - assertNotNull(article); - List articleList = articleImpl.findByTitle(articleTitle); - assertEquals(1, articleList.size()); - } - - @Test - public void testArticleAddAndDelete() { - - } - - @Test - public void testArticleFindAll() { - - } -} diff --git a/java/src/test/java/com/ibtp/kontor/library/dal/AuthorImplTest.java b/java/src/test/java/com/ibtp/kontor/library/dal/AuthorImplTest.java deleted file mode 100644 index cec2048..0000000 --- a/java/src/test/java/com/ibtp/kontor/library/dal/AuthorImplTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import com.ibtp.kontor.library.entity.AuthorEntity; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; - -/** - * Created by thomas on 23.01.15. - */ -public class AuthorImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testAddAuthor() { - String authorName = "testAddAuthor"; - AuthorImpl authorImpl = new AuthorImpl(); - AuthorEntity author = authorImpl.addAuthor(authorName); - assertNotNull(author); - } - - @Test - public void testDeleteAuthor() { - String authorName = "testDeleteAuthor"; - AuthorImpl authorImpl = new AuthorImpl(); - AuthorEntity author = authorImpl.addAuthor(authorName); - assertNotNull(author); - List authorList = authorImpl.findByName(authorName); - assertEquals(1, authorList.size()); - authorImpl.delete(author); - authorList = authorImpl.findByName(authorName); - assertEquals(0, authorList.size()); - } - - @Test - public void testAuthorAddAndDelete() { - - } - - @Test - public void testAuthorFindAll() { - - } -} diff --git a/java/src/test/java/com/ibtp/kontor/library/dal/BookImplTest.java b/java/src/test/java/com/ibtp/kontor/library/dal/BookImplTest.java deleted file mode 100644 index 95080e8..0000000 --- a/java/src/test/java/com/ibtp/kontor/library/dal/BookImplTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class BookImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testBookAddAndDelete() { - - } - - @Test - public void testBookFindAll() { - - } -} diff --git a/java/src/test/java/com/ibtp/kontor/library/dal/FileImplTest.java b/java/src/test/java/com/ibtp/kontor/library/dal/FileImplTest.java deleted file mode 100644 index dd0c690..0000000 --- a/java/src/test/java/com/ibtp/kontor/library/dal/FileImplTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class FileImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testFileAddAndDelete() { - - } - - @Test - public void testFileFindAll() { - - } -} diff --git a/java/src/test/java/com/ibtp/kontor/library/dal/TitleImplTest.java b/java/src/test/java/com/ibtp/kontor/library/dal/TitleImplTest.java deleted file mode 100644 index 92acd55..0000000 --- a/java/src/test/java/com/ibtp/kontor/library/dal/TitleImplTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ibtp.kontor.library.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class TitleImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testTitleAddAndDelete() { - - } - - @Test - public void testTitleFindAll() { - - } -} diff --git a/java/src/test/java/com/ibtp/kontor/tradingcards/CollectionTest.java b/java/src/test/java/com/ibtp/kontor/tradingcards/CollectionTest.java deleted file mode 100644 index 69e28ad..0000000 --- a/java/src/test/java/com/ibtp/kontor/tradingcards/CollectionTest.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.ibtp.kontor.tradingcards; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.tradingcards.dal.TeamImpl; -import com.ibtp.kontor.tradingcards.entity.TeamEntity; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import com.ibtp.kontor.tradingcards.dal.SportImpl; -import com.ibtp.kontor.tradingcards.entity.SportEntity; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Collection; -import java.util.Iterator; - -/** - * Created by TPEETZ on 27.01.2015. - */ -public class CollectionTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - setupSports(); - } - - public static void setupSports() { - SportImpl sportImpl = new SportImpl(); - SportEntity football = sportImpl.addSport("Football"); - setupFootballTeams(football); - SportEntity baseball = sportImpl.addSport("Baseball"); - setupFootballTeams(baseball); - SportEntity basketball = sportImpl.addSport("Basketball"); - setupBasketballTeams(basketball); - SportEntity hockey = sportImpl.addSport("Hockey"); - setupHockeyTeams(hockey); - } - - public static void setupFootballTeams(SportEntity football) { - TeamImpl teamImpl = new TeamImpl(); - teamImpl.addTeam("Dallas Cowboys", football); - teamImpl.addTeam("New York Giants", football); - teamImpl.addTeam("Philadelphia Eagles", football); - teamImpl.addTeam("Arizona Cardinals", football); - teamImpl.addTeam("Washington Redskins", football); - teamImpl.addTeam("Detroit Lions", football); - teamImpl.addTeam("Minnesota Vikings", football); - teamImpl.addTeam("Green Bay Packers", football); - teamImpl.addTeam("Chicago Bears", football); - teamImpl.addTeam("Tampa Bay Buccaneers", football); - teamImpl.addTeam("San Francisco 49ers", football); - teamImpl.addTeam("New Orleans Saints", football); - teamImpl.addTeam("Atlanta Falcons", football); - teamImpl.addTeam("Los Angeles Rams", football); - teamImpl.addTeam("Buffalo Bills", football); - teamImpl.addTeam("Miami Dolphins", football); - teamImpl.addTeam("New York Jets", football); - teamImpl.addTeam("New England Patriots", football); - teamImpl.addTeam("Indianapolis Colts", football); - teamImpl.addTeam("Houston Oilers", football); - teamImpl.addTeam("Pittsburgh Steelers", football); - teamImpl.addTeam("Cleveland Browns", football); - teamImpl.addTeam("Kansas City Chiefs", football); - teamImpl.addTeam("Los Angeles Raiders", football); - teamImpl.addTeam("Denver Broncos", football); - teamImpl.addTeam("San Diego Chargers", football); - teamImpl.addTeam("Seattle Seahawks", football); - teamImpl.addTeam("Jacksonville Jaguars", football); - teamImpl.addTeam("Houston Texans", football); - } - - public static void setupBaseballTeams(SportEntity baseball) { - TeamImpl teamImpl = new TeamImpl(); - } - - public static void setupBasketballTeams(SportEntity basketball) { - TeamImpl teamImpl = new TeamImpl(); - teamImpl.addTeam("Houston Rockets", basketball); - teamImpl.addTeam("San Antonio Spurs", basketball); - teamImpl.addTeam("Utah Jazz", basketball); - teamImpl.addTeam("Denver Nuggets", basketball); - teamImpl.addTeam("Minnesota Timberwolves", basketball); - teamImpl.addTeam("Dallas Mavericks", basketball); - teamImpl.addTeam("Seattle SuperSonics", basketball); - teamImpl.addTeam("Phoenix Suns", basketball); - teamImpl.addTeam("Golden State Warriors", basketball); - teamImpl.addTeam("Portland Trail Blazers", basketball); - teamImpl.addTeam("Los Angeles Lakers", basketball); - teamImpl.addTeam("Sacramento Kings", basketball); - teamImpl.addTeam("Los Angeles Clippers", basketball); - teamImpl.addTeam("New York Knicks", basketball); - teamImpl.addTeam("Orlando Magic", basketball); - teamImpl.addTeam("New Jersey Nets", basketball); - teamImpl.addTeam("Miami Heat", basketball); - teamImpl.addTeam("Boston Celtics", basketball); - teamImpl.addTeam("Philadelphia 76ers", basketball); - teamImpl.addTeam("Washington Bullets", basketball); - teamImpl.addTeam("Atlanta Hawks", basketball); - teamImpl.addTeam("Chicago Bulls", basketball); - teamImpl.addTeam("Indiana Pacers", basketball); - teamImpl.addTeam("Cleveland Cavaliers", basketball); - teamImpl.addTeam("Charlotte Hornets", basketball); - teamImpl.addTeam("Detroit Pistons", basketball); - teamImpl.addTeam("Milwaukee Bucks", basketball); - } - - public static void setupHockeyTeams(SportEntity hockey) { - TeamImpl teamImpl = new TeamImpl(); - teamImpl.addTeam("New York Rangers", hockey); - teamImpl.addTeam("Buffalo Sabers", hockey); - teamImpl.addTeam("Detroit Red Wings", hockey); - teamImpl.addTeam("Vancouver Canucks", hockey); - teamImpl.addTeam("Mighty Ducks of Anaheim", hockey); - teamImpl.addTeam("Calgary Flames", hockey); - teamImpl.addTeam("Edmonton Oilers", hockey); - teamImpl.addTeam("Los Angeles Kings", hockey); - teamImpl.addTeam("San Jose Sharks", hockey); - teamImpl.addTeam("Chicago Blackhawks", hockey); - teamImpl.addTeam("Dallas Stars", hockey); - teamImpl.addTeam("St. Louis Blues", hockey); - teamImpl.addTeam("Toronto Maple Leafs", hockey); - teamImpl.addTeam("Winnipeg Jets", hockey); - teamImpl.addTeam("Boston Bruins", hockey); - teamImpl.addTeam("Hartford Whalers", hockey); - teamImpl.addTeam("Montreal Canadiers", hockey); - teamImpl.addTeam("Ottawa Senators", hockey); - teamImpl.addTeam("Pittsburgh Penguins", hockey); - teamImpl.addTeam("Quebec Nordiques", hockey); - teamImpl.addTeam("Florida Panthers", hockey); - teamImpl.addTeam("New Jersey Devils", hockey); - teamImpl.addTeam("New York Islanders", hockey); - teamImpl.addTeam("Philadelphia Flyers", hockey); - teamImpl.addTeam("Tamba Bay Lightning", hockey); - teamImpl.addTeam("Washington Capitals", hockey); - } - - @AfterAll - public static void tearDown() { - TeamImpl teamImpl = new TeamImpl(); - Collection teamEntities = teamImpl.findAll(); - for (TeamEntity teamEntity : teamEntities) { - teamImpl.delete(teamEntity); - } - SportImpl sportImpl = new SportImpl(); - Collection sportEntities = sportImpl.findAll(); - for (SportEntity sportEntity : sportEntities) { - sportImpl.delete(sportEntity); - } - } - - @Test - public void gettAllSports() { - SportImpl sportImpl = new SportImpl(); - Collection resultList = sportImpl.findAll(); - assertEquals(4, resultList.size()); - } - - @Test - public void getAllTeams() { - TeamImpl teamImpl = new TeamImpl(); - Collection resultList = teamImpl.findAll(); - assertEquals(111, resultList.size()); - } -} diff --git a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/BaseSetImplTest.java b/java/src/test/java/com/ibtp/kontor/tradingcards/dal/BaseSetImplTest.java deleted file mode 100644 index 9f3bb4c..0000000 --- a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/BaseSetImplTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class BaseSetImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testBaseSetAddAndDelete() { - - } - - @Test - public void testBaseSetFindAll() { - - } -} diff --git a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/InsertImplTest.java b/java/src/test/java/com/ibtp/kontor/tradingcards/dal/InsertImplTest.java deleted file mode 100644 index c246743..0000000 --- a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/InsertImplTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class InsertImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - - @Test - public void testInsertAddAndDelete() { - - } - - @Test - public void testInsertFindAll() { - - } -} diff --git a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/ManufacturerImplTest.java b/java/src/test/java/com/ibtp/kontor/tradingcards/dal/ManufacturerImplTest.java deleted file mode 100644 index 3681a3f..0000000 --- a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/ManufacturerImplTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import com.ibtp.kontor.tradingcards.entity.ManufacturerEntity; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; - -/** - * Created by tpeetz on 20.01.2015. - */ -public class ManufacturerImplTest { - - @BeforeAll - public static void setup() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void addManufacturer() { - String manufacturerName = "Manufacturer1"; - ManufacturerImpl manufacturerImpl = new ManufacturerImpl(); - ManufacturerEntity manufacturer = manufacturerImpl.addManufacturer(manufacturerName); - assertNotNull(manufacturer); - List manufacturerList = manufacturerImpl.findByName(manufacturerName); - assertTrue(manufacturerList.size() > 0); - } - - @Test - public void deleteManufacturer() { - String manufacturerName = "Manufacturer1"; - ManufacturerImpl manufacturerImpl = new ManufacturerImpl(); - List manufacturerList = manufacturerImpl.findByName(manufacturerName); - assertTrue(manufacturerList.size() > 0); - manufacturerImpl.delete(manufacturerList.get(0)); - manufacturerList = manufacturerImpl.findByName(manufacturerName); - assertEquals(0, manufacturerList.size()); - } - - @Test - public void testManufacturerAddAndDelete() { - - } - - @Test - public void testManufacturerFindAll() { - - } -} diff --git a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/ParallelSetImplTest.java b/java/src/test/java/com/ibtp/kontor/tradingcards/dal/ParallelSetImplTest.java deleted file mode 100644 index b674dd1..0000000 --- a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/ParallelSetImplTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class ParallelSetImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testParallelSetAddAndDelete() { - - } - - @Test - public void testParallelSetFindAll() { - - } -} diff --git a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/PlayerImplTest.java b/java/src/test/java/com/ibtp/kontor/tradingcards/dal/PlayerImplTest.java deleted file mode 100644 index bee6239..0000000 --- a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/PlayerImplTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class PlayerImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testPlayerAddAndDelete() { - - } - - @Test - public void testPlayerFindAll() { - - } -} diff --git a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/PositionImplTest.java b/java/src/test/java/com/ibtp/kontor/tradingcards/dal/PositionImplTest.java deleted file mode 100644 index 9271707..0000000 --- a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/PositionImplTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import com.ibtp.kontor.tradingcards.entity.PositionEntity; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Collection; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class PositionImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testPositionAddAndDelete() { - String positionName = "testPositionAddAndDelete"; - PositionImpl positionImpl = new PositionImpl(); - PositionEntity position = positionImpl.addPosition(positionName); - Collection resultList = positionImpl.findByName(positionName); - assertEquals(1, resultList.size()); - positionImpl.delete(position); - resultList = positionImpl.findByName(positionName); - assertEquals(0, resultList.size()); - } - - @Test - public void testPositionFindAll() { - PositionImpl positionImpl = new PositionImpl(); - Collection resultList = positionImpl.findAll(); - assertEquals(0, resultList.size()); - } -} - diff --git a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/SportCardImplTest.java b/java/src/test/java/com/ibtp/kontor/tradingcards/dal/SportCardImplTest.java deleted file mode 100644 index 6cc8b5c..0000000 --- a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/SportCardImplTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -/** - * Created by tpeetz on 27.01.2015. - */ -public class SportCardImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testSportCardAddAndDelete() { - - } - - @Test - public void testSportCardFindAll() { - - } -} diff --git a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/SportImplTest.java b/java/src/test/java/com/ibtp/kontor/tradingcards/dal/SportImplTest.java deleted file mode 100644 index 6a4d580..0000000 --- a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/SportImplTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import com.ibtp.kontor.tradingcards.entity.SportEntity; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Collection; -import java.util.List; - -/** - * Created by TPEETZ on 19.01.2015. - */ -public class SportImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testSportAddAndDelete() { - String sportName = "testSportAddAndDelete"; - SportImpl sportImpl = new SportImpl(); - SportEntity sport = sportImpl.addSport(sportName); - List sportList = sportImpl.findByName(sportName); - assertEquals(1, sportList.size()); - sportImpl.delete(sport); - List result = sportImpl.findByName(sportName); - assertEquals(0, result.size()); - } - - @Test - public void testSportFindAll() { - SportImpl sportImpl = new SportImpl(); - Collection resultList = sportImpl.findAll(); - assertEquals(0, resultList.size()); - } -} diff --git a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/TeamImplTest.java b/java/src/test/java/com/ibtp/kontor/tradingcards/dal/TeamImplTest.java deleted file mode 100644 index 7e94a1b..0000000 --- a/java/src/test/java/com/ibtp/kontor/tradingcards/dal/TeamImplTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.ibtp.kontor.tradingcards.dal; - -import com.ibtp.kontor.dal.DatabaseManager; -import com.ibtp.kontor.util.LocalTestDatabase; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import com.ibtp.kontor.tradingcards.entity.TeamEntity; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Collection; - -/** - * Created by tpeetz on 20.01.2015. - */ -public class TeamImplTest { - - @BeforeAll - public static void setUp() { - DatabaseManager.setDatabase(new LocalTestDatabase()); - } - - @Test - public void testTeamAddAndDelete() { - String teamName = "testTeamAddAndDelete"; - TeamEntity team = new TeamEntity(teamName); - TeamImpl teamImpl = new TeamImpl(); - teamImpl.store(team); - Collection resultList = teamImpl.findByName(teamName); - assertEquals(1, resultList.size()); - teamImpl.delete(team); - resultList = teamImpl.findByName(teamName); - assertEquals(0, resultList.size()); - } - - @Test - public void testTeamFindAll() { - TeamImpl teamImpl = new TeamImpl(); - Collection resultList = teamImpl.findAll(); - assertEquals(0, resultList.size()); - } -} diff --git a/java/src/test/java/com/ibtp/kontor/util/LocalTestDatabase.java b/java/src/test/java/com/ibtp/kontor/util/LocalTestDatabase.java deleted file mode 100644 index 503104a..0000000 --- a/java/src/test/java/com/ibtp/kontor/util/LocalTestDatabase.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.ibtp.kontor.util; - -import com.ibtp.kontor.dal.Database; -import org.hibernate.jpa.HibernatePersistenceProvider; -import org.hsqldb.Server; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; -import javax.persistence.spi.PersistenceProvider; -import javax.persistence.spi.PersistenceProviderResolver; -import javax.persistence.spi.PersistenceProviderResolverHolder; -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Created by TPEETZ on 21.01.2015. - */ -public class LocalTestDatabase implements Database { - - private static Server server; - private static EntityManagerFactory factory; - private static EntityManager em; - private static Logger logger = LoggerFactory.getLogger(LocalTestDatabase.class.getName()); - - static { - logger.info("initialization and starting database"); - LocalTestDatabase.assureDatabaseRunning(); - } - - public LocalTestDatabase() { - logger.info("LocalDatabaseTest started"); - } - - private static void assureDatabaseRunning() { - if (LocalTestDatabase.server == null) { - LocalTestDatabase.startDatabase(); - } - } - - private static void startDatabase() { - logger.info("startDatabase as kontor in hsqldb_databases/test"); - LocalTestDatabase.server = new Server(); - LocalTestDatabase.server.setAddress("localhost"); - LocalTestDatabase.server.setDatabaseName(0, "kontor"); - LocalTestDatabase.server.setDatabasePath(0, "file:build/hsqldb_databases/test"); - LocalTestDatabase.server.setPort(2345); - LocalTestDatabase.server.setTrace(true); - LocalTestDatabase.server.setLogWriter(new PrintWriter(System.out)); - LocalTestDatabase.server.start(); - } - - private static void stopDatabase() { - server.shutdown(); - } - - private static EntityManagerFactory getFactory() { - if (LocalTestDatabase.factory == null) { - LocalTestDatabase.assureDatabaseRunning(); - PersistenceProviderResolverHolder.setPersistenceProviderResolver(new PersistenceProviderResolver() { - private final List providers_ = Arrays.asList((PersistenceProvider) new HibernatePersistenceProvider()); - - @Override - public void clearCachedProviders() { - // Auto-generated method stub - } - - @Override - public List getPersistenceProviders() { - return providers_; - } - }); - LocalTestDatabase.factory = Persistence.createEntityManagerFactory("com.ibtp.kontor"); - logger.info("EntityManagerFactory(com.ibtp.kontor) created"); - } - return factory; - } - - private static EntityManager getSingleEntityManager() { - return LocalTestDatabase.em; - } - - private static void setSingleEntityManager(EntityManager manager) { - LocalTestDatabase.em = manager; - } - - @Override - public EntityManager getEntityManager() { - if (getSingleEntityManager() == null) { - setSingleEntityManager(getFactory().createEntityManager()); - logger.info("EntityManager created"); - } - return getSingleEntityManager(); - } - - @Override - public String toString() { - String serverMessage; - if (LocalTestDatabase.server == null) { - serverMessage = "server:null"; - } else { - serverMessage = LocalTestDatabase.server.toString(); - } - return LocalTestDatabase.class.getName() + " " + serverMessage; - } -} diff --git a/java/src/test/resources/META-INF/persistence.xml b/java/src/test/resources/META-INF/persistence.xml deleted file mode 100644 index 35d671b..0000000 --- a/java/src/test/resources/META-INF/persistence.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - org.hibernate.jpa.HibernatePersistenceProvider - com.ibtp.kontor.comics.entity.ArtistEntity - com.ibtp.kontor.comics.entity.ComicEntity - com.ibtp.kontor.comics.entity.IssueEntity - com.ibtp.kontor.comics.entity.StoryArcEntity - com.ibtp.kontor.comics.entity.VolumeEntity - com.ibtp.kontor.comics.entity.PublisherEntity - com.ibtp.kontor.library.entity.AuthorEntity - com.ibtp.kontor.library.entity.ArticleEntity - com.ibtp.kontor.library.entity.BookEntity - com.ibtp.kontor.library.entity.FileEntity - com.ibtp.kontor.library.entity.TitleEntity - com.ibtp.kontor.tradingcards.entity.SportEntity - com.ibtp.kontor.tradingcards.entity.TeamEntity - com.ibtp.kontor.tradingcards.entity.PositionEntity - com.ibtp.kontor.tradingcards.entity.PlayerEntity - com.ibtp.kontor.tradingcards.entity.ManufacturerEntity - com.ibtp.kontor.tradingcards.entity.BaseSetEntity - com.ibtp.kontor.tradingcards.entity.InsertEntity - com.ibtp.kontor.tradingcards.entity.ParallelSetEntity - com.ibtp.kontor.tradingcards.entity.SportCardEntity - - - - - - - - - - - - - diff --git a/java/src/test/resources/logback.xml b/java/src/test/resources/logback.xml deleted file mode 100644 index 5254e50..0000000 --- a/java/src/test/resources/logback.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - %d{yyyy-MM-dd_HH:mm:ss.SSS} %-5level %logger{36} - %msg%n - - - - - - build/kontortest.log - - %d{yyyy-MM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - build/kontortest.%i.log.zip - 1 - 10 - - - - 2MB - - - - - - - - - - - - - - diff --git a/java/tysc-20041010-1819.sql b/java/tysc-20041010-1819.sql deleted file mode 100644 index 167c41d..0000000 --- a/java/tysc-20041010-1819.sql +++ /dev/null @@ -1,168 +0,0 @@ -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */; -CREATE DATABASE /*!32312 IF NOT EXISTS*/ `tysc`; -USE `tysc`; - -DROP TABLE IF EXISTS `angebote`; -CREATE TABLE `angebote` ( - `user_id` int(11) NOT NULL default '0', - `karte_id` int(11) NOT NULL default '0' -) TYPE=MyISAM; -INSERT INTO `angebote` (`user_id`,`karte_id`) VALUES (3,28),(3,30); - -DROP TABLE IF EXISTS `benutzer`; -CREATE TABLE `benutzer` ( - `ID` int(11) NOT NULL auto_increment, - `forename` varchar(40) default NULL, - `surname` varchar(40) default NULL, - `strasse` varchar(60) default NULL, - `plz` int(6) default NULL, - `ort` varchar(20) default NULL, - `username` varchar(20) default NULL, - `email` varchar(60) default NULL, - `password` varchar(32) default NULL, - `java` char(1) default NULL, - `language` int(11) NOT NULL default '0', - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `benutzer` (`ID`,`forename`,`surname`,`strasse`,`plz`,`ort`,`username`,`email`,`password`,`java`,`language`) VALUES (1,'Thomas','Peetz','Reichweindamm 24',13627,'Berlin','gophard','thomas.peetz@snafu.de','t.log1n','N',1),(2,'Heiko','John','Johannastr.49',13581,'Berlin','John','healjo@hotmail.com','redskins','N',1),(3,'Thomas','Peetz','Reichweindamm 24',13627,'Berlin','peetz','gophard@snafu.de','peetz','N',1); - -DROP TABLE IF EXISTS `changelog`; -CREATE TABLE `changelog` ( - `datum` date default NULL, - `tablename` varchar(20) default NULL, - `id` int(11) NOT NULL default '0' -) TYPE=MyISAM; -INSERT INTO `changelog` (`datum`,`tablename`,`id`) VALUES ('2002-02-27','benutzer',1),('2002-02-28','benutzer',2),('2002-03-05','benutzer',3),('2002-03-05','angebote',0),('2002-03-05','angebote',0); - -DROP TABLE IF EXISTS `hersteller`; -CREATE TABLE `hersteller` ( - `ID` int(11) NOT NULL auto_increment, - `name` varchar(30) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `hersteller` (`ID`,`name`) VALUES (1,'Pacific'),(2,'Fleer'),(3,'Bowman'),(6,'Topps'),(7,'Donruss'),(8,'Score'),(9,'Flair'); - -DROP TABLE IF EXISTS `inserts`; -CREATE TABLE `inserts` ( - `ID` int(11) NOT NULL auto_increment, - `hersteller_id` int(11) NOT NULL default '0', - `name` varchar(40) default NULL, - PRIMARY KEY (`ID`,`hersteller_id`) -) TYPE=MyISAM; -INSERT INTO `inserts` (`ID`,`hersteller_id`,`name`) VALUES (1,2,'Mystique Big Buzz'); - -DROP TABLE IF EXISTS `karte`; -CREATE TABLE `karte` ( - `ID` int(11) NOT NULL auto_increment, - `spieler_id` int(11) NOT NULL default '0', - `team_id` int(11) NOT NULL default '0', - `hersteller_id` int(11) NOT NULL default '0', - `serie_id` int(11) default NULL, - `parallel_id` int(11) default NULL, - `inserts_id` int(11) default NULL, - `rookie` char(1) default NULL, - `jahr` int(4) default NULL, - `nummer` int(11) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `karte` (`ID`,`spieler_id`,`team_id`,`hersteller_id`,`serie_id`,`parallel_id`,`inserts_id`,`rookie`,`jahr`,`nummer`) VALUES (12,12,13,1,1,0,0,'N',2001,212),(1,1,2,1,1,0,0,'N',2001,185),(2,2,2,1,1,0,0,'N',2001,250),(3,3,8,1,1,0,0,'N',2001,103),(4,4,8,1,1,0,0,'N',2001,112),(5,5,6,1,1,0,0,'N',2001,37),(6,6,6,1,1,0,0,'N',2001,38),(7,7,6,1,1,0,0,'N',2001,31),(8,8,10,1,1,0,0,'N',2001,338),(9,9,10,1,1,0,0,'N',2001,335),(10,10,10,1,1,0,0,'N',2001,345),(11,11,13,1,1,0,0,'N',2001,213),(13,13,14,1,1,0,0,'N',2001,311),(14,14,14,1,1,0,0,'N',2001,312),(15,15,16,1,1,0,0,'N',2001,403),(16,16,16,1,1,0,0,'N',2001,397),(17,17,16,1,1,0,0,'N',2001,404),(18,18,18,1,1,0,0,'N',2001,116),(19,19,18,1,1,0,0,'N',2001,122),(20,20,18,1,1,0,0,'N',2001,117),(21,21,19,1,1,0,0,'N',2001,281),(22,22,19,1,1,0,0,'N',2001,321),(23,23,20,1,1,0,0,'N',2001,331),(24,24,20,1,1,0,0,'N',2001,324),(25,25,21,1,1,0,0,'N',2001,445),(26,26,27,1,1,0,0,'N',2001,28),(27,27,27,1,1,0,0,'N',2001,17),(28,28,27,1,1,0,0,'N',2001,23),(29,29,29,1,1,0,0,'N',2001,273); -INSERT INTO `karte` (`ID`,`spieler_id`,`team_id`,`hersteller_id`,`serie_id`,`parallel_id`,`inserts_id`,`rookie`,`jahr`,`nummer`) VALUES (30,30,31,1,1,0,0,'N',2001,380),(31,31,31,1,1,0,0,'N',2001,390),(32,32,31,1,1,0,0,'N',2001,381),(33,33,31,1,1,0,0,'N',2001,387),(34,34,31,1,1,0,0,'N',2001,386),(35,35,30,1,1,0,0,'N',2001,349),(36,36,30,1,1,0,0,'N',2001,350),(37,37,44,5,8,0,0,'N',1994,106); - -DROP TABLE IF EXISTS `language`; -CREATE TABLE `language` ( - `ID` int(11) NOT NULL auto_increment, - `name` varchar(15) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; - -DROP TABLE IF EXISTS `mannschaft`; -CREATE TABLE `mannschaft` ( - `ID` int(11) NOT NULL auto_increment, - `team_id` int(11) NOT NULL default '0', - `sportart_id` int(11) NOT NULL default '0', - PRIMARY KEY (`ID`) -) TYPE=MyISAM; - -DROP TABLE IF EXISTS `parallelset`; -CREATE TABLE `parallelset` ( - `ID` int(11) NOT NULL auto_increment, - `hersteller_id` int(11) NOT NULL default '0', - `name` varchar(40) default NULL, - PRIMARY KEY (`ID`,`hersteller_id`) -) TYPE=MyISAM; -INSERT INTO `parallelset` (`ID`,`hersteller_id`,`name`) VALUES (1,2,'Mystique Gold'),(2,1,'Pacific Copper'),(3,1,'Pacific Gold'); - -DROP TABLE IF EXISTS `position`; -CREATE TABLE `position` ( - `ID` int(11) NOT NULL auto_increment, - `sportart_id` int(11) NOT NULL default '0', - `name` varchar(20) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `position` (`ID`,`sportart_id`,`name`) VALUES (1,1,'QB'),(2,1,'WR'),(3,1,'RB'),(4,1,'LB'),(5,1,'TE'),(6,1,'FB'),(7,1,'SS'),(8,1,'DE'),(9,1,'K'),(10,1,'P'),(11,1,'LG'),(12,1,'RG'),(13,1,'OF'),(14,1,'DB'),(15,1,'CB'),(16,2,'C'),(17,2,'1B'),(18,2,'2B'),(19,2,'3B'),(20,2,'SS'),(21,2,'LF'),(22,2,'CF'),(23,2,'RF'),(24,2,'DH'),(25,2,'P'); - -DROP TABLE IF EXISTS `serie`; -CREATE TABLE `serie` ( - `ID` int(11) NOT NULL auto_increment, - `hersteller_id` int(11) NOT NULL default '0', - `name` varchar(40) default NULL, - PRIMARY KEY (`ID`,`hersteller_id`) -) TYPE=MyISAM; -INSERT INTO `serie` (`ID`,`hersteller_id`,`name`) VALUES (1,1,'Pacific'),(2,2,'Fleer'),(3,3,'Bowman'),(4,4,'Leaf'),(5,2,'Ultra'),(6,2,'Mystique'),(7,1,'Finest Hour'),(8,5,'SP'),(9,5,'SPX'),(10,5,'SP Authentic'),(11,5,'Black Diamond'); - -DROP TABLE IF EXISTS `spiele`; -CREATE TABLE `spiele` ( - `datum` date default NULL, - `gast` int(11) NOT NULL default '0', - `gast_pkt` int(11) default NULL, - `heim` int(11) NOT NULL default '0', - `heim_pkt` int(11) default NULL -) TYPE=MyISAM; - -DROP TABLE IF EXISTS `spieler`; -CREATE TABLE `spieler` ( - `ID` int(11) NOT NULL auto_increment, - `name` varchar(40) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `spieler` (`ID`,`name`) VALUES (1,'Pathon, Jerome'),(2,'Bruschi, Tedy'),(3,'Couch, Tim'),(4,'Shea, Aaron'),(5,'Lewis, Jamal'),(6,'Lewis, Jermaine'),(7,'Banks, Tony'),(8,'Fuamatu-Ma\'Afala, Chris'),(9,'Bettis, Jerome'),(10,'Stewart, Kordell'),(11,'Moon, Warren'),(12,'Lockett, Kevin'),(13,'Gannon, Rich'),(14,'Jett, James'),(15,'Strong, Mack'),(16,'Huard, Brock'),(17,'Watters, Ricky'),(18,'Aikman, Troy'),(19,'LaFleur, David'),(20,'Brazzell, Chris'),(21,'Dayne, Ron'),(22,'Brown, Na'),(23,'Small, Torrance'),(24,'Lewis, Chad'),(25,'Murrell, Adrian'),(26,'Smith, Maurice'),(27,'Chandler, Chris'),(28,'Kanell, Danny'),(29,'Williams, Ricky'),(30,'Garcia, Jeff'),(31,'Streets, Tai'),(32,'Garner, Charlie'),(33,'Rice, Jerry'),(34,'Owens, Terrell'),(35,'Bruce, Isaac'),(36,'Canidate, Trung'); - -DROP TABLE IF EXISTS `spielerposition`; -CREATE TABLE `spielerposition` ( - `spieler_id` int(11) NOT NULL default '0', - `sportart_id` int(11) NOT NULL default '0', - `position_id` int(11) NOT NULL default '0' -) TYPE=MyISAM; - -DROP TABLE IF EXISTS `sportart`; -CREATE TABLE `sportart` ( - `ID` int(11) NOT NULL auto_increment, - `name` varchar(30) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `sportart` (`ID`,`name`) VALUES (1,'Football'),(2,'Baseball'),(3,'Basketball'),(4,'Hockey'); - -DROP TABLE IF EXISTS `suche`; -CREATE TABLE `suche` ( - `user_id` int(11) NOT NULL default '0', - `karte_id` int(11) NOT NULL default '0' -) TYPE=MyISAM; - -DROP TABLE IF EXISTS `team`; -CREATE TABLE `team` ( - `ID` int(11) NOT NULL auto_increment, - `sportart_id` int(11) NOT NULL default '0', - `name` varchar(40) default NULL, - `short` varchar(15) default NULL, - PRIMARY KEY (`ID`) -) TYPE=MyISAM; -INSERT INTO `team` (`ID`,`sportart_id`,`name`,`short`) VALUES (1,1,'Buffalo Bills','Bills'),(2,1,'Indianapolis Colts','Colts'),(3,1,'Miami Dolphins','Dolphins'),(4,1,'New England Patriots','Patriots'),(5,1,'New York Jets','Jets'),(6,1,'Baltimore Ravens','Ravens'),(7,1,'Cincinnati Bengals','Bengals'),(8,1,'Cleveland Browns','Browns'),(9,1,'Jacksonville Jaguars','Jaguars'),(10,1,'Pittsburgh Steelers','Steelers'),(11,1,'Tennessee Titans','Titans'),(12,1,'Denver Broncos','Broncos'),(13,1,'Kansas City Chiefs','Chiefs'),(14,1,'Oakland Raiders','Raiders'),(15,1,'San Diego Chargers','Chargers'),(16,1,'Seattle Seahawks','Seahawks'),(17,1,'Arizona Cardinals','Cardinals'),(18,1,'Dallas Cowboys','Cowboys'),(19,1,'New York Giants','Giants'),(20,1,'Philadelphia Eagles','Eagles'),(21,1,'Washington Redskins','Redskins'),(22,1,'Chicago Bears','Bears'),(23,1,'Detroit Lions','Lions'),(24,1,'Green Bay Packers','Packers'),(25,1,'Minnesota Vikings','Vikings'),(26,1,'Tampa Bay Buccaneers','Buccaneers'),(27,1,'Atlanta Falcons','Falcons'),(28,1,'Carolina Panthers','Panthers'); -INSERT INTO `team` (`ID`,`sportart_id`,`name`,`short`) VALUES (29,1,'New Orleans Saints','Saints'),(30,1,'St.Louis Rams','Rams'),(31,1,'San Francisco 49ers','49ers'),(32,2,'Baltimore Orioles','Orioles'),(33,2,'Boston Red Sox','Red Sox'),(34,2,'New York Yankees','Yankees'),(35,2,'Tampa Bay Devil Rays','Devil Rays'),(36,2,'Toronto Blue Jays','Blue Jays'),(37,2,'Chicago White Sox','White Sox'),(38,2,'Cleveland Indians','Indians'),(39,2,'Detroit Tigers','Tigers'),(40,2,'Kansas City Royals','Royals'),(41,2,'Minnesota Twins','Twins'),(42,2,'Anaheim Angels','Angels'),(43,2,'Oakland Athletics','Athletics'),(44,2,'Seattle Mariners','Mariners'),(45,2,'Texas Rangers','Rangers'),(46,2,'Atlanta Braves','Braves'),(47,2,'Florida Marlins','Marlins'),(48,2,'Montreal Expos','Expos'),(49,2,'New York Mets','Mets'),(50,2,'Philadelphia Phillies','Phillies'),(51,2,'Chicago Cubs','Cubs'),(52,2,'Cincinnati Reds','Reds'),(53,2,'Houston Astros','Astros'),(54,2,'Milwaukee Brewers','Brewers'),(55,2,'Pittsburgh Pirates','Pirates'),(56,2,'St.Louis Cardinals','Cardinals'); -INSERT INTO `team` (`ID`,`sportart_id`,`name`,`short`) VALUES (57,2,'Arizona Diamondbacks','Diamondbacks'),(58,2,'Colorado Rockies','Rockies'),(59,2,'Los Angeles Dodgers','Dodgers'),(60,2,'San Diego Padres','Padres'),(61,2,'San Francisco Giants','Giants'),(62,3,'Boston Celtics','Celtics'),(63,3,'Miami Heat','Heat'),(64,3,'New Jersey Nets','Mets'),(65,3,'New York Knicks','Knicks'),(66,3,'Orlando Magic','Magic'),(67,3,'Philadelphia 76ers','76ers'),(68,3,'Washington Wizards','Wizards'),(69,3,'Atlanta Hawks','Hawks'),(70,3,'Charlotte Hornets','Hornets'),(71,3,'Chicago Bulls','Bulls'),(72,3,'Cleveland Cavaliers','Cavaliers'),(73,3,'Detroit Pistons','Pistons'),(74,3,'Indiana Pacers','Pacers'),(75,3,'Milwaukee Bucks','Bucks'),(76,3,'Toronto Raptors','Raptors'),(77,3,'Dallas Mavericks','Mavericks'),(78,3,'Denver Nuggets','Nuggets'),(79,3,'Houston Rockets','Rockets'),(80,3,'Minnesota Timberwolves','Timberwolves'),(81,3,'San Antonio Spurs','Spurs'),(82,3,'Utah Jazz','Jazz'),(83,3,'Vancouver Grizzlies','Grizzlies'),(84,3,'Golden State Warriors','Warriors'); -INSERT INTO `team` (`ID`,`sportart_id`,`name`,`short`) VALUES (85,3,'Los Angeles Clippers','Clippers'),(86,3,'Los Angeles Lakers','Lakers'),(87,3,'Phoenix Suns','Suns'),(88,3,'Portland Trail Blazers','Blazers'),(89,3,'Sacramento Kings','Kings'),(90,3,'Seattle SuperSonics','SuperSonics'),(91,4,'Boston Bruins','Bruins'),(92,4,'Buffalo Sabres','Sabres'),(93,4,'Montreal Canadiens','Canadiens'),(94,4,'Ottawa Senators','Senators'),(95,4,'Toronto Maple Leafs','Maple Leafs'),(96,4,'New Jersey Devils','Devils'),(97,4,'New York Islander','Islander'),(98,4,'New York Rangers','Rangers'),(99,4,'Philadelphia Flyers','Flyers'),(100,4,'Pittsburgh Penguins','Penguins'),(101,4,'Atlanta Trashers','Trashers'),(102,4,'Carolina Hurricanes','Hurricanes'),(103,4,'Florida Panthers','Panthers'),(104,4,'Tampa Bay Lightnings','Lightnings'),(105,4,'Washington Capitals','Capitals'),(106,4,'Chicago Blackhawks','Blackhawks'),(107,4,'Columbo Blue Jackets','Blue Jackets'),(108,4,'Detroit Red Wings','Red Wings'),(109,4,'Nashville Predators','Predators'),(110,4,'St.Louis Blues','Blues'); -INSERT INTO `team` (`ID`,`sportart_id`,`name`,`short`) VALUES (111,4,'Calgary Flames','Flames'),(112,4,'Colorado Avalanche','Avalanche'),(113,4,'Edmonton Oilers','Oilers'),(114,4,'Minnesota Wild','Wild'),(115,4,'Vancouver Canucks','Canucks'),(116,4,'Anaheim Mighty Ducks','Mighty Ducks'),(117,4,'Dallas Stars','Stars'),(118,4,'Los Angeles Kings','Kings'),(119,4,'Phoenix Coyotes','Coyotes'),(120,4,'San Jose Sharks','Sharks'),(121,1,'Houston Texans','Texans'),(122,1,'Houston Oilers','Oilers'); -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; diff --git a/kontor-angular/Containerfile b/kontor-angular/Containerfile new file mode 100644 index 0000000..1a11fe7 --- /dev/null +++ b/kontor-angular/Containerfile @@ -0,0 +1,15 @@ +### STAGE 1: Build ### +FROM docker.io/node:22-alpine AS build +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm install +COPY . . +RUN npm run build + +### STAGE 2: Run ### +FROM docker.io/library/nginx:stable-alpine +COPY nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=build /app/dist/kontor-angular/browser /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] + diff --git a/kontor-angular/Dockerfile b/kontor-angular/Dockerfile deleted file mode 100644 index 770d77a..0000000 --- a/kontor-angular/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -### STAGE 1: Build ### -FROM node:22.15-alpine AS build -WORKDIR /app -COPY package.json package-lock.json ./ -RUN npm install -COPY . . -RUN npm run build - -### STAGE 2: Run ### -FROM nginx:1.17.1-alpine -COPY nginx.conf /etc/nginx/conf.d/default.conf -COPY --from=build /app/dist/kontor-angular/browser /usr/share/nginx/html -EXPOSE 80 - diff --git a/kontor-angular/nginx.conf b/kontor-angular/nginx.conf index c8444ce..c9f210c 100644 --- a/kontor-angular/nginx.conf +++ b/kontor-angular/nginx.conf @@ -1,4 +1,5 @@ server { + listen 8800; # Root-Verzeichnis für den Server setzen (wir kopieren unsere Anwendung hierher) root /usr/share/nginx/html; diff --git a/kontor-api/Containerfile b/kontor-api/Containerfile new file mode 100644 index 0000000..991a1b0 --- /dev/null +++ b/kontor-api/Containerfile @@ -0,0 +1,40 @@ +## ------------------------------- Builder Stage ------------------------------ ## +FROM python:3.13-bookworm AS builder + +RUN apt-get update && apt-get install --no-install-recommends -y build-essential && \ + apt-get clean && rm -rf /var/lib/apt/lists/* + +# Download the latest installer, install it and then remove it +ADD https://astral.sh/uv/install.sh /install.sh +RUN chmod -R 655 /install.sh && /install.sh && rm /install.sh + +# Set up the UV environment path correctly +ENV PATH="/root/.local/bin:${PATH}" + +WORKDIR /app + +COPY ./pyproject.toml . +#RUN --mount=type=bind,source=/home/tpeetz/projects/kontor/kontor-model,target=/container/kontor-model uv add /container/kontor-model +#COPY ../kontor-model/ /container +RUN uv add /container/kontor-model +RUN uv sync + +# ------------------------------- Production Stage ------------------------------ ## +FROM python:3.13-slim-bookworm AS production + +RUN apt-get update && apt-get install --no-install-recommends -y curl + +WORKDIR /app + +COPY /src src +COPY --from=builder /app/.venv .venv + +# Set up environment variables for production +ENV PATH="/app/.venv/bin:$PATH" + +# Expose the specified port for FastAPI +EXPOSE 8200 + +# Start the application with Uvicorn in production mode, using environment variable references +CMD ["uvicorn", "src.main:kontor", "--log-level", "info", "--host", "0.0.0.0" , "--port", "8200"] + diff --git a/kontor-api/Dockerfile b/kontor-api/Dockerfile deleted file mode 100644 index df9de03..0000000 --- a/kontor-api/Dockerfile +++ /dev/null @@ -1,55 +0,0 @@ -## ------------------------------- Builder Stage ------------------------------ ## -FROM python:3.13-bookworm AS builder - -RUN apt-get update && apt-get install --no-install-recommends -y build-essential && \ - apt-get clean && rm -rf /var/lib/apt/lists/* - -# Download the latest installer, install it and then remove it -ADD https://astral.sh/uv/install.sh /install.sh -RUN chmod -R 655 /install.sh && /install.sh && rm /install.sh - -# Set up the UV environment path correctly -ENV PATH="/root/.local/bin:${PATH}" - -WORKDIR /app - -COPY ./pyproject.toml . - -RUN uv sync - -# ------------------------------- Production Stage ------------------------------ ## -FROM python:3.13-slim-bookworm AS production - -# The following secrets are available during build time -#RUN --mount=type=secret,id=DB_PASSWORD \ -# --mount=type=secret,id=DB_USER \ -# --mount=type=secret,id=DB_NAME \ -# --mount=type=secret,id=DB_HOST \ -# --mount=type=secret,id=DB_PORT \ -# DB_PASSWORD=/run/secrets/DB_PASSWORD \ -# DB_USER=$(cat /run/secrets/DB_USER) \ -# DB_NAME=$(cat /run/secrets/DB_NAME) \ -# DB_HOST=$(cat /run/secrets/DB_HOST) \ -# DB_PORT=$(cat /run/secrets/DB_PORT) - -#RUN --mount=type=secret,id=secret-key,target=secrets.json - -RUN apt-get update && apt-get install --no-install-recommends -y curl - -RUN useradd --create-home appuser -USER appuser - -WORKDIR /app - -COPY /src src -COPY --from=builder /app/.venv .venv - -# Set up environment variables for production -ENV PATH="/app/.venv/bin:$PATH" - -# Expose the specified port for FastAPI -EXPOSE $PORT - -# Start the application with Uvicorn in production mode, using environment variable references -CMD ["uvicorn", "src.main:kontor", "--log-level", "info", "--host", "0.0.0.0" , "--port", "8500"] - diff --git a/kontor-api/pyproject.toml b/kontor-api/pyproject.toml index 8245184..dd68147 100644 --- a/kontor-api/pyproject.toml +++ b/kontor-api/pyproject.toml @@ -24,9 +24,13 @@ dependencies = [ "psycopg2-binary>=2.9.10", "pytest-cov>=6.1.1", "databases[sqlite]>=0.9.0", - "pydantic[email]>=2.11.3", "jinja2>=3.1.6", "asyncpg>=0.30.0", "bcrypt>=4.3.0", "fastapi-jwt-auth>=0.5.0", + "msgspec[toml,yaml]>=0.21.1", + "kontor-model", ] + +[tool.uv.sources] +kontor-model = { path = "../kontor-model", editable = true } diff --git a/kontor-api/src/apis/base.py b/kontor-api/src/apis/base.py index fbae827..6002400 100644 --- a/kontor-api/src/apis/base.py +++ b/kontor-api/src/apis/base.py @@ -1,11 +1,245 @@ -from fastapi import APIRouter +""" +add router for different parts (like comics, tysc, media) +""" -from src.apis.version1 import comic, mediaactor, mediafile, mediaactorfile, tysc, admin +from fastapi import APIRouter, Depends +from src.apis.version1.admin import mailaccount +from src.apis.version1.comics import ( + artist, + publisher, + comic, + issue, + worktype, + volume, + storyarc, + comicwork, + issuework, +) +from src.apis.version1.media import ( + actor, + file, + lofi, + mediaactorfile, + mediavideo, + mediaarticle, +) +from src.apis.version1.tysc import ( + card, + cardset, + fieldposition, + player, + rooster, + sport, + team, + vendor, +) +from src.core.security import get_current_user_from_token -api_router = APIRouter(prefix="/api") -api_router.include_router(comic.router, prefix="/comics", tags=["comics"]) -api_router.include_router(mediafile.router, prefix="/media", tags=["media"]) -api_router.include_router(mediaactor.router, prefix="/media", tags=["media"]) -api_router.include_router(mediaactorfile.router, prefix="/media", tags=["media"]) -api_router.include_router(tysc.router, prefix="/tysc", tags=["tysc"]) -api_router.include_router(admin.router, prefix="/login", tags=["login"]) +from src.apis.version1.user import assignment, permission, profile, token +from src.apis.version1.bookshelf import article, bookshelf_publisher, book, author, articleauthor, bookauthor + +api_router = APIRouter(prefix="/api") +api_router.include_router( + comic.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + publisher.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + artist.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + issue.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + worktype.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + volume.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + storyarc.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + comicwork.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + issuework.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + file.router, + prefix="/media", + tags=["media"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + mediavideo.router, + prefix="/media", + tags=["media"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + lofi.router, + prefix="/media", + tags=["media"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + mediaarticle.router, + prefix="/media", + tags=["media"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + actor.router, + prefix="/media", + tags=["media"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + mediaactorfile.router, + prefix="/media", + tags=["media"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + sport.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + player.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + team.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + fieldposition.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + rooster.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + vendor.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + cardset.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + card.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + article.router, + prefix="/bookshelf", + tags=["bookshelf"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + bookshelf_publisher.router, + prefix="/bookshelf", + tags=["bookshelf"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + book.router, + prefix="/bookshelf", + tags=["bookshelf"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + author.router, + prefix="/bookshelf", + tags=["bookshelf"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + articleauthor.router, + prefix="/bookshelf", + tags=["bookshelf"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + bookauthor.router, + prefix="/bookshelf", + tags=["bookshelf"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + profile.router, + prefix="/user", + tags=["user"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + token.router, + prefix="/user", + tags=["user"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + permission.router, + prefix="/user", + tags=["user"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + assignment.router, + prefix="/user", + tags=["user"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + mailaccount.router, + prefix="/admin", + tags=["admin"], + dependencies=[Depends(get_current_user_from_token)], +) diff --git a/kontor-api/src/apis/version1/admin.py b/kontor-api/src/apis/version1/admin.py deleted file mode 100644 index 6214a45..0000000 --- a/kontor-api/src/apis/version1/admin.py +++ /dev/null @@ -1,52 +0,0 @@ -from datetime import timedelta -from typing import Annotated - -from fastapi import APIRouter, Body, HTTPException, status, Depends, Response -from fastapi.security import OAuth2PasswordRequestForm - -from src.core.config import settings -from src.core.security import create_access_token, authenticate_user, get_current_active_user -from src.db.models.admin import Profile -from src.schema.admin import Token, ProfileModel -from src.webapps.auth.forms import LoginForm - -router = APIRouter() - - -@router.post("/token") -def login_for_access_token(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]) -> Token: - user = authenticate_user(form_data.username, form_data.password) - if not user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Incorrect username or password", - headers={"WWW-Authenticate": "Bearer"}, - ) - access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) - access_token = create_access_token( - data={"sub": user.email, "scope": " ".join(form_data.scopes)}, expires_delta=access_token_expires - ) - return Token(access_token=access_token, token_type="bearer") - - -# @router.post("/token-cookie", response_model=Token) -def login_for_token_cookie(response: Response, form_data: LoginForm = Depends()): - user = authenticate_user(form_data.username, form_data.password) # type: ignore - if not user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Incorrect username or password", - ) - access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) - access_token = create_access_token( - data={"sub": user.email}, expires_delta=access_token_expires - ) - response.set_cookie( - key="access_token", value=f"Bearer {access_token}", httponly=True - ) - return {"access_token": access_token, "token_type": "bearer"} - - -@router.get("/profile", response_model=ProfileModel) -async def read_profile(current_user: Annotated[Profile, Depends(get_current_active_user)]): - return current_user diff --git a/kontor-api/src/apis/version1/admin/login.py b/kontor-api/src/apis/version1/admin/login.py new file mode 100644 index 0000000..bbf743f --- /dev/null +++ b/kontor-api/src/apis/version1/admin/login.py @@ -0,0 +1,74 @@ +from datetime import timedelta + +from fastapi import APIRouter, Depends, HTTPException, Response, status +from fastapi.security import OAuth2PasswordRequestForm +from src.core.config import settings +from src.core.log_conf import logger +from src.core.security import ( + authenticate_user_by_email, + authenticate_user_by_username, + create_access_token, +) +from kontor_model.schema.admin.login import LoginRequest +from kontor_model.schema.admin.token import Token +from src.webapps.auth.forms import LoginForm + +login_router = APIRouter() + + +@login_router.post( + "/login", + tags=["login"], + summary="Login and get token", + response_description="Return HTTP status code 200 (OK)", + status_code=status.HTTP_200_OK, +) +def login(request: LoginRequest) -> Token: + logger.info("login with %s", request.email) + user = authenticate_user_by_email(str(request.email), str(request.password)) + scopes = ["admin", "read"] + if not user: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Incorrect username or password", + headers={"WWW-Authenticate": "Bearer"}, + ) + access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) + access_token = create_access_token( + data={"sub": user.email, "scope": " ".join(scopes)}, + expires_delta=access_token_expires, + ) + return Token(access_token=access_token, token_type="bearer") + + +@login_router.post("/token", tags=["login"], summary="Login for access token") +# async def login_for_access_token(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]) -> Token: +async def login_for_access_token( + form_data: OAuth2PasswordRequestForm = Depends(), +) -> Token: + user = authenticate_user_by_username(form_data.username, form_data.password) + if not user: + raise HTTPException(status_code=400, detail="Incorrect username or password") + access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) + access_token = create_access_token( + data={"sub": user.user_name, "scope": " ".join(form_data.scopes)}, + expires_delta=access_token_expires, + ) + return Token(access_token=access_token, token_type="bearer") + + +def login_for_token_cookie(response: Response, form_data: LoginForm = Depends()): + user = authenticate_user_by_email(str(form_data.username), str(form_data.password)) + if not user: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Incorrect username or password", + ) + access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) + access_token = create_access_token( + data={"sub": user.email}, expires_delta=access_token_expires + ) + response.set_cookie( + key="access_token", value=f"Bearer {access_token}", httponly=True + ) + return {"access_token": access_token, "token_type": "bearer"} diff --git a/kontor-api/src/apis/version1/admin/mailaccount.py b/kontor-api/src/apis/version1/admin/mailaccount.py new file mode 100644 index 0000000..4a3bdbe --- /dev/null +++ b/kontor-api/src/apis/version1/admin/mailaccount.py @@ -0,0 +1,32 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.admin import MailAccount +from src.db.session import SessionDep +from kontor_model.schema.admin.mailaccount import MailAccountResponse, to_response + +router = APIRouter() + +@router.get("/mailaccounts", response_model=List[MailAccountResponse]) +def get_all_mailaccounts(db: SessionDep) -> List[MailAccountResponse]: + """ + return all MailAccounts as JSON. + """ + results: List[MailAccountResponse] = [] + mailaccounts = db.query(MailAccount).all() + for mailaccount in mailaccounts: + response = to_response(mailaccount) + results.append(response) + return results + +@router.get("/mailaccounts/{mailaccount_id}", response_model=MailAccountResponse) +def get_mailaccount(mailaccount_id: str, db: SessionDep) -> MailAccountResponse: + """ + return MailAccounts by id. + """ + mailaccount = db.get(MailAccount, mailaccount_id) + if mailaccount is None: + raise HTTPException(status_code=409, detail="Mailaccount could not be found") + response = to_response(mailaccount) + return response diff --git a/kontor-api/src/apis/version1/bookshelf/article.py b/kontor-api/src/apis/version1/bookshelf/article.py new file mode 100644 index 0000000..64646e1 --- /dev/null +++ b/kontor-api/src/apis/version1/bookshelf/article.py @@ -0,0 +1,20 @@ +from typing import List + +from fastapi import APIRouter + +from kontor_model.db.models.bookshelf import Article +from src.db.session import SessionDep +from kontor_model.schema.bookshelf.article import ArticleResponse, to_response + + +router = APIRouter() + + +@router.get("/articles", response_model=List[ArticleResponse]) +def get_all_artists(db: SessionDep) -> List[ArticleResponse]: + results: List[ArticleResponse] = [] + articles = db.query(Article).all() + for article in articles: + response = to_response(article) + results.append(response) + return results diff --git a/kontor-api/src/apis/version1/bookshelf/articleauthor.py b/kontor-api/src/apis/version1/bookshelf/articleauthor.py new file mode 100644 index 0000000..0addeb9 --- /dev/null +++ b/kontor-api/src/apis/version1/bookshelf/articleauthor.py @@ -0,0 +1,19 @@ +from typing import List + +from fastapi import APIRouter + +from kontor_model.db.models.bookshelf import ArticleAuthor +from src.db.session import SessionDep +from kontor_model.schema.bookshelf.articleauthor import ArticleAuthorResponse, to_response + +router = APIRouter() + + +@router.get("/articleauthors", response_model=List[ArticleAuthorResponse]) +def get_all_artists(db: SessionDep) -> List[ArticleAuthorResponse]: + results: List[ArticleAuthorResponse] = [] + articleauthors = db.query(ArticleAuthor).all() + for articleauthor in articleauthors: + response = to_response(articleauthor) + results.append(response) + return results diff --git a/kontor-api/src/apis/version1/bookshelf/author.py b/kontor-api/src/apis/version1/bookshelf/author.py new file mode 100644 index 0000000..9bbb9a7 --- /dev/null +++ b/kontor-api/src/apis/version1/bookshelf/author.py @@ -0,0 +1,26 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.bookshelf import Author +from src.db.session import SessionDep +from kontor_model.schema.bookshelf.author import AuthorResponse, to_response + +router = APIRouter() + +@router.get("/authors", response_model=List[AuthorResponse]) +def get_all_authors(db: SessionDep) -> List[AuthorResponse]: + results: List[AuthorResponse] = [] + authors = db.query(Author).all() + for author in authors: + response = to_response(author) + results.append(response) + return results + +@router.get("/authors/{author_id}", response_model=AuthorResponse) +def get_author(author_id: str, db: SessionDep) -> AuthorResponse: + author = db.get(Author, author_id) + if author is None: + raise HTTPException(status_code=404, detail="Author could not be found") + response = to_response(author) + return response diff --git a/kontor-api/src/apis/version1/bookshelf/book.py b/kontor-api/src/apis/version1/bookshelf/book.py new file mode 100644 index 0000000..55345a0 --- /dev/null +++ b/kontor-api/src/apis/version1/bookshelf/book.py @@ -0,0 +1,19 @@ +from typing import List + +from fastapi import APIRouter + +from kontor_model.db.models.bookshelf import Book +from src.db.session import SessionDep +from kontor_model.schema.bookshelf.book import BookResponse, to_response + +router = APIRouter() + + +@router.get("/books", response_model=List[BookResponse]) +def get_all_artists(db: SessionDep) -> List[BookResponse]: + results: List[BookResponse] = [] + books = db.query(Book).all() + for book in books: + response = to_response(book) + results.append(response) + return results diff --git a/kontor-api/src/apis/version1/bookshelf/bookauthor.py b/kontor-api/src/apis/version1/bookshelf/bookauthor.py new file mode 100644 index 0000000..4150bf2 --- /dev/null +++ b/kontor-api/src/apis/version1/bookshelf/bookauthor.py @@ -0,0 +1,19 @@ +from typing import List + +from fastapi import APIRouter + +from kontor_model.db.models.bookshelf import BookAuthor +from src.db.session import SessionDep +from kontor_model.schema.bookshelf.bookauthor import BookAuthorResponse, to_response + +router = APIRouter() + + +@router.get("/bookauthors", response_model=List[BookAuthorResponse]) +def get_all_artists(db: SessionDep) -> List[BookAuthorResponse]: + results: List[BookAuthorResponse] = [] + bookauthors = db.query(BookAuthor).all() + for bookauthor in bookauthors: + response = to_response(bookauthor) + results.append(response) + return results diff --git a/kontor-api/src/apis/version1/bookshelf/bookshelf_publisher.py b/kontor-api/src/apis/version1/bookshelf/bookshelf_publisher.py new file mode 100644 index 0000000..94898a6 --- /dev/null +++ b/kontor-api/src/apis/version1/bookshelf/bookshelf_publisher.py @@ -0,0 +1,19 @@ +from typing import List + +from fastapi import APIRouter + +from kontor_model.db.models.bookshelf import BookshelfPublisher +from src.db.session import SessionDep +from kontor_model.schema.bookshelf.publisher import PublisherResponse, to_response + +router = APIRouter() + + +@router.get("/publishers", response_model=List[PublisherResponse]) +def get_all_artists(db: SessionDep) -> List[PublisherResponse]: + results: List[PublisherResponse] = [] + publishers = db.query(BookshelfPublisher).all() + for publisher in publishers: + response = to_response(publisher) + results.append(response) + return results diff --git a/kontor-api/src/apis/version1/comic.py b/kontor-api/src/apis/version1/comic.py deleted file mode 100644 index 9a955f6..0000000 --- a/kontor-api/src/apis/version1/comic.py +++ /dev/null @@ -1,103 +0,0 @@ -from typing import List - -from fastapi import APIRouter, HTTPException, status - -from src.core.log_conf import logger -from src.db.models.comic import Artist, Comic, Issue, Publisher -from src.db.repository.comics.artist import get_artist_details -from src.db.repository.comics.comic import ( - get_comic_details, - get_issue_details, - get_short_info, - list_comics, -) -from src.db.repository.comics.publisher import get_publisher_details -from src.db.session import SessionDep -from src.schema.comics.artist import ArtistCreation, ArtistResponse -from src.schema.comics.artist_details import ArtistDetailResponse -from src.schema.comics.comic import ComicResponse -from src.schema.comics.comic_details import ComicDetailsResponse -from src.schema.comics.issue_details import IssueDetailsResponse -from src.schema.comics.publisher import PublisherResponse -from src.schema.comics.publisher_details import PublisherDetailsResponse - -router = APIRouter() - - -@router.get("/comics") -def get_all_comics(db: SessionDep) -> List[ComicResponse]: - results: List[ComicResponse] = [] - comics = list_comics(db) - for comic in comics: - response = get_short_info(comic) - results.append(response) - return results - - -@router.get("/comics/{comic_id}", response_model=ComicDetailsResponse) -def get_comic(comic_id: str, db: SessionDep) -> ComicDetailsResponse: - comic = db.get(Comic, comic_id) - if comic is None: - raise HTTPException(status_code=404, detail="Comic could not be found") - logger.info(f"create ComicDetailsResponse for {comic}") - response: ComicDetailsResponse = get_comic_details(comic) - logger.info(f"ComicDetailsResponse: {response}") - return response - - -@router.get("/artists", response_model=List[ArtistResponse]) -def get_all_artists(db: SessionDep) -> List[ArtistResponse]: - results: List[ArtistResponse] = [] - artists = db.query(Artist).all() - for artist in artists: - results.append(ArtistResponse(id=artist.id, name=str(artist.name))) # type: ignore - return results - - -@router.get("/artists/{artist_id}", response_model=ArtistDetailResponse) -def get_artist(artist_id: str, db: SessionDep) -> ArtistDetailResponse: - artist = db.get(Artist, artist_id) - if artist is None: - raise HTTPException(status_code=404, detail="Artist could not be found") - response: ArtistDetailResponse = get_artist_details(artist) - return response - - -@router.post("/artists", status_code=status.HTTP_201_CREATED) -def add_artist(db: SessionDep, artist_creation: ArtistCreation) -> ArtistResponse: - artist: Artist = Artist() - setattr(artist, "name", artist_creation.name) - try: - db.add(artist) - db.commit() - except: - raise HTTPException(status_code=409, detail="Artist already added") - response = ArtistResponse(id=artist.id, name=str(artist.name)) - return response - - -@router.get("/publishers", response_model=List[PublisherResponse]) -def get_all_publishers(db: SessionDep) -> List[PublisherResponse]: - results: List[PublisherResponse] = [] - publishers = db.query(Publisher).all() - for publisher in publishers: - results.append(PublisherResponse(id=publisher.id, name=str(publisher.name))) - return results - - -@router.get("/publishers/{publisher_id}", response_model=PublisherDetailsResponse) -def get_publisher(publisher_id: str, db: SessionDep) -> PublisherDetailsResponse: - publisher = db.get(Publisher, publisher_id) - if publisher is None: - raise HTTPException(status_code=404, detail="Publisher could not be found") - response: PublisherDetailsResponse = get_publisher_details(publisher) - return response - - -@router.get("/issues", response_model=List[IssueDetailsResponse]) -def get_issues(db: SessionDep) -> List[IssueDetailsResponse]: - results: List[IssueDetailsResponse] = [] - issues = db.query(Issue).all() - for issue in issues: - results.append(get_issue_details(issue)) - return results diff --git a/kontor-api/src/apis/version1/comics/artist.py b/kontor-api/src/apis/version1/comics/artist.py new file mode 100644 index 0000000..cc329b7 --- /dev/null +++ b/kontor-api/src/apis/version1/comics/artist.py @@ -0,0 +1,53 @@ +from typing import List + +from fastapi import APIRouter, HTTPException, status + +from kontor_model.db.models.comic import Artist +from kontor_model.db.repository.comics.artist import get_artist_details +from src.db.session import SessionDep +from kontor_model.schema.comics.artist import ArtistCreation, ArtistResponse, artist_to_response +from kontor_model.schema.comics.artist_details import ArtistDetailResponse + + +router = APIRouter() + + +@router.get("/artists", response_model=List[ArtistResponse]) +def get_all_artists(db: SessionDep) -> List[ArtistResponse]: + results: List[ArtistResponse] = [] + artists = db.query(Artist).all() + for artist in artists: + response = artist_to_response(artist) + results.append(response) + return results + + +@router.get("/artists/{artist_id}", response_model=ArtistResponse) +def get_artist(artist_id: str, db: SessionDep) -> ArtistResponse: + artist = db.get(Artist, artist_id) + if artist is None: + raise HTTPException(status_code=404, detail="Artist could not be found") + response: ArtistResponse = artist_to_response(artist) + return response + + +@router.get("/artists/details/{artist_id}", response_model=ArtistDetailResponse) +def get_artist_details_by_id(artist_id: str, db: SessionDep) -> ArtistDetailResponse: + artist = db.get(Artist, artist_id) + if artist is None: + raise HTTPException(status_code=404, detail="Artist could not be found") + response: ArtistDetailResponse = get_artist_details(artist) + return response + + +@router.post("/artists", status_code=status.HTTP_201_CREATED) +def add_artist(db: SessionDep, artist_creation: ArtistCreation) -> ArtistResponse: + artist: Artist = Artist() + setattr(artist, "name", artist_creation.name) + try: + db.add(artist) + db.commit() + except: + raise HTTPException(status_code=409, detail="Artist already added") + response = artist_to_response(artist) + return response diff --git a/kontor-api/src/apis/version1/comics/comic.py b/kontor-api/src/apis/version1/comics/comic.py new file mode 100644 index 0000000..823c198 --- /dev/null +++ b/kontor-api/src/apis/version1/comics/comic.py @@ -0,0 +1,44 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from src.core.log_conf import logger +from kontor_model.db.models.comic import Comic +from kontor_model.db.repository.comics.comic import ( + get_comic_details, +) +from src.db.session import SessionDep +from kontor_model.schema.comics.comic import ComicResponse, comic_to_response +from kontor_model.schema.comics.comic_details import ComicDetailsResponse + +router = APIRouter() + + +@router.get("/comics") +def get_all_comics(db: SessionDep) -> List[ComicResponse]: + results: List[ComicResponse] = [] + comics = db.query(Comic).all() + for comic in comics: + response = comic_to_response(comic) + results.append(response) + return results + + +@router.get("/comics/{comic_id}", response_model=ComicResponse) +def get_comic(comic_id: str, db: SessionDep) -> ComicResponse: + comic = db.get(Comic, comic_id) + if comic is None: + raise HTTPException(status_code=404, detail="Comic could not be found") + response: ComicResponse = comic_to_response(comic) + return response + + +@router.get("/comics/details/{comic_id}", response_model=ComicDetailsResponse) +def get_comic_details_by_id(comic_id: str, db: SessionDep) -> ComicDetailsResponse: + comic = db.get(Comic, comic_id) + if comic is None: + raise HTTPException(status_code=404, detail="Comic could not be found") + logger.info(f"create ComicDetailsResponse for {comic}") + response: ComicDetailsResponse = get_comic_details(comic) + logger.info(f"ComicDetailsResponse: {response}") + return response diff --git a/kontor-api/src/apis/version1/comics/comicwork.py b/kontor-api/src/apis/version1/comics/comicwork.py new file mode 100644 index 0000000..2dcd441 --- /dev/null +++ b/kontor-api/src/apis/version1/comics/comicwork.py @@ -0,0 +1,27 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.comic import ComicWork +from src.db.session import SessionDep +from kontor_model.schema.comics.comicwork import ComicWorkResponse, comicwork_to_response + + +router = APIRouter() + +@router.get("/comicworks", response_model=List[ComicWorkResponse]) +def get_comicworks(db: SessionDep) -> List[ComicWorkResponse]: + results: List[ComicWorkResponse] = [] + worktypes = db.query(ComicWork).all() + for worktype in worktypes: + response = comicwork_to_response(worktype) + results.append(response) + return results + +@router.get("/comicworks/{comicwork_id}", response_model=ComicWorkResponse) +def get_comicwork(comicwork_id: str, db: SessionDep) -> ComicWorkResponse: + worktype = db.get(ComicWork, comicwork_id) + if worktype is None: + raise HTTPException(status_code=404, detail="Comicwork could not be found") + response = comicwork_to_response(worktype) + return response diff --git a/kontor-api/src/apis/version1/comics/issue.py b/kontor-api/src/apis/version1/comics/issue.py new file mode 100644 index 0000000..8af3fb7 --- /dev/null +++ b/kontor-api/src/apis/version1/comics/issue.py @@ -0,0 +1,27 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.comic import Issue +from src.db.session import SessionDep +from kontor_model.schema.comics.issue import IssueResponse, issue_to_response + + +router = APIRouter() + +@router.get("/issues", response_model=List[IssueResponse]) +def get_issues(db: SessionDep) -> List[IssueResponse]: + results: List[IssueResponse] = [] + issues = db.query(Issue).all() + for issue in issues: + response = issue_to_response(issue) + results.append(response) + return results + +@router.get("/issues/{issue_id}", response_model=IssueResponse) +def get_issue(issue_id: str, db: SessionDep) -> IssueResponse: + issue = db.get(Issue, issue_id) + if issue is None: + raise HTTPException(status_code=404, detail="Issue could not be found") + response = issue_to_response(issue) + return response diff --git a/kontor-api/src/apis/version1/comics/issuework.py b/kontor-api/src/apis/version1/comics/issuework.py new file mode 100644 index 0000000..078a8ec --- /dev/null +++ b/kontor-api/src/apis/version1/comics/issuework.py @@ -0,0 +1,27 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.comic import IssueWork +from src.db.session import SessionDep +from kontor_model.schema.comics.issuework import IssueWorkResponse, issuework_to_response + + +router = APIRouter() + +@router.get("/issueworks", response_model=List[IssueWorkResponse]) +def get_issueworks(db: SessionDep) -> List[IssueWorkResponse]: + results: List[IssueWorkResponse] = [] + worktypes = db.query(IssueWork).all() + for worktype in worktypes: + response = issuework_to_response(worktype) + results.append(response) + return results + +@router.get("/issueworks/{issuework_id}", response_model=IssueWorkResponse) +def get_issuework(issuework_id: str, db: SessionDep) -> IssueWorkResponse: + worktype = db.get(IssueWork, issuework_id) + if worktype is None: + raise HTTPException(status_code=404, detail="Issuework could not be found") + response = issuework_to_response(worktype) + return response diff --git a/kontor-api/src/apis/version1/comics/publisher.py b/kontor-api/src/apis/version1/comics/publisher.py new file mode 100644 index 0000000..4780877 --- /dev/null +++ b/kontor-api/src/apis/version1/comics/publisher.py @@ -0,0 +1,37 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.comic import Publisher +from kontor_model.db.repository.comics.publisher import get_publisher_details +from src.db.session import SessionDep +from kontor_model.schema.comics.publisher import PublisherResponse, publisher_to_response +from kontor_model.schema.comics.publisher_details import PublisherDetailsResponse + + +router = APIRouter() + +@router.get("/publishers", response_model=List[PublisherResponse]) +def get_all_publishers(db: SessionDep) -> List[PublisherResponse]: + results: List[PublisherResponse] = [] + publishers = db.query(Publisher).all() + for publisher in publishers: + response: PublisherResponse = publisher_to_response(publisher) + results.append(response) + return results + +@router.get("/publishers/{publisher_id}", response_model=PublisherResponse) +def get_publisher(publisher_id: str, db: SessionDep) -> PublisherResponse: + publisher = db.get(Publisher, publisher_id) + if publisher is None: + raise HTTPException(status_code=404, detail="Publisher could not be found") + response: PublisherResponse = publisher_to_response(publisher) + return response + +@router.get("/publishers/details/{publisher_id}", response_model=PublisherDetailsResponse) +def get_publisher_details_by_id(publisher_id: str, db: SessionDep) -> PublisherDetailsResponse: + publisher = db.get(Publisher, publisher_id) + if publisher is None: + raise HTTPException(status_code=404, detail="Publisher could not be found") + response: PublisherDetailsResponse = get_publisher_details(publisher) + return response diff --git a/kontor-api/src/apis/version1/comics/storyarc.py b/kontor-api/src/apis/version1/comics/storyarc.py new file mode 100644 index 0000000..2ae6239 --- /dev/null +++ b/kontor-api/src/apis/version1/comics/storyarc.py @@ -0,0 +1,26 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.comic import StoryArc +from src.db.session import SessionDep +from kontor_model.schema.comics.storyarc import StoryArcResponse, storyarc_to_response + +router = APIRouter() + +@router.get("/storyarcs", response_model=List[StoryArcResponse]) +def get_storyarcs(db: SessionDep) -> List[StoryArcResponse]: + results: List[StoryArcResponse] = [] + storyarcs = db.query(StoryArc).all() + for storyarc in storyarcs: + response = storyarc_to_response(storyarc) + results.append(response) + return results + +@router.get("/storyarcs/{storyarc_id}", response_model=StoryArcResponse) +def get_storyarc(story_arc_id: str, db: SessionDep) -> StoryArcResponse: + storyarc = db.get(StoryArc, story_arc_id) + if storyarc is None: + raise HTTPException(status_code=404, detail="Storyarc could not be found") + response = storyarc_to_response(storyarc) + return response diff --git a/kontor-api/src/apis/version1/comics/volume.py b/kontor-api/src/apis/version1/comics/volume.py new file mode 100644 index 0000000..faab88f --- /dev/null +++ b/kontor-api/src/apis/version1/comics/volume.py @@ -0,0 +1,26 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.comic import Volume +from src.db.session import SessionDep +from kontor_model.schema.comics.volume import VolumeResponse, volume_to_response + +router = APIRouter() + +@router.get("/volumes", response_model=List[VolumeResponse]) +def volumes(db: SessionDep) -> List[VolumeResponse]: + results: List[VolumeResponse] = [] + worktypes = db.query(Volume).all() + for worktype in worktypes: + response = volume_to_response(worktype) + results.append(response) + return results + +@router.get("/volumes/{volume_id}", response_model=VolumeResponse) +def get_volume(volume_id: str, db: SessionDep) -> VolumeResponse: + worktype = db.get(Volume, volume_id) + if worktype is None: + raise HTTPException(status_code=404, detail="Volume could not be found") + response = volume_to_response(worktype) + return response diff --git a/kontor-api/src/apis/version1/comics/worktype.py b/kontor-api/src/apis/version1/comics/worktype.py new file mode 100644 index 0000000..a06df0f --- /dev/null +++ b/kontor-api/src/apis/version1/comics/worktype.py @@ -0,0 +1,27 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.comic import WorkType +from src.db.session import SessionDep +from kontor_model.schema.comics.worktype import WorktypeResponse, worktype_to_response + + +router = APIRouter() + +@router.get("/worktypes", response_model=List[WorktypeResponse]) +def get_issues(db: SessionDep) -> List[WorktypeResponse]: + results: List[WorktypeResponse] = [] + worktypes = db.query(WorkType).all() + for worktype in worktypes: + response = worktype_to_response(worktype) + results.append(response) + return results + +@router.get("/worktypes/{worktype_id}", response_model=WorktypeResponse) +def get_issue(worktype_id: str, db: SessionDep) -> WorktypeResponse: + worktype = db.get(WorkType, worktype_id) + if worktype is None: + raise HTTPException(status_code=404, detail="Worktype could not be found") + response = worktype_to_response(worktype) + return response diff --git a/kontor-api/src/apis/version1/healthcheck.py b/kontor-api/src/apis/version1/healthcheck.py index c531634..aec2131 100644 --- a/kontor-api/src/apis/version1/healthcheck.py +++ b/kontor-api/src/apis/version1/healthcheck.py @@ -1,6 +1,6 @@ from fastapi import APIRouter, status -from src.schema.admin import HealthCheck +from kontor_model.schema.admin.healthcheck import HealthCheck health_router = APIRouter() diff --git a/kontor-api/src/apis/version1/login.py b/kontor-api/src/apis/version1/login.py deleted file mode 100644 index f6b28b7..0000000 --- a/kontor-api/src/apis/version1/login.py +++ /dev/null @@ -1,41 +0,0 @@ -from datetime import timedelta - -from fastapi import APIRouter, HTTPException, status -from pydantic import BaseModel - -from src.core.config import settings -from src.core.log_conf import logger -from src.core.security import authenticate_user, create_access_token -from src.schema.admin import Token - -login_router = APIRouter() - - -class LoginRequest(BaseModel): - email: str | None = None - password: str | None = None - - -@login_router.post( - "/login", - tags=["login"], - summary="Login and get token", - response_description="Return HTTP status code 200 (OK)", - status_code=status.HTTP_200_OK, -) -def login(request: LoginRequest) -> Token: - logger.info(f"login with {request.email}") - user = authenticate_user(request.email, request.password) # type: ignore - scopes = ["admin", "read"] - if not user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Incorrect username or password", - headers={"WWW-Authenticate": "Bearer"}, - ) - access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) - access_token = create_access_token( - data={"sub": user.email, "scope": " ".join(scopes)}, - expires_delta=access_token_expires, - ) - return Token(access_token=access_token, token_type="bearer") diff --git a/kontor-api/src/apis/version1/media/actor.py b/kontor-api/src/apis/version1/media/actor.py new file mode 100644 index 0000000..222e236 --- /dev/null +++ b/kontor-api/src/apis/version1/media/actor.py @@ -0,0 +1,45 @@ +from typing import List + +from fastapi import APIRouter, status, HTTPException +from src.core.log_conf import logger +from kontor_model.db.repository.media.actor import delete_mediaactor, import_mediaactor +from src.db.session import SessionDep +from kontor_model.schema.media.actor import MediaActorModel, MediaActorResponse, actor_to_response +from kontor_model.db.models.media import MediaActor + +router = APIRouter() + +@router.get("/actors", response_model=List[MediaActorResponse]) +def get_all_actors(db: SessionDep) -> List[MediaActorResponse]: + results: list[MediaActorResponse] = [] + actors = db.query(MediaActor).all() + for mediaactor in actors: + response = actor_to_response(mediaactor) + results.append(response) + return results + +@router.get("/actors/{actor_id}", response_model=MediaActorResponse) +def get_actor(actor_id: str, db: SessionDep) -> MediaActorResponse: + media_actor = db.get(MediaActor, actor_id) + if not media_actor: + raise HTTPException(status_code=404, detail="MediaActor could not be found") + response = actor_to_response(media_actor) + return response + +@router.delete("/actors/{actor_id}", status_code=status.HTTP_204_NO_CONTENT) +def delete_actor(actor_id: str, db: SessionDep): + media_actor = db.get(MediaActor, actor_id) + if not media_actor: + raise HTTPException(status_code=404, detail="MediaActor could not be found") + logger.info(f"delete MediaActor: {actor_id}") + delete_mediaactor(db, media_actor.id) + +@router.post("/actors", status_code=status.HTTP_201_CREATED) +def add_actor(new_actor: MediaActorModel, db: SessionDep) -> MediaActorResponse: + logger.info(f"add actor {new_actor.url}") + try: + mediaActor: MediaActor = import_mediaactor(db, new_actor) + except Exception as exception: + raise HTTPException(status_code=409, detail=f"Link duplicate: {exception}") + response = actor_to_response(mediaActor) + return response diff --git a/kontor-api/src/apis/version1/media/file.py b/kontor-api/src/apis/version1/media/file.py new file mode 100644 index 0000000..3c695e0 --- /dev/null +++ b/kontor-api/src/apis/version1/media/file.py @@ -0,0 +1,163 @@ +from typing import List + +from fastapi import APIRouter, status, HTTPException +from src.core.log_conf import logger +from kontor_model.db.repository.media.actorfile import ( + create_new_mediaactorfile, + delete_mediaactorfile, +) +from kontor_model.db.repository.media.file import delete_mediafile, import_mediafile +from src.db.session import SessionDep +from kontor_model.schema.media.actor import MediaActorResponse, actor_to_response +from kontor_model.schema.media.actorfile import MediaActorFileResponse, actorfile_to_response +from kontor_model.schema.media.file import ( + MediaFileModel, + MediaFileResponse, + file_to_response, + file_to_model, +) +from kontor_model.db.models.media import MediaFile + +router = APIRouter() + + +@router.get("/update-titles") +def update_titles(db: SessionDep) -> List[MediaFileResponse]: + """ + Update title for given MediaFile. + """ + results: list[MediaFileResponse] = [] + files = db.query(MediaFile).filter(MediaFile.review.is_(True)).all() + for mediafile in files: + mediafile.update_title() + db.add(mediafile) + response = file_to_response(mediafile) + results.append(response) + db.commit() + return results + + +@router.get("/files", response_model=List[MediaFileResponse]) +def get_all_files( + db: SessionDep, review: bool = False, download: bool = False +) -> List[MediaFileResponse]: + """ + Get all MediaFiles. + """ + results: List[MediaFileResponse] = [] + files: List[MediaFile] + if review: + files = db.query(MediaFile).filter(MediaFile.review.is_(True)).all() + elif download: + files = db.query(MediaFile).filter(MediaFile.should_download.is_(True)).all() + else: + files = db.query(MediaFile).all() + for mediafile in files: + response = file_to_response(mediafile) + results.append(response) + return results + + +@router.get("/files/{file_id}", response_model=MediaFileResponse) +def get_file(file_id: str, db: SessionDep) -> MediaFileResponse: + """ + Get MediaFile with given id or return HTTPException. + """ + mediafile = db.get(MediaFile, file_id) + if not mediafile: + raise HTTPException(status_code=404, detail="MediaFile could not be found") + response = file_to_response(mediafile) + return response + + +@router.delete("/files/{file_id}", status_code=status.HTTP_204_NO_CONTENT) +def delete_file(file_id: str, db: SessionDep): + """ + Delete MediaFile by given id. + """ + mediafile = db.get(MediaFile, file_id) + if not mediafile: + raise HTTPException(status_code=404, detail="MediaFile could not be found") + logger.info("delete MediaFile: %s", file_id) + actor_files = mediafile.media_actor_files + logger.info("MediaActorFiles links %s", len(actor_files)) + if len(actor_files) > 0: + logger.info("delete MediaActor relations first") + for actor_file in actor_files: + delete_mediaactorfile(db, actor_file.id) + delete_mediafile(db, mediafile.id) + + +@router.get("/files/{file_id}/actors", response_model=list[MediaActorResponse]) +def get_file_actors(file_id: str, db: SessionDep) -> list[MediaActorResponse]: + """ + Get list of Actors for given MediaFile. + """ + mediafile = db.get(MediaFile, file_id) + if not mediafile: + raise HTTPException(status_code=404, detail="MediaFile could not be found") + actor_files = mediafile.media_actor_files + logger.info("already known actors: %s", actor_files) + results: list[MediaActorResponse] = [] + for actor_file in actor_files: + response = actor_to_response(actor_file.media_actor) + results.append(response) + return results + + +@router.put("/files/{file_id}/actors", response_model=List[MediaActorFileResponse]) +def update_file_actors( + file_id: str, db: SessionDep, actors: List[MediaActorResponse] +) -> List[MediaActorFileResponse]: + mediafile = db.get(MediaFile, file_id) + if not mediafile: + raise HTTPException(status_code=404, detail="MediaFile could not be found") + actor_files = mediafile.media_actor_files + logger.info("already known actors: %s", actor_files) + for actor in actors: + already_associated = False + for actor_file in actor_files: + if actor.id == actor_file.media_actor_id: + logger.info("alreay associated - do nothing") + already_associated = True + break + if not already_associated: + create_new_mediaactorfile(db, actor.id, mediafile.id) + db.refresh(mediafile) + actor_files = mediafile.media_actor_files + results: List[MediaActorFileResponse] = [] + for actor_file in actor_files: + response = actorfile_to_response(actor_file) + results.append(response) + return results + + +@router.put("/files/{file_id}", response_model=MediaFileResponse) +def update_file( + file_id: str, db: SessionDep, info: MediaFileResponse +) -> MediaFileResponse: + """ + Update MediaFile with given id and data. + """ + media_file = db.get(MediaFile, file_id) + if not media_file: + raise HTTPException(status_code=404, detail="MediaFile could not be found") + file_to_model(info, media_file) + db.add(media_file) + db.commit() + mediafile = db.get(MediaFile, file_id) + if not mediafile: + raise HTTPException(status_code=404, detail="MediaFile could not be updated") + response = file_to_response(mediafile) + return response + + +@router.post("/files", status_code=status.HTTP_201_CREATED) +def add_file(new_file: MediaFileModel, db: SessionDep) -> MediaFileResponse: + logger.info("add mediafile %s", new_file) + try: + mediaFile: MediaFile = import_mediafile(db, new_file) + except: + raise HTTPException(status_code=409, detail="MediaFile duplicate") + response = file_to_response(mediaFile) + return response diff --git a/kontor-api/src/apis/version1/media/lofi.py b/kontor-api/src/apis/version1/media/lofi.py new file mode 100644 index 0000000..8f7e356 --- /dev/null +++ b/kontor-api/src/apis/version1/media/lofi.py @@ -0,0 +1,42 @@ + +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.media import MediaLofi +from src.db.session import SessionDep +from kontor_model.schema.media.lofi import MediaLofiResponse, lofi_to_response + + +router = APIRouter() + +@router.get("/lofi", response_model=List[MediaLofiResponse]) +def get_all_lofis( + db: SessionDep, review: bool = False, download: bool = False +) -> List[MediaLofiResponse]: + """ + Get all MediaLofis. + """ + results: List[MediaLofiResponse] = [] + lofis: List[MediaLofi] + if review: + lofis = db.query(MediaLofi).filter(MediaLofi.review.is_(True)).all() + elif download: + lofis = db.query(MediaLofi).filter(MediaLofi.should_download.is_(True)).all() + else: + lofis = db.query(MediaLofi).all() + for medialofi in lofis: + response = lofi_to_response(medialofi) + results.append(response) + return results + +@router.get("/lofi/{lofi_id}", response_model=MediaLofiResponse) +def get_lofi(lofi_id: str, db: SessionDep) -> MediaLofiResponse: + """ + Get MediaLofi by id. + """ + lofi = db.get(MediaLofi, lofi_id) + if lofi is None: + raise HTTPException(status_code=404, detail="MediaLofi could not be found") + response = lofi_to_response(lofi) + return response diff --git a/kontor-api/src/apis/version1/media/mediaactorfile.py b/kontor-api/src/apis/version1/media/mediaactorfile.py new file mode 100644 index 0000000..97f436b --- /dev/null +++ b/kontor-api/src/apis/version1/media/mediaactorfile.py @@ -0,0 +1,43 @@ +from typing import List +from fastapi import APIRouter, status, HTTPException +from src.core.log_conf import logger +from kontor_model.db.models.media import MediaActorFile +from kontor_model.db.repository.media.actorfile import delete_mediaactorfile, import_mediaactorfile +from src.db.session import SessionDep +from kontor_model.schema.media.actorfile import MediaActorFileModel, MediaActorFileResponse, actorfile_to_response + +router = APIRouter() + +@router.get("/actorfiles", response_model=List[MediaActorFileResponse]) +def get_all_actorfiles(db: SessionDep) -> List[MediaActorFileResponse]: + results: List[MediaActorFileResponse] = [] + actorfiles = db.query(MediaActorFile).all() + for media_actorfile in actorfiles: + response = actorfile_to_response(media_actorfile) + results.append(response) + return results + +@router.get("/actorfiles/{actorfile_id}", response_model=MediaActorFileResponse) +def get_actorfile(actorfile_id: str, db: SessionDep) -> MediaActorFileResponse: + media_actorfile = db.get(MediaActorFile, actorfile_id) + if not media_actorfile: + raise HTTPException(status_code=404, detail="MediaActor could not be found") + response = actorfile_to_response(media_actorfile) + return response + +@router.delete("/actorfiles/{actorfile_id}", status_code=status.HTTP_204_NO_CONTENT) +def delete_actorfile(actorfile_id: str, db: SessionDep): + media_actorfile = db.get(MediaActorFile, actorfile_id) + if not media_actorfile: + raise HTTPException(status_code=404, detail="MediaActor could not be found") + delete_mediaactorfile(db, media_actorfile.id) + +@router.post("/actorfiles", status_code=status.HTTP_201_CREATED) +def add_actorfile(new_actorfile: MediaActorFileModel, db: SessionDep) -> MediaActorFileResponse: + logger.info("add actorfile %s - %s", new_actorfile.media_actor_id, new_actorfile.media_file_id) + try: + mediaActorFile: MediaActorFile = import_mediaactorfile(db, new_actorfile) + except Exception as exception: + raise HTTPException(status_code=409, detail=f"Link duplicate: {exception}") + response = actorfile_to_response(mediaActorFile) + return response diff --git a/kontor-api/src/apis/version1/media/mediaarticle.py b/kontor-api/src/apis/version1/media/mediaarticle.py new file mode 100644 index 0000000..4c0b89d --- /dev/null +++ b/kontor-api/src/apis/version1/media/mediaarticle.py @@ -0,0 +1,25 @@ + +from typing import List + +from fastapi import APIRouter + +from kontor_model.db.models.media import MediaArticle +from src.db.session import SessionDep +from kontor_model.schema.media.article import MediaArticleResponse, to_response + +router = APIRouter() + +@router.get("/articles", response_model=List[MediaArticleResponse]) +def get_all_files( + db: SessionDep, review: bool = False, download: bool = False +) -> List[MediaArticleResponse]: + """ + Get all MediaVideos. + """ + results: List[MediaArticleResponse] = [] + articles: List[MediaArticle] + articles = db.query(MediaArticle).all() + for article in articles: + response = to_response(article) + results.append(response) + return results diff --git a/kontor-api/src/apis/version1/media/mediavideo.py b/kontor-api/src/apis/version1/media/mediavideo.py new file mode 100644 index 0000000..2dba52c --- /dev/null +++ b/kontor-api/src/apis/version1/media/mediavideo.py @@ -0,0 +1,42 @@ + +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.media import MediaVideo +from src.db.session import SessionDep +from kontor_model.schema.media.video import MediaVideoResponse, video_to_response + + +router = APIRouter() + +@router.get("/videos", response_model=List[MediaVideoResponse]) +def get_all_videos( + db: SessionDep, review: bool = False, download: bool = False +) -> List[MediaVideoResponse]: + """ + Get all MediaVideos. + """ + results: List[MediaVideoResponse] = [] + files: List[MediaVideo] + if review: + files = db.query(MediaVideo).filter(MediaVideo.review.is_(True)).all() + elif download: + files = db.query(MediaVideo).filter(MediaVideo.should_download.is_(True)).all() + else: + files = db.query(MediaVideo).all() + for mediafile in files: + response = video_to_response(mediafile) + results.append(response) + return results + +@router.get("/videos/{video_id}", response_model=MediaVideoResponse) +def get_video(video_id: str, db: SessionDep) -> MediaVideoResponse: + """ + Get MediaVideo by id. + """ + video = db.get(MediaVideo, video_id) + if video is None: + raise HTTPException(status_code=404, detail="MediaVideo could not be found") + response = video_to_response(video) + return response diff --git a/kontor-api/src/apis/version1/mediaactor.py b/kontor-api/src/apis/version1/mediaactor.py deleted file mode 100644 index ec2c236..0000000 --- a/kontor-api/src/apis/version1/mediaactor.py +++ /dev/null @@ -1,48 +0,0 @@ -from fastapi import APIRouter, status, HTTPException -from sqlalchemy import select -from src.core.log_conf import logger -from src.db.repository.media import create_new_mediaactor, delete_mediaactor -from src.db.session import SessionDep -from src.schema.media.actor import Actor, MediaActorResponse, get_actor_details -from src.db.models.media import MediaActor - -router = APIRouter() - -@router.get("/actors", response_model=list[MediaActorResponse]) -# def get_all_files(db: SessionDep, review: bool = False, download: bool = False, current_user: Profile = Depends(get_current_user_from_token)) -> List[MediaFileResponse]: -def get_all_actors(db: SessionDep, review: bool = False, download: bool = False) -> list[MediaActorResponse]: # type: ignore - results: list[MediaActorResponse] = [] - actors = db.scalars(select(MediaActor)).all() - for mediaactor in actors: - response = MediaActorResponse(id=mediaactor.id, name=str(mediaactor.name), url=str(mediaactor.url)) - results.append(response) - return results - -@router.get("/actors/{actor_id}", response_model=MediaActorResponse) -def get_actor(actor_id: str, db: SessionDep) -> MediaActorResponse: # type: ignore - media_actor = db.get(MediaActor, actor_id) - if not media_actor: - raise HTTPException(status_code=404, detail="MediaActor could not be found") - response = get_actor_details(media_actor) - return response - -@router.delete("/actors/{actor_id}", status_code=status.HTTP_204_NO_CONTENT) -def delete_actor(actor_id: str, db: SessionDep): # type: ignore - media_actor = db.get(MediaActor, actor_id) - if not media_actor: - raise HTTPException(status_code=404, detail="MediaActor could not be found") - logger.info(f"delete MediaActor: {actor_id}") - actor_files = media_actor.media_actor_files - logger.info(f"MediaActorFiles links {len(actor_files)}") - if len(actor_files) == 0: - delete_mediaactor(db, media_actor.id) - -@router.post("/actors", status_code=status.HTTP_201_CREATED) -def add_actor(new_actor: Actor, db: SessionDep) -> MediaActorResponse: # type: ignore - logger.info(f"add actor {new_actor.url}") - try: - mediaActor: MediaActor = create_new_mediaactor(new_actor, db) - except: - raise HTTPException(status_code=409, detail="Link duplicate") - response = get_actor_details(mediaActor) - return response diff --git a/kontor-api/src/apis/version1/mediaactorfile.py b/kontor-api/src/apis/version1/mediaactorfile.py deleted file mode 100644 index 2d9524c..0000000 --- a/kontor-api/src/apis/version1/mediaactorfile.py +++ /dev/null @@ -1,33 +0,0 @@ -from fastapi import APIRouter, status, HTTPException -from sqlalchemy import select -from src.db.models.media import MediaActorFile -from src.db.repository.media import delete_mediaactorfile -from src.db.session import SessionDep -from src.schema.media.actorfile import MediaActorFileResponse, get_actorfile_details - -router = APIRouter() - -@router.get("/actorfiles", response_model=list[MediaActorFileResponse]) -def get_all_actorfiles(db: SessionDep) -> list[MediaActorFileResponse]: # type: ignore - results: list[MediaActorFileResponse] = [] - actorfiles = db.scalars(select(MediaActorFile)).all() - for mediaactorfile in actorfiles: - response = MediaActorFileResponse(id=mediaactorfile.id, actor_id=str(mediaactorfile.media_actor_id), file_id=str(mediaactorfile.media_file_id)) - results.append(response) - return results - -@router.get("/actorfiles/{actorfile_id}", response_model=MediaActorFileResponse) -def get_actorfile(actorfile_id: str, db: SessionDep) -> MediaActorFileResponse: # type: ignore - media_actorfile = db.get(MediaActorFile, actorfile_id) - if not media_actorfile: - raise HTTPException(status_code=404, detail="MediaActor could not be found") - response = get_actorfile_details(media_actorfile) - return response - -@router.delete("/actorfiles/{actorfile_id}", status_code=status.HTTP_204_NO_CONTENT) -def delete_actorfile(actorfile_id: str, db: SessionDep): # type: ignore - media_actorfile = db.get(MediaActorFile, actorfile_id) - if not media_actorfile: - raise HTTPException(status_code=404, detail="MediaActor could not be found") - delete_mediaactorfile(db, media_actorfile.id) - diff --git a/kontor-api/src/apis/version1/mediafile.py b/kontor-api/src/apis/version1/mediafile.py deleted file mode 100644 index 9823fbf..0000000 --- a/kontor-api/src/apis/version1/mediafile.py +++ /dev/null @@ -1,120 +0,0 @@ -from fastapi import APIRouter, status, HTTPException, Depends -from sqlalchemy import select, Sequence -from src.core.log_conf import logger -from src.db.repository.media import create_new_mediaactorfile, create_new_mediafile, delete_mediafile -from src.db.session import SessionDep -from src.schema.media.actor import MediaActorResponse -from src.schema.media.actorfile import MediaActorFileResponse -from src.schema.media.file import MediaFileResponse, Link, get_file_details, set_file -from src.db.models.media import MediaFile - -router = APIRouter() - -@router.get("/update-titles") -def update_titles(db: SessionDep) -> list[MediaFileResponse]: # type: ignore - results: list[MediaFileResponse] = [] - files = db.query(MediaFile).filter(MediaFile.review == True).all() - for mediafile in files: - mediafile.update_title() - db.add(mediafile) - response = get_file_details(mediafile) - results.append(response) - db.commit() - return results - - -@router.get("/files", response_model=list[MediaFileResponse]) -# def get_all_files(db: SessionDep, review: bool = False, download: bool = False, current_user: Profile = Depends(get_current_user_from_token)) -> List[MediaFileResponse]: -def get_all_files(db: SessionDep, review: bool = False, download: bool = False) -> list[MediaFileResponse]: # type: ignore - results: list[MediaFileResponse] = [] - files: Sequence[MediaFile] - if review: - files = db.query(MediaFile).filter(MediaFile.review == True).all() # type: ignore - elif download: - files = db.query(MediaFile).filter(MediaFile.should_download == True).all() # type: ignore - else: - files = db.scalars(select(MediaFile)).all() # type: ignore - for mediafile in files: # type: ignore - response = get_file_details(mediafile) - results.append(response) - return results - -@router.get("/files/{file_id}", response_model=MediaFileResponse) -def get_file(file_id: str, db: SessionDep) -> MediaFileResponse: # type: ignore - mediafile = db.get(MediaFile, file_id) - if not mediafile: - raise HTTPException(status_code=404, detail="MediaFile could not be found") - response = get_file_details(mediafile) - return response - -@router.delete("/files/{file_id}", status_code=status.HTTP_204_NO_CONTENT) -def delete_file(file_id: str, db: SessionDep): # type: ignore - mediafile = db.get(MediaFile, file_id) - if not mediafile: - raise HTTPException(status_code=404, detail="MediaFile could not be found") - logger.info(f"delete MediaFile: {file_id}") - actor_files = mediafile.media_actor_files - logger.info(f"MediaActorFiles links {len(actor_files)}") - if len(actor_files) == 0: - delete_mediafile(db, mediafile.id) - -@router.get("/files/{file_id}/actors", response_model=list[MediaActorResponse]) -def get_file_actors(file_id: str, db: SessionDep) -> list[MediaActorResponse]: # type: ignore - mediafile = db.get(MediaFile, file_id) - if not mediafile: - raise HTTPException(status_code=404, detail="MediaFile could not be found") - actor_files = mediafile.media_actor_files - logger.info(f"already known actors: {actor_files}") - results: list[MediaActorResponse] = [] - for actor_file in actor_files: - response = MediaActorResponse(id=actor_file.media_actor.id, name=actor_file.media_actor.name, url=actor_file.media_actor.url) - results.append(response) - return results - -@router.put("/files/{file_id}/actors", response_model=list[MediaActorFileResponse]) -def update_file_actors(file_id: str, db: SessionDep, actors: list[MediaActorResponse]) -> list[MediaActorFileResponse]: # type: ignore - mediafile = db.get(MediaFile, file_id) - if not mediafile: - raise HTTPException(status_code=404, detail="MediaFile could not be found") - actor_files = mediafile.media_actor_files - logger.info(f"already known actors: {actor_files}") - for actor in actors: - already_associated = False - for actor_file in actor_files: - if actor.id == actor_file.media_actor_id: - logger.info("alreay associated - do nothing") - already_associated = True - break - if not already_associated: - create_new_mediaactorfile(db, actor.id, mediafile.id) - db.refresh(mediafile) - actor_files = mediafile.media_actor_files - results: list[MediaActorFileResponse] = [] - for actor_file in actor_files: - response = MediaActorFileResponse(id=actor_file.id, actor_id=actor_file.media_actor_id, file_id=actor_file.media_file_id) - results.append(response) - return results - -@router.put("/files/{file_id}", response_model=MediaFileResponse) -def update_file(file_id: str, db: SessionDep, info: MediaFileResponse) -> MediaFileResponse: # type: ignore - mediaFile = db.get(MediaFile, file_id) - if not mediaFile: - raise HTTPException(status_code=404, detail="MediaFile could not be found") - set_file(info, mediaFile) - db.add(mediaFile) - db.commit() - mediafile = db.get(MediaFile, file_id) - if not mediafile: - raise HTTPException(status_code=404, detail="MediaFile could not be updated") - response = get_file_details(mediafile) - return response - -@router.post("/files", status_code=status.HTTP_201_CREATED) -def add_file(new_link: Link, db: SessionDep) -> MediaFileResponse: # type: ignore - logger.info(f"add url {new_link.url}") - try: - mediaFile: MediaFile = create_new_mediafile(new_link.url, db) - except: - raise HTTPException(status_code=409, detail="Link duplicate") - response = get_file_details(mediaFile) - return response diff --git a/kontor-api/src/apis/version1/tysc.py b/kontor-api/src/apis/version1/tysc.py deleted file mode 100644 index 9d68288..0000000 --- a/kontor-api/src/apis/version1/tysc.py +++ /dev/null @@ -1,16 +0,0 @@ -from typing import List -from fastapi import APIRouter - -from src.db.session import SessionDep -from src.schema.tysc.sport import SportResponse -from src.db.models.tysc import Sport - -router = APIRouter() - -@router.get("/sports") -def get_all_sports(db: SessionDep) -> List[SportResponse]: - results: list[SportResponse] = [] - sports = db.query(Sport).all() - for sport in sports: - results.append(SportResponse(id=sport.id, name=sport.name)) - return results diff --git a/kontor-api/src/apis/version1/tysc/card.py b/kontor-api/src/apis/version1/tysc/card.py new file mode 100644 index 0000000..9449f34 --- /dev/null +++ b/kontor-api/src/apis/version1/tysc/card.py @@ -0,0 +1,27 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.tysc import Card +from src.db.session import SessionDep +from kontor_model.schema.tysc.card import CardResponse, to_response + + +router = APIRouter() + +@router.get("/cards") +def get_all_cards(db: SessionDep) -> List[CardResponse]: + results: List[CardResponse] = [] + cards = db.query(Card).all() + for card in cards: + response = to_response(card) + results.append(response) + return results + +@router.get("/cards/{card_id}", response_model=CardResponse) +def get_card(card_id: str, db: SessionDep) -> CardResponse: + card = db.get(Card, card_id) + if card is None: + raise HTTPException(status_code=404, detail="Card could not be found") + response = to_response(card) + return response diff --git a/kontor-api/src/apis/version1/tysc/cardset.py b/kontor-api/src/apis/version1/tysc/cardset.py new file mode 100644 index 0000000..3faa267 --- /dev/null +++ b/kontor-api/src/apis/version1/tysc/cardset.py @@ -0,0 +1,27 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.tysc import CardSet +from src.db.session import SessionDep +from kontor_model.schema.tysc.cardset import CardSetResponse, to_response + + +router = APIRouter() + +@router.get("/cardsets") +def get_all_cardsets(db: SessionDep) -> List[CardSetResponse]: + results: List[CardSetResponse] = [] + cardsets = db.query(CardSet).all() + for cardset in cardsets: + response = to_response(cardset) + results.append(response) + return results + +@router.get("/cardsets/{cardset_id}", response_model=CardSetResponse) +def get_cardset(cardset_id: str, db: SessionDep) -> CardSetResponse: + cardset = db.get(CardSet, cardset_id) + if cardset is None: + raise HTTPException(status_code=404, detail="Cardset could not be found") + response = to_response(cardset) + return response diff --git a/kontor-api/src/apis/version1/tysc/fieldposition.py b/kontor-api/src/apis/version1/tysc/fieldposition.py new file mode 100644 index 0000000..d613940 --- /dev/null +++ b/kontor-api/src/apis/version1/tysc/fieldposition.py @@ -0,0 +1,27 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.tysc import FieldPosition +from src.db.session import SessionDep +from kontor_model.schema.tysc.fieldposition import FieldPositionResponse, to_response + + +router = APIRouter() + +@router.get("/positions") +def get_all_positions(db: SessionDep) -> List[FieldPositionResponse]: + results: list[FieldPositionResponse] = [] + positions = db.query(FieldPosition).all() + for position in positions: + response = to_response(position) + results.append(response) + return results + +@router.get("/positions/{position_id}", response_model=FieldPositionResponse) +def get_position(position_id: str, db: SessionDep) -> FieldPositionResponse: + position = db.get(FieldPosition, position_id) + if position is None: + raise HTTPException(status_code=404, detail="Fieldposition could not be found") + response = to_response(position) + return response diff --git a/kontor-api/src/apis/version1/tysc/player.py b/kontor-api/src/apis/version1/tysc/player.py new file mode 100644 index 0000000..c91296a --- /dev/null +++ b/kontor-api/src/apis/version1/tysc/player.py @@ -0,0 +1,27 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.tysc import Player +from src.db.session import SessionDep +from kontor_model.schema.tysc.player import PlayerResponse, to_response + + +router = APIRouter() + +@router.get("/players") +def get_all_players(db: SessionDep) -> List[PlayerResponse]: + results: List[PlayerResponse] = [] + players = db.query(Player).all() + for player in players: + response = to_response(player) + results.append(response) + return results + +@router.get("/players/{player_id}", response_model=PlayerResponse) +def get_player(player_id: str, db: SessionDep) -> PlayerResponse: + player = db.get(Player, player_id) + if player is None: + raise HTTPException(status_code=404, detail="Player could not be found") + response = to_response(player) + return response diff --git a/kontor-api/src/apis/version1/tysc/rooster.py b/kontor-api/src/apis/version1/tysc/rooster.py new file mode 100644 index 0000000..7fd3187 --- /dev/null +++ b/kontor-api/src/apis/version1/tysc/rooster.py @@ -0,0 +1,27 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.tysc import Rooster +from src.db.session import SessionDep +from kontor_model.schema.tysc.rooster import RoosterResponse, to_response + + +router = APIRouter() + +@router.get("/roosters") +def get_all_roosters(db: SessionDep) -> List[RoosterResponse]: + results: list[RoosterResponse] = [] + roosters = db.query(Rooster).all() + for rooster in roosters: + response = to_response(rooster) + results.append(response) + return results + +@router.get("/roosters/{rooster_id}", response_model=RoosterResponse) +def get_rooster(rooster_id: str, db: SessionDep) -> RoosterResponse: + rooster = db.get(Rooster, rooster_id) + if rooster is None: + raise HTTPException(status_code=404, detail="Rooster could not be found") + response = to_response(rooster) + return response diff --git a/kontor-api/src/apis/version1/tysc/sport.py b/kontor-api/src/apis/version1/tysc/sport.py new file mode 100644 index 0000000..1c712cc --- /dev/null +++ b/kontor-api/src/apis/version1/tysc/sport.py @@ -0,0 +1,28 @@ +from typing import List +from fastapi import APIRouter, HTTPException + +from src.core.log_conf import logger +from src.db.session import SessionDep +from kontor_model.schema.tysc.sport import SportResponse, to_response +from kontor_model.db.models.tysc import Sport + +router = APIRouter() + +@router.get("/sports") +def get_all_sports(db: SessionDep) -> List[SportResponse]: + results: list[SportResponse] = [] + sports = db.query(Sport).all() + for sport in sports: + response = to_response(sport) + results.append(response) + return results + +@router.get("/sports/{sport_id}", response_model=SportResponse) +def get_sport(sport_id: str, db: SessionDep) -> SportResponse: + sport = db.get(Sport, sport_id) + if sport is None: + raise HTTPException(status_code=404, detail="Sport could not be found") + logger.debug(f"create SportResponse for {sport}") + response: SportResponse = to_response(sport) + return response + diff --git a/kontor-api/src/apis/version1/tysc/team.py b/kontor-api/src/apis/version1/tysc/team.py new file mode 100644 index 0000000..d1a047e --- /dev/null +++ b/kontor-api/src/apis/version1/tysc/team.py @@ -0,0 +1,27 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.tysc import Team +from src.db.session import SessionDep +from kontor_model.schema.tysc.team import TeamResponse, to_response + + +router = APIRouter() + +@router.get("/teams") +def get_all_teams(db: SessionDep) -> List[TeamResponse]: + results: list[TeamResponse] = [] + teams = db.query(Team).all() + for team in teams: + response = to_response(team) + results.append(response) + return results + +@router.get("/teams/{team_id}", response_model=TeamResponse) +def get_team(team_id: str, db: SessionDep) -> TeamResponse: + team = db.get(Team, team_id) + if team is None: + raise HTTPException(status_code=404, detail="Team could not be found") + response = to_response(team) + return response diff --git a/kontor-api/src/apis/version1/tysc/vendor.py b/kontor-api/src/apis/version1/tysc/vendor.py new file mode 100644 index 0000000..e86752b --- /dev/null +++ b/kontor-api/src/apis/version1/tysc/vendor.py @@ -0,0 +1,33 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.tysc import Vendor +from src.db.session import SessionDep +from kontor_model.schema.tysc.vendor import VendorResponse, to_response + + +router = APIRouter() + +@router.get("/vendors") +def get_all_vendors(db: SessionDep) -> List[VendorResponse]: + """ + retrieve all vendors as json response. + """ + results: list[VendorResponse] = [] + vendors = db.query(Vendor).all() + for vendor in vendors: + response = to_response(vendor) + results.append(response) + return results + +@router.get("/vendors/{vendor_id}", response_model=VendorResponse) +def get_vendor(vendor_id: str, db: SessionDep) -> VendorResponse: + """ + retrieve vendor by id as json response. + """ + vendor = db.get(Vendor, vendor_id) + if vendor is None: + raise HTTPException(status_code=404, detail="Vendor could not be found") + response = to_response(vendor) + return response diff --git a/kontor-api/src/apis/version1/user/assignment.py b/kontor-api/src/apis/version1/user/assignment.py new file mode 100644 index 0000000..64ee2e4 --- /dev/null +++ b/kontor-api/src/apis/version1/user/assignment.py @@ -0,0 +1,26 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.admin import Assignment +from src.db.session import SessionDep +from kontor_model.schema.user.assignment import AssignmentResponse, to_response + +router = APIRouter() + +@router.get("/assignments", response_model=List[AssignmentResponse]) +def get_all_assignments(db: SessionDep) -> List[AssignmentResponse]: + results: List[AssignmentResponse] = [] + assignments = db.query(Assignment).all() + for assignment in assignments: + response = to_response(assignment) + results.append(response) + return results + +@router.get("/assignments/{assignment_id}", response_model=AssignmentResponse) +def get_assignment(assignment_id: str, db: SessionDep) -> AssignmentResponse: + assignment = db.get(Assignment, assignment_id) + if assignment is None: + raise HTTPException(status_code=404, detail="Assignment could not be found") + response = to_response(assignment) + return response diff --git a/kontor-api/src/apis/version1/user/permission.py b/kontor-api/src/apis/version1/user/permission.py new file mode 100644 index 0000000..4c99faa --- /dev/null +++ b/kontor-api/src/apis/version1/user/permission.py @@ -0,0 +1,26 @@ +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.admin import Permission +from src.db.session import SessionDep +from kontor_model.schema.user.permission import PermissionResponse, to_response + +router = APIRouter() + +@router.get("/permissions", response_model=List[PermissionResponse]) +def get_all_permissions(db: SessionDep) -> List[PermissionResponse]: + results: List[PermissionResponse] = [] + permissions = db.query(Permission).all() + for permission in permissions: + response = to_response(permission) + results.append(response) + return results + +@router.get("/permissions/{permission_id}", response_model=PermissionResponse) +def get_permission(permission_id: str, db: SessionDep) -> PermissionResponse: + permission = db.get(Permission, permission_id) + if permission is None: + raise HTTPException(status_code=404, detail="Permission could not be found") + response = to_response(permission) + return response diff --git a/kontor-api/src/apis/version1/user/profile.py b/kontor-api/src/apis/version1/user/profile.py new file mode 100644 index 0000000..7187d6d --- /dev/null +++ b/kontor-api/src/apis/version1/user/profile.py @@ -0,0 +1,53 @@ +from typing import List +from fastapi import APIRouter, HTTPException, status +from sqlalchemy import select +from src.core.log_conf import logger + +from src.core.security import CurrentUser +from kontor_model.db.models.admin import Profile +from src.db.repository.user import create_new_profile +from src.db.session import SessionDep +from kontor_model.schema.user.profile import ProfileResponse, ProfileModel, to_response + + +router = APIRouter() + + +@router.get("/profile", response_model=ProfileModel) +async def read_profile(current_user: CurrentUser): + return current_user + +@router.get("/profiles", response_model=List[ProfileResponse]) +def get_all_profiles(db: SessionDep) -> List[ProfileResponse]: + results: List[ProfileResponse] = [] + profiles = db.scalars(select(Profile)).all() + for profile in profiles: + response = to_response(profile) + results.append(response) + return results + +@router.get("/profiles/{profile_id}", response_model=ProfileResponse) +def get_profile(profile_id: str, db: SessionDep) -> ProfileResponse: + profile = db.get(Profile, profile_id) + if not profile: + raise HTTPException(status_code=404, detail="Profile could not be found") + response = to_response(profile) + return response + +@router.delete("/profiles/{profile_id}", status_code=status.HTTP_204_NO_CONTENT) +def delete_profile(profile_id: str, db: SessionDep): # type: ignore + profile = db.get(Profile, profile_id) + if not profile: + raise HTTPException(status_code=404, detail="Profile could not be found") + logger.info(f"delete Profile: {profile_id}") + delete_profile(profile_id=profile_id, db=db) + +@router.post("/profiles", status_code=status.HTTP_201_CREATED) +def add_profile(new_profile: ProfileModel, db: SessionDep) -> ProfileResponse: + logger.info(f"add profile {new_profile.username}") + try: + profile: Profile = create_new_profile(new_profile, db) + except: + raise HTTPException(status_code=409, detail="Profile duplicate") + response = to_response(profile) + return response diff --git a/kontor-api/src/apis/version1/user/token.py b/kontor-api/src/apis/version1/user/token.py new file mode 100644 index 0000000..9a53e25 --- /dev/null +++ b/kontor-api/src/apis/version1/user/token.py @@ -0,0 +1,19 @@ +from typing import List + +from fastapi import APIRouter + +from kontor_model.db.models.admin import Token +from src.db.session import SessionDep +from kontor_model.schema.user.token import TokenResponse, to_response + +router = APIRouter() + + +@router.get("/tokens", response_model=List[TokenResponse]) +def get_all_profiles(db: SessionDep) -> List[TokenResponse]: + results: List[TokenResponse] = [] + tokens = db.query(Token).all() + for token in tokens: + response = to_response(token) + results.append(response) + return results diff --git a/kontor-api/src/core/config.py b/kontor-api/src/core/config.py index 135454f..a7811b9 100644 --- a/kontor-api/src/core/config.py +++ b/kontor-api/src/core/config.py @@ -9,7 +9,7 @@ load_dotenv(dotenv_path=env_path) class Settings: PROJECT_NAME: str = "Kontor" - PROJECT_VERSION: str = "0.2.0" + PROJECT_VERSION: str = "0.3.0" DB_USER: str = os.getenv("DB_USER", "kontor") DB_PASSWORD: str = os.getenv("DB_PASSWORD", "kontor") diff --git a/kontor-api/src/core/middleware.py b/kontor-api/src/core/middleware.py new file mode 100644 index 0000000..a0b86f9 --- /dev/null +++ b/kontor-api/src/core/middleware.py @@ -0,0 +1,35 @@ +import json +import time + +from fastapi import Request, Response +from starlette.middleware.base import BaseHTTPMiddleware +from src.core.log_conf import logger + +class RequestLoggingMiddleware(BaseHTTPMiddleware): + async def dispatch(self, request: Request, call_next) -> Response: + start_time = time.time() + path = request.url.path + + if path != "/health": + # Log request info + request_info ={ + "method": request.method, + "path": path, + "client_ip": request.client.host if request.client else "unknown" + } + logger.info("Incoming: %s", json.dumps(request_info)) + + # Process request + response = await call_next(request) + + if path != "/health": + # Log response info + duration_ms = (time.time()- start_time)*1000 + response_info = { + "status_code": response.status_code, + "duration_ms": round(duration_ms, 2) + } + logger.info("completed: %s", json.dumps(response_info)) + + return response + \ No newline at end of file diff --git a/kontor-api/src/core/security.py b/kontor-api/src/core/security.py index 10c8796..3567de6 100644 --- a/kontor-api/src/core/security.py +++ b/kontor-api/src/core/security.py @@ -1,67 +1,106 @@ -import logging from datetime import datetime, timedelta, timezone -from typing import Annotated, Dict, List, Optional +from typing import Annotated, List, Optional import bcrypt -from fastapi import Depends, HTTPException, Request, Security, status -from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel -from fastapi.security import OAuth2, OAuth2PasswordBearer, SecurityScopes -from fastapi.security.utils import get_authorization_scheme_param +from fastapi import Depends, HTTPException, Security, status +#from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel +from fastapi.security import ( + #OAuth2, + OAuth2PasswordBearer, + SecurityScopes +) +#from fastapi.security.utils import get_authorization_scheme_param from jose import JWTError, jwt from pydantic import ValidationError from src.core.config import settings from src.core.log_conf import logger -from src.db.models.admin import Profile -from src.db.repository.admin import get_profile +from kontor_model.db.models.admin import Profile +from kontor_model.db.repository.admin import ( + get_profile_by_username, + get_profile_by_email, + is_database_empty, +) from src.db.session import SessionLocal -from src.schema.admin import ProfileModel, TokenData +from kontor_model.schema.admin.token import TokenData +from kontor_model.schema.user.profile import ProfileModel, to_model oauth2_scheme = OAuth2PasswordBearer( - tokenUrl="/api/login/token", - scopes={"me": "read", "admin": "read"}, + tokenUrl="/token", + scopes={ + "me": "read", + "admin": "read", + "ROLE_ADMIN": "admin", + "ROLE_MEDIA": "media", + "ROLE_USER": "user", + }, ) -class OAuth2PasswordBearerWithCookie(OAuth2): - def __init__( - self, - tokenUrl: str, - scheme_name: Optional[str] = None, - scopes: Optional[Dict[str, str]] = None, - auto_error: bool = True, - ): - if not scopes: - scopes = {} - flows = OAuthFlowsModel(password={"tokenUrl": tokenUrl, "scopes": scopes}) # type: ignore - super().__init__(flows=flows, scheme_name=scheme_name, auto_error=auto_error) +# class OAuth2PasswordBearerWithCookie(OAuth2): +# def __init__( +# self, +# tokenUrl: str, +# scheme_name: Optional[str] = None, +# scopes: Optional[Dict[str, str]] = None, +# auto_error: bool = True, +# ): +# if not scopes: +# scopes = {} +# flows = OAuthFlowsModel(password={"tokenUrl": tokenUrl, "scopes": scopes}) # type: ignore +# super().__init__(flows=flows, scheme_name=scheme_name, auto_error=auto_error) - async def __call__(self, request: Request) -> Optional[str]: - authorization: str = request.cookies.get("access_token") # type: ignore # changed to accept access token from httpOnly Cookie +# async def __call__(self, request: Request) -> Optional[str]: +# authorization: str = request.cookies.get("access_token") # changed to accept access token from httpOnly Cookie - scheme, param = get_authorization_scheme_param(authorization) - if not authorization or scheme.lower() != "bearer": - if self.auto_error: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Not authenticated", - headers={"WWW-Authenticate": "Bearer"}, - ) - else: - return None - return param +# scheme, param = get_authorization_scheme_param(authorization) +# if not authorization or scheme.lower() != "bearer": +# if self.auto_error: +# raise HTTPException( +# status_code=status.HTTP_401_UNAUTHORIZED, +# detail="Not authenticated", +# headers={"WWW-Authenticate": "Bearer"}, +# ) +# else: +# return None +# return param -def authenticate_user(username: str, password: str) -> Optional[Profile]: +def authenticate_user_by_email(email: str, password: str) -> Optional[Profile]: with SessionLocal() as db: - user = get_profile(username=username, db=db) + user = get_profile_by_email(email=email, db=db) logger.debug(user) if not user: + if is_database_empty(db): + logger.info("database is empty, use temporary access") + user = Profile() + user.email = "init_user@thpeetz.de" + return user return None - if bcrypt.checkpw(password.encode(), user.password.encode()): - print("User successful authenticated") else: - logger.info("Authentication failed!") + if bcrypt.checkpw(password.encode(), user.password.encode()): + logger.info("User successful authenticated") + else: + logger.info("Authentication failed!") + return user + + +def authenticate_user_by_username(username: str, password: str) -> Optional[Profile]: + with SessionLocal() as db: + user = get_profile_by_username(username=username, db=db) + logger.debug(user) + if not user: + if is_database_empty(db): + logger.info("database is empty, use temporary access") + user = Profile() + user.email = "init_user@thpeetz.de" + return user + return None + else: + if bcrypt.checkpw(password.encode(), user.password.encode()): + logger.info("User successful authenticated") + else: + logger.info("Authentication failed!") return user @@ -97,17 +136,19 @@ async def get_current_user( token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM] ) username: str = payload.get("sub") # type: ignore - logger.info("username/email extracted is ", username) + logger.info("username/email extracted is %s", username) if username is None: raise credentials_exception scope: str = payload.get("scope", "") token_scopes: List[str] = scope.split(" ") token_data = TokenData(scopes=token_scopes, username=username) except (JWTError, ValidationError): + logger.info("Exception raised", exc_info=True) raise credentials_exception with SessionLocal() as db: - user = get_profile(username=token_data.username, db=db) # type: ignore + user = get_profile_by_username(username=str(token_data.username), db=db) if user is None: + logger.info("user not found") raise credentials_exception for scope in security_scopes.scopes: if scope not in token_scopes: @@ -122,19 +163,14 @@ async def get_current_user( async def get_current_active_user( current_user: Annotated[Profile, Security(get_current_user, scopes=["me"])], ) -> ProfileModel: - if not current_user.enabled: # type: ignore + if not bool(current_user.enabled): raise HTTPException(status_code=400, detail="Inactive user") - user_model = ProfileModel( - username=current_user.user_name, - email=current_user.email, # type: ignore - first_name=current_user.first_name, - last_name=current_user.last_name, # type: ignore - active=current_user.enabled, - ) # type: ignore + user_model = to_model(current_user) return user_model def get_current_user_from_token(token: str = Depends(oauth2_scheme)): + """ """ credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials", @@ -143,14 +179,21 @@ def get_current_user_from_token(token: str = Depends(oauth2_scheme)): payload = jwt.decode( token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM] ) - username: str = payload.get("sub") # type: ignore - logger.info("username/email extracted is ", username) + username: Optional[str] = payload.get("sub") + logger.info("username/email extracted is %s", username) if username is None: raise credentials_exception - except JWTError: - raise credentials_exception + except JWTError as exception: + raise credentials_exception from exception with SessionLocal() as db: - user = get_profile(username=username, db=db) + user = get_profile_by_email(email=username, db=db) if user is None: - raise credentials_exception + user = get_profile_by_username(username=username, db=db) + if user is None: + raise credentials_exception return user + + +UserDep = Annotated[Profile, Depends(get_current_user_from_token)] + +CurrentUser = Annotated[Profile, Depends(get_current_active_user)] diff --git a/kontor-api/src/db/models/admin.py b/kontor-api/src/db/models/admin.py deleted file mode 100644 index 723dffc..0000000 --- a/kontor-api/src/db/models/admin.py +++ /dev/null @@ -1,74 +0,0 @@ -from datetime import datetime - -from sqlalchemy import Column, ForeignKey, Integer, String, Boolean -from sqlalchemy.orm import relationship, mapped_column, Mapped - -from src.db.models.base import Base, BaseMixin - - -class Profile(Base, BaseMixin): - __tablename__ = 'profile' - first_name = Column(String) - last_name = Column(String) - user_name = Column(String, nullable=False) - email = Column(String) - password = Column(String) - enabled = Column(Boolean) - assignments = relationship("Assignment") - tokens = relationship("Token") - - def get_full_name(self) -> str: - full_name = "" - if self.first_name is not None: - full_name += self.first_name - if self.last_name is not None: - if len(full_name) > 0: - full_name += " " - full_name += self.last_name - return full_name - - def __str__(self): - return f"Profile({self.id} {self.user_name}, {self.email})" - - -class Token(Base, BaseMixin): - __tablename__ = "token" - token = Column(String, nullable=False, unique=True) - name = Column(String) - last_used_date: Mapped[datetime] = mapped_column() - enabled = Column(Boolean) - profile_id = Column(String, ForeignKey("profile.id"), nullable=False) - profile = relationship("Profile", back_populates="tokens") - - -class Permission(Base, BaseMixin): - __tablename__ = "permission" - name = Column(String, nullable=False) - assignments = relationship("Assignment") - - -class Assignment(Base, BaseMixin): - __tablename__ = "assignment" - profile_id = Column(String, ForeignKey("profile.id"), nullable=False) - profile = relationship("Profile", back_populates="assignments") - permission_id = Column(String, ForeignKey("permission.id"), nullable=False) - permission = relationship("Permission", back_populates="assignments") - - -class MailAccount(Base, BaseMixin): - __tablename__ = "mail_account" - host = Column(String) - port = Column(Integer) - protocol = Column(String) - user_name = Column(String) - password = Column(String) - start_tls = Column(Boolean) - - -class Mail(Base, BaseMixin): - __tablename__ = "mail" - folder: Mapped[str] = mapped_column() - subject: Mapped[str] = mapped_column() - body: Mapped[str] = mapped_column() - sent_date: Mapped[datetime] = mapped_column() - received_date: Mapped[datetime] = mapped_column() diff --git a/kontor-api/src/db/models/base.py b/kontor-api/src/db/models/base.py deleted file mode 100644 index 79755ff..0000000 --- a/kontor-api/src/db/models/base.py +++ /dev/null @@ -1,30 +0,0 @@ -import uuid -from datetime import datetime - -from sqlalchemy import func, Column, String, Boolean -from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column - - -class Base(DeclarativeBase): - pass - - -class BaseMixin: - #id = Column(String, primary_key=True, default=uuid.uuid4) - id: Mapped[str] = mapped_column(primary_key=True, default=str(uuid.uuid4())) - # created_date = Column(DateTime) - created_date: Mapped[datetime] = mapped_column(default=func.now()) - # last_modified_date = Column(DateTime) - last_modified_date: Mapped[datetime] = mapped_column(default=func.now()) - # version = Column(Integer) - version: Mapped[int] = mapped_column(default=0) - - -class BaseVideoMixin: - cloud_link = Column(String, nullable=True) - file_name = Column(String, nullable=True) - path = Column(String) - review = Column(Boolean) - title = Column(String) - url = Column(String, nullable=True) - should_download = Column(Boolean) diff --git a/kontor-api/src/db/models/bookshelf.py b/kontor-api/src/db/models/bookshelf.py deleted file mode 100644 index c2b4e4b..0000000 --- a/kontor-api/src/db/models/bookshelf.py +++ /dev/null @@ -1,50 +0,0 @@ -from sqlalchemy import Column, ForeignKey, Integer, String -from sqlalchemy.orm import relationship - -from src.db.models.base import Base, BaseMixin - - -class Article(Base, BaseMixin): - __tablename__ = 'article' - title = Column(String, unique=True) - article_authors = relationship("ArticleAuthor") - - -class Author(Base, BaseMixin): - __tablename__ = 'author' - first_name = Column(String) - last_name = Column(String) - article_authors = relationship("ArticleAuthor") - book_authors = relationship("BookAuthor") - - -class BookshelfPublisher(Base, BaseMixin): - __tablename__ = 'bookshelf_publisher' - name = Column(String, unique=True) - books = relationship("Book") - - -class Book(Base, BaseMixin): - __tablename__ = 'book' - isbn = Column(String, unique=True) - title = Column(String) - year = Column(Integer, nullable=False) - publisher_id = Column(String, ForeignKey('bookshelf_publisher.id'), nullable=False) - publisher = relationship('BookshelfPublisher', back_populates="books") - book_authors = relationship("BookAuthor") - - -class ArticleAuthor(Base, BaseMixin): - __tablename__ = 'article_author' - article_id = Column(String, ForeignKey('article.id'), nullable=False) - article = relationship('Article', back_populates="article_authors") - author_id = Column(String, ForeignKey('author.id'), nullable=False) - author = relationship('Author', back_populates="article_authors") - - -class BookAuthor(Base, BaseMixin): - __tablename__ = 'book_author' - author_id = Column(String, ForeignKey('author.id'), nullable=False) - author = relationship('Author', back_populates="book_authors") - book_id = Column(String, ForeignKey('book.id'), nullable=False) - book = relationship('Book', back_populates="book_authors") diff --git a/kontor-api/src/db/models/comic.py b/kontor-api/src/db/models/comic.py deleted file mode 100644 index b22214a..0000000 --- a/kontor-api/src/db/models/comic.py +++ /dev/null @@ -1,188 +0,0 @@ -import uuid -from datetime import datetime -from typing import AnyStr, Dict, List, Optional, Any -from natsort import natsorted -from sqlalchemy import Column, ForeignKey, Integer, String, Boolean, func -from sqlalchemy.orm import relationship, Mapped, mapped_column - -from src.db.models.base import Base, BaseMixin - - -class Publisher(Base): - __tablename__ = "publisher" - id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4) - created_date: Mapped[datetime] = mapped_column(default=func.now()) - last_modified_date: Mapped[datetime] = mapped_column(default=func.now()) - version: Mapped[int] = mapped_column(default=0) - name = Column(String, unique=True) - weblink = Column(String, nullable=True) - parent_publisher_id: Mapped[Optional[str]] = mapped_column(ForeignKey('publisher.id')) - parent_publisher: Mapped[Optional['Publisher']] = relationship("Publisher", back_populates="imprints", remote_side=[id]) - imprints: Mapped[List['Publisher']] = relationship('Publisher', back_populates="parent_publisher") - comics = relationship("Comic") - - def __repr__(self): - return f'Publisher({self.id} {self.name})' - - def __str__(self): - return self.__repr__() - - -class Comic(Base, BaseMixin): - __tablename__ = 'comic' - title = Column(String, unique=True) - publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False) - publisher = relationship("Publisher", back_populates="comics") - current_order = Column(Boolean) - completed = Column(Boolean) - weblink = Column(String, nullable=True) - issues = relationship("Issue", order_by="Issue.issue_number") - story_arcs = relationship("StoryArc") - trade_paperbacks = relationship("TradePaperback") - volumes = relationship("Volume") - comic_works = relationship("ComicWork") - - def __repr__(self): - return f'Comic({self.id} {self.version} {self.title} {self.publisher.name})' - - def __str__(self): - return f'{self.title}({self.id})' - - def get_artists(self) -> Dict[Any, List[Any]]: - works: Dict[Any, List[Any]] = {} - for work in self.comic_works: - work_type = work.work_type - artist = work.artist - if work_type in works: - works[work_type].append(artist) - else: - works[work_type] = [artist] - return works - - def sorted_issues(self): - sorted_issues = natsorted(self.issues, key=lambda x: getattr(x, 'issue_number')) - return sorted_issues - - -class Volume(Base, BaseMixin): - __tablename__ = "volume" - name = Column(String, nullable=False) - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="volumes") - story_arcs = relationship("StoryArc") - issues = relationship("Issue") - - -class TradePaperback(Base, BaseMixin): - __tablename__ = "trade_paperback" - name = Column(String, nullable=False) - issue_start = Column(Integer) - issue_end = Column(Integer) - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="trade_paperbacks") - - -class StoryArc(Base, BaseMixin): - __tablename__ = "story_arc" - name = Column(String, nullable=False) - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="story_arcs") - volume_id = Column(String, ForeignKey("volume.id"), nullable=True) - volume = relationship("Volume", back_populates="story_arcs") - issues = relationship("Issue") - - -class Issue(Base, BaseMixin): - __tablename__ = "issue" - issue_number = Column(String) - title = Column(String, nullable=True) - published_on: Mapped[datetime] = mapped_column(nullable=True) - in_stock = Column(Boolean) - is_read = Column(Boolean) - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="issues") - volume_id = Column(String, ForeignKey("volume.id"), nullable=True) - volume = relationship("Volume", back_populates="issues") - story_arc_id = Column(String, ForeignKey("story_arc.id"), nullable=True) - story_arc = relationship("StoryArc", back_populates="issues") - issue_works = relationship("IssueWork") - - def get_full_title(self) -> str: - full_title: str = str(self.issue_number) - if self.title: - full_title += str(": " + self.title) - return full_title - - def get_artists(self) -> Dict[Any, List[Any]]: - works: Dict[Any, List[Any]] = {} - for work in self.issue_works: - work_type = work.work_type - artist = work.artist - if work_type in works: - works[work_type].append(artist) - else: - works[work_type] = [artist] - return works - - -class Artist(Base, BaseMixin): - __tablename__ = "artist" - name = Column(String, nullable=False) - weblink = Column(String, nullable=True) - comic_works = relationship("ComicWork") - issue_works = relationship("IssueWork") - - def get_comics(self) -> Dict[Any, List[Comic]]: - works: Dict[Any, List[Comic]] = {} - for work in self.comic_works: - work_type = work.work_type - comic = work.comic - if work_type in works: - works[work_type].append(comic) - else: - works[work_type] = [comic] - return works - - -class WorkType(Base, BaseMixin): - __tablename__ = "worktype" - name = Column(String, nullable=False, unique=True) - comic_works = relationship("ComicWork") - issue_works = relationship("IssueWork") - - def get_artists(self) -> Dict[str, List[str]]: - works: Dict[str, List[str]] = {} - for work in self.comic_works: - comic = work.comic.title - artist = work.artist - if comic in works: - works[comic].append(artist) - else: - works[comic] = [artist] - return works - - def __repr__(self): - return f'Worktype({self.id} {self.version} {self.name} {len(self.comic_works)})' - - def __str__(self): - return f'{self.name}({self.id})' - - -class ComicWork(Base, BaseMixin): - __tablename__ = "comic_work" - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="comic_works") - artist_id = Column(String, ForeignKey("artist.id"), nullable=False) - artist = relationship("Artist", back_populates="comic_works") - work_type_id = Column(String, ForeignKey("worktype.id"), nullable=False) - work_type = relationship("WorkType", back_populates="comic_works") - - -class IssueWork(Base, BaseMixin): - __tablename__ = "issue_work" - issue_id = Column(String, ForeignKey("issue.id"), nullable=False) - issue = relationship("Issue", back_populates="issue_works") - artist_id = Column(String, ForeignKey("artist.id"), nullable=False) - artist = relationship("Artist", back_populates="issue_works") - work_type_id = Column(String, ForeignKey("worktype.id"), nullable=False) - work_type = relationship("WorkType", back_populates="issue_works") diff --git a/kontor-api/src/db/models/database.py b/kontor-api/src/db/models/database.py deleted file mode 100644 index 0da5f88..0000000 --- a/kontor-api/src/db/models/database.py +++ /dev/null @@ -1,395 +0,0 @@ -import json -import logging -from datetime import datetime -from enum import Enum, auto -from pathlib import Path -from typing import Any, List - -from sqlalchemy import select -from sqlalchemy.exc import IntegrityError -from sqlalchemy.orm import sessionmaker - -from src.db.models.tysc import Card, CardSet, Rooster, Team, FieldPosition, Player, Vendor, Sport -from src.db.models.comic import Issue, TradePaperback, StoryArc, Volume, ComicWork, Artist, Comic, Publisher, WorkType -from src.db.models.bookshelf import ArticleAuthor, BookAuthor, BookshelfPublisher, Article, Book, Author -from src.db.models.admin import Mail, MailAccount, ModuleData, Token, Assignment, Permission, Profile -from src.db.models.metadata import MetaDataTable, MetaDataColumn -from src.db.models.media import MediaVideo, MediaArticle, MediaFile, MediaActor, MediaActorFile - - -class ColumnEntry(Enum): - COLUMN_NAME = 'column' - COLUMN_LABEL = 'label' - COLUMN_ORDER = 'order' - COLUMN_REF_COLUMN = 'ref_column' - COLUMN_TYPE = 'type' - COLUMN_WIDGET = 'widget' - - -class StatusType(Enum): - UNKNOWN = auto() - FILE_NAME = auto() - FILE_ID = auto() - DUPLICATE = auto() - CLOUD_LINK = auto() - CLOUD_LINK_ID = auto() - -class ExportType(Enum): - JSON = "JSON" - YAML = "YAML" - SQLITE = "SQLite" - - -class KontorDB: - - def __init__(self, db_engine: Any): - self.engine = db_engine - self.registry = {} - self.init_registry() - - def init_registry(self): - self.registry[Card.__tablename__] = Card - self.registry[CardSet.__tablename__] = CardSet - self.registry[Rooster.__tablename__] = Rooster - self.registry[Team.__tablename__] = Team - self.registry[FieldPosition.__tablename__] = FieldPosition - self.registry[Player.__tablename__] = Player - self.registry[Vendor.__tablename__] = Vendor - self.registry[Sport.__tablename__] = Sport - self.registry[Issue.__tablename__] = Issue - self.registry[TradePaperback.__tablename__] = TradePaperback - self.registry[StoryArc.__tablename__] = StoryArc - self.registry[Volume.__tablename__] = Volume - self.registry[ComicWork.__tablename__] = ComicWork - self.registry[Artist.__tablename__] = Artist - self.registry[Comic.__tablename__] = Comic - self.registry[Publisher.__tablename__] = Publisher - self.registry[WorkType.__tablename__] = WorkType - self.registry[ArticleAuthor.__tablename__] = ArticleAuthor - self.registry[BookAuthor.__tablename__] = BookAuthor - self.registry[BookshelfPublisher.__tablename__] = BookshelfPublisher - self.registry[Article.__tablename__] = Article - self.registry[Book.__tablename__] = Book - self.registry[Author.__tablename__] = Author - self.registry[MediaFile.__tablename__] = MediaFile - self.registry[MediaActor.__tablename__] = MediaActor - self.registry[MediaActorFile.__tablename__] = MediaActorFile - self.registry[MediaArticle.__tablename__] = MediaArticle - self.registry[MediaVideo.__tablename__] = MediaVideo - self.registry[MetaDataColumn.__tablename__] = MetaDataColumn - self.registry[MetaDataTable.__tablename__] = MetaDataTable - self.registry[Assignment.__tablename__] = Assignment - self.registry[Token.__tablename__] = Token - self.registry[Profile.__tablename__] = Profile - self.registry[Permission.__tablename__] = Permission - self.registry[ModuleData.__tablename__] = ModuleData - self.registry[MailAccount.__tablename__] = MailAccount - self.registry[Mail.__tablename__] = Mail - - def get_table_names(self) -> list: - result = [] - __session__ = sessionmaker(self.engine) - with __session__() as session: - tables = session.scalars(select(MetaDataTable)).all() - result = [table.table_name for table in tables] - return result - - def get_table_by_name(self, table_name: str) -> dict: - result = {} - __session__ = sessionmaker(self.engine) - _filter = {'table_name': table_name} - with __session__() as session: - table = session.query(MetaDataTable).filter_by(**_filter).one() - result['id'] = table.id - result['table_name'] = table.table_name - return result - - def get_column_meta_data(self, table_name: str, view_only=True) -> dict: - meta_data = {} - order = 0 - __session__ = sessionmaker(self.engine) - columns = list() - table_info = self.get_table_by_name(table_name) - _filters = {'table_id': table_info['id']} - if view_only: - _filters['is_shown'] = True - with __session__() as session: - columns = session.query(MetaDataColumn).filter_by(**_filters).all() - for column in columns: - # self.log.info("get_column_meta_data: %s %s %d", column.column_name, column.column_label, column.column_order) - meta_data[order] = { - ColumnEntry.COLUMN_NAME: column.column_name, - ColumnEntry.COLUMN_LABEL: column.column_label, - ColumnEntry.COLUMN_ORDER: column.column_order, - ColumnEntry.COLUMN_REF_COLUMN: column.ref_column, - ColumnEntry.COLUMN_TYPE: column.column_type - } - order += 1 - return meta_data - - def get_columns(self, table_name: str) -> dict: - columns = {} - __session__ = sessionmaker(self.engine) - table_info = self.get_table_by_name(table_name) - _filters = {'table_id': table_info['id']} - with __session__() as session: - for column in session.query(MetaDataColumn).filter_by(**_filters).all(): - columns[column.column_name] = { - ColumnEntry.COLUMN_ORDER: column.column_order, - ColumnEntry.COLUMN_TYPE: column.column_type - } - return columns - - def get_filters(self, table_name: str) -> dict: - _filter_map = {} - __session__ = sessionmaker(self.engine) - table_info = self.get_table_by_name(table_name) - _filters = {'table_id': table_info['id'], 'show_filter': True} - with __session__() as session: - for column in session.query(MetaDataColumn).filter_by(**_filters).all(): - _filter_map[column.column_name] = { - ColumnEntry.COLUMN_LABEL: column.filter_label, - ColumnEntry.COLUMN_WIDGET: None - } - return _filter_map - - def data(self, table_name: str, columns: dict, filters: dict) -> list: - data = [] - __session__ = sessionmaker(self.engine) - table = self.registry[table_name] - with __session__() as session: - entries = [] - if len(filters) == 0: - entries = session.scalars(select(table)).all() - else: - entries = session.scalars(select(table).filter_by(**filters)).all() - for entry in entries: - # self.log.info("data: %s", entry) - row = [] - for order in columns.keys(): - column_name = columns[order][ColumnEntry.COLUMN_NAME] - ref_column = columns[order][ColumnEntry.COLUMN_REF_COLUMN] - if str(column_name).endswith("_id"): - ref_table = column_name[:-3] - ref = getattr(entry, ref_table) - value = getattr(ref, ref_column) - row.append(value) - else: - row.append(getattr(entry, column_name)) - data.append(row) - # self.log.info("data: %s", data) - return data - - def export_db(self, export_type: str, export_file_name: str) -> dict: - results = {} - db = {} - export_table_list = self.get_table_names() - for table in export_table_list: - columns = self.get_column_meta_data(table, view_only=False) - if table in self.registry: - model = self.registry[table] - else: - logging.info(f"table {table} is not registered") - continue - __session__ = sessionmaker(self.engine) - with __session__() as session: - rows = session.query(model).all() - entries = [] - for row in rows: - # print(row) - entry = {} - for order in columns: - # print(columns[order]) - column_name = columns[order][ColumnEntry.COLUMN_NAME] - # print(f"get value {column_name} from {row} of table {table}") - try: - value = getattr(row, column_name) - if isinstance(value, datetime): - entry[column_name] = str(value) - else: - entry[column_name] = value - except AttributeError: - pass - entries.append(entry) - db[table] = entries - results[table] = len(entries) - match export_type: - case "JSON": - json_dump = json.dumps(db, indent=4) - with open(export_file_name, "w") as dump_file: - dump_file.write(json_dump) - case "YAML": - pass - case "SQLite": - pass - logging.info(f"{len(results)} tables exported") - return results - - def import_db(self, import_file_name: str) -> dict: - result = {} - import_file = Path(import_file_name) - if not import_file.exists(): - logging.info(f"File {import_file_name} does not exist. Do nothing.") - return result - match import_file.suffix: - case '.json': - print("read json file") - with open(import_file_name, 'r') as json_file: - json_load = json.load(json_file) - for table in json_load: - logging.info(f"{table}: {len(json_load[table])}") - result[table] = self.import_table(table, json_load[table]) - case '.yml': - print("read yaml file") - case '.yaml': - print("read yaml file") - case '.db': - print("read sqlite file") - return result - - def import_table(self, table_name: str, items:list) -> dict: - result = {} - updated = [] - added = [] - remaining = [] - existing_ids = self.get_ids(table_name) - logging.info(f"found {len(existing_ids)} existing ids for table {table_name}") - for item in items: - current_id = item['id'] - # print(f"import item: {item}") - found_item = None - __session__ = sessionmaker(self.engine) - with __session__() as session: - found_item = session.get(self.registry[table_name], current_id) - # print(f"found item: {found_item}") - if found_item is not None: - changed = self.update_entry(table_name, current_id, item) - updated.append(item) - if changed: - logging.info(f"{current_id} has changed") - updated.append(item) - existing_ids.remove(current_id) - else: - try: - self.add_entry(table_name, item) - added.append(item) - except IntegrityError as error: - logging.info(f"Could not add item, due to: {error.detail}") - if len(existing_ids) > 0: - print(f"remaining items for {table_name}: {existing_ids}") - remaining.extend(existing_ids) - result['updated'] = updated - result['added'] = added - result['remaining'] = remaining - return result - - def get_ids(self, table_name: str) -> list: - existing_ids = [] - __session__ = sessionmaker(self.engine) - with __session__() as session: - items = session.query(self.registry[table_name]).all() - for item in items: - existing_ids.append(getattr(item, 'id')) - return existing_ids - - def add_entry(self, table_name: str, update_item: dict): - logging.debug(f"add entry to table {table_name} with {update_item}") - __session__ = sessionmaker(self.engine) - with __session__() as session: - add_item = self.registry[table_name]() - for key in update_item.keys(): - update_value = update_item[key] - setattr(add_item, key, update_value) - session.add(add_item) - session.commit() - - def update_entry(self, table_name, current_id, update_item: dict) -> bool: - # self.log.info("update entry to table %s", table_name) - __session__ = sessionmaker(self.engine) - with __session__() as session: - existing_item = session.query(self.registry[table_name]).get(current_id) - changed = False - for key in update_item.keys(): - update_value = update_item[key] - existing_value = getattr(existing_item, key) - if type(existing_value) is not type(update_value): - existing_value = str(existing_value) - if existing_value != update_value: - logging.info(f"{key} has changed: {existing_value} != {update_value}") - setattr(existing_item, key, update_value) - session.commit() - changed = True - logging.info(f"update {key} with {update_value}") - return changed - - def add_link(self, link: str) -> dict: - result = {} - __session__ = sessionmaker(self.engine) - with __session__() as session: - media_file = MediaFile() - media_file.id = str(uuid.uuid4()) - media_file.created_date = datetime.now() - media_file.last_modified_date = datetime.now() - media_file.version = 0 - media_file.url = link - media_file.review = 1 - media_file.should_download = 1 - try: - session.add(media_file) - session.commit() - result['added'] = {'url': media_file.url, 'title': media_file.title, 'review': media_file.review, 'download': media_file.should_download} - except IntegrityError as error: - session.rollback() - result['error'] = error.orig - return result - - def update_titles(self) -> dict: - update_list = {} - __session__ = sessionmaker(self.engine) - _filter = { 'review': True} - with __session__() as session: - links = session.query(MediaFile).filter_by(**_filter).all() - self.log.info("%d entries found for updating titles", len(links)) - for link in links: - url = link.url - if url is None: - continue - link.update_title() - session.commit() - update_list[link.id] = link.title - return update_list - - def get_download_list(self) -> List[str]: - download_list = [] - __session__ = sessionmaker(self.engine) - _filter = { 'should_download': True} - with __session__() as session: - links = session.query(MediaFile).filter_by(**_filter).all() - for link in links: - url = link.url - if url is None: - continue - download_list.append(link.id) - return download_list - - def download_file(self, entry_id: str, download_dir = "/data/media", dl_tool = "yt-dlp") -> str: - __session__ = sessionmaker(self.engine) - with __session__() as session: - link = session.query(MediaFile).get(entry_id) - link.download_file(download_dir, dl_tool) - session.commit() - file_name = link.file_name - return file_name - - def delete_entries(self): - for (table_name, table) in self.registry.items(): - # self.log.info("delete entries from table %s", table_name) - __session__ = sessionmaker(self.engine) - with __session__() as session: - items = session.query(table).all() - for item in items: - session.delete(item) - session.commit() - - def check_files(self): - pass diff --git a/kontor-api/src/db/models/media.py b/kontor-api/src/db/models/media.py deleted file mode 100644 index d52b449..0000000 --- a/kontor-api/src/db/models/media.py +++ /dev/null @@ -1,121 +0,0 @@ -import logging -import re -import subprocess -from datetime import datetime -from pathlib import Path - -import requests -from bs4 import BeautifulSoup -from sqlalchemy import Column, String, ForeignKey, Boolean -from sqlalchemy.orm import relationship - -from src.db.models.base import Base, BaseMixin, BaseVideoMixin - - -class MediaFile(Base, BaseMixin, BaseVideoMixin): - __tablename__ = 'media_file' - media_actor_files = relationship("MediaActorFile") - - def __repr__(self): - return f'MediaFile({self.id} {self.title} {self.title})' - - def __str__(self): - return f'{self.title}({self.id})' - - def update_title(self) -> None: - logging.info(f"update title for {self.url}") - try: - r = requests.get(str(self.url)) - soup = BeautifulSoup(r.content, "html.parser") - title = soup.title.get_text() # type: ignore - self.title = title - self.review = False - except: - self.title = None - self.review = True - self.last_modified_date = datetime.now() - - def download_file(self, download_dir: str, dl_tool: str): - logging.info(f"download file for {self.url} to {download_dir}") - result = subprocess.run([dl_tool, self.url], cwd=download_dir, capture_output=True, text=True) # type: ignore - if result.returncode == 0: - output = result.stdout - output = re.sub(' +', ' ', output) - lines_list = output.splitlines() - file_name = self.__parse_output__(lines_list) - if file_name is None: - self.review = True - self.should_download = True - self.file_name = None - else: - download_file = Path(file_name) - self.should_download = False - self.file_name = download_file.name - self.cloud_link = str(download_file.absolute()) - self.last_modified_date = datetime.now() - - def __parse_output__(self, lines_list): - self.file_name = None - for line in lines_list: - if 'has already been downloaded' in line: - end_len = len(' has already been downloaded') - self.file_name = line[11:-end_len] - if 'Destination' in line: - line_len = len(line) - start_len = len('[download] Destination: ') - file_len = line_len - start_len - self.file_name = line[-file_len:] - return self.file_name - - -class MediaActor(Base, BaseMixin): - __tablename__ = 'media_actor' - name = Column(String) - url = Column(String, unique=True, nullable=True) - media_actor_files = relationship("MediaActorFile") - - def __repr__(self) -> str: - return f'MediaActor({self.id} {self.name} {self.url})' - - def __str__(self) -> str: - return f'{self.url}({self.id})' - - -class MediaActorFile(Base, BaseMixin): - __tablename__ = 'media_actor_file' - media_actor_id = Column(String, ForeignKey("media_actor.id"), nullable=False) - media_actor = relationship("MediaActor", back_populates="media_actor_files") - media_file_id = Column(String, ForeignKey("media_file.id"), nullable=True) - media_file = relationship("MediaFile", back_populates="media_actor_files") - - def __repr__(self): - return f'MediaActorFile({self.id} {self.media_actor_id} {self.media_file_id})' - - def __str__(self) -> str: - return f'{self.id} {self.media_actor_id} {self.media_file_id}' - -class MediaArticle(Base, BaseMixin): - __tablename__ = 'media_article' - review = Column(Boolean) - title = Column(String) - url = Column(String, unique=True) - - -class MediaVideo(Base, BaseMixin): - __tablename__ = 'media_video' - cloud_link = Column(String) - file_name = Column(String) - path = Column(String) - review = Column(Boolean) - title = Column(String) - url = Column(String, unique=True) - should_download = Column(Boolean) - - def __repr__(self): - return f'MediaFile({self.id} {self.title} {self.url})' - - def __str__(self): - if self.title is None: - return f'{self.url}({self.id})' - else: - return f'{self.title}({self.id})' diff --git a/kontor-api/src/db/models/tysc.py b/kontor-api/src/db/models/tysc.py deleted file mode 100644 index 3a4f553..0000000 --- a/kontor-api/src/db/models/tysc.py +++ /dev/null @@ -1,99 +0,0 @@ -from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Boolean -from sqlalchemy.orm import relationship - -from src.db.models.base import Base, BaseMixin - - -class Sport(Base, BaseMixin): - __tablename__ = "sport" - __table_args__ = ( - UniqueConstraint("name"), - ) - name = Column(String, nullable=False, index=True, unique=True) - teams = relationship("Team") - positions = relationship("FieldPosition") - - -class Team(Base, BaseMixin): - __tablename__ = "team" - name = Column(String, nullable=False, index=True, unique=True) - short_name = Column(String, nullable=False, ) - sport_id = Column(String, ForeignKey("sport.id"), nullable=False) - sport = relationship("Sport", back_populates="teams") - roosters = relationship("Rooster") - - -class FieldPosition(Base, BaseMixin): - __tablename__ = "field_position" - __table_args__ = ( - UniqueConstraint("name", "sport_id"), - UniqueConstraint("short_name", "sport_id"), - ) - name = Column(String, nullable=False, index=True) - short_name = Column(String, nullable=False) - sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True) - sport = relationship("Sport", back_populates="positions") - roosters = relationship("Rooster") - - -class Player(Base, BaseMixin): - __tablename__ = "player" - __table_args__ = ( - UniqueConstraint("first_name", "last_name"), - ) - first_name = Column(String, nullable=False, index=True) - last_name = Column(String, nullable=False, index=True) - roosters = relationship("Rooster") - - def get_full_name(self) -> str: - return f"{self.last_name}, {self.first_name}" - - -class Rooster(Base, BaseMixin): - __tablename__ = "rooster" - __table_args__ = ( - UniqueConstraint("year", "team_id", "player_id", "position_id"), - ) - year = Column(Integer) - team_id = Column(String, ForeignKey("team.id"), nullable=False, index=True) - team = relationship("Team", back_populates="roosters") - player_id = Column(String, ForeignKey("player.id"), nullable=False, index=True) - player = relationship("Player", back_populates="roosters") - position_id = Column(String, ForeignKey("field_position.id"), nullable=False, index=True) - position = relationship("FieldPosition", back_populates="roosters") - cards = relationship("Card") - - -class Vendor(Base, BaseMixin): - __tablename__ = "vendor" - name = Column(String, nullable=False, unique=True, index=True) - card_sets = relationship("CardSet") - cards = relationship("Card") - - -class CardSet(Base, BaseMixin): - __tablename__ = "card_set" - __table_args__ = ( - UniqueConstraint("name", "vendor_id"), - ) - name = Column(String, index=True) - parallel_set = Column(Boolean) - insert_set = Column(Boolean) - vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False, index=True) - vendor = relationship("Vendor", back_populates="card_sets") - cards = relationship("Card") - - -class Card(Base, BaseMixin): - __tablename__ = "card" - __table_args__ = ( - UniqueConstraint("card_number", "year", "vendor_id", "card_set_id"), - ) - card_number = Column(Integer, index=True) - year = Column(Integer, index=True) - card_set_id = Column(String, ForeignKey("card_set.id"), nullable=False) - card_set = relationship("CardSet", back_populates="cards") - rooster_id = Column(String, ForeignKey("rooster.id"), nullable=False) - rooster = relationship("Rooster", back_populates="cards") - vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False) - vendor = relationship("Vendor", back_populates="cards") diff --git a/kontor-api/src/db/repository/admin.py b/kontor-api/src/db/repository/admin.py deleted file mode 100644 index cc06404..0000000 --- a/kontor-api/src/db/repository/admin.py +++ /dev/null @@ -1,10 +0,0 @@ -from typing import AnyStr, Optional - -from sqlalchemy.orm import Session - -from src.db.models.admin import Profile - - -def get_profile(username: AnyStr, db: Session) -> Optional[Profile]: - profile = db.query(Profile).filter(Profile.email == username).first() - return profile diff --git a/kontor-api/src/db/repository/comics/artist.py b/kontor-api/src/db/repository/comics/artist.py deleted file mode 100644 index ec0077e..0000000 --- a/kontor-api/src/db/repository/comics/artist.py +++ /dev/null @@ -1,46 +0,0 @@ -import uuid -from typing import List, Optional - -from sqlalchemy.orm import Session - -from src.core.log_conf import logger -from src.db.models.comic import Artist -from src.schema.comics.artist import AddArtist -from src.schema.comics.artist_details import ArtistDetailResponse, ArtistWorktypeComicResponse, ArtistWorktypeIssueResponse -from src.schema.comics.comic import ComicResponse -from src.schema.comics.worktype import WorktypeResponse - - -def get_artist_details(artist: Artist) -> ArtistDetailResponse: - comic_works: List[ArtistWorktypeComicResponse] = [] - comic_works_map = {} - for work in artist.comic_works: - worktype_id = work.work_type.id - if worktype_id in comic_works_map: - comic = ComicResponse(id=work.comic.id, title=work.comic.title, completed=work.comic.completed) - comic_works_map[worktype_id].comics.append(comic) - else: - comic_works_map[worktype_id] = ArtistWorktypeComicResponse( - worktype=WorktypeResponse(id=worktype_id, name=work.work_type.name), - comics=[ComicResponse(id=work.comic.id, title=work.comic.title, completed=work.comic.completed)] - ) - for value in comic_works_map.values(): - comic_works.append(value) - issue_works: List[ArtistWorktypeIssueResponse] = [] - response = ArtistDetailResponse( - id=artist.id, - name=str(artist.name), - weblink=str(artist.weblink), - comic_works=comic_works, - issue_works=issue_works, - ) - return response - -def update_artist(add_artist: AddArtist, artist_id: str, db: Session) -> Artist: - logger.info("update artist") - artist: Optional[Artist] = db.get(Artist, artist_id) - artist.name = add_artist.name - db.add(artist) - db.commit() - db.refresh(artist) - return artist diff --git a/kontor-api/src/db/repository/comics/comic.py b/kontor-api/src/db/repository/comics/comic.py deleted file mode 100644 index 4821d29..0000000 --- a/kontor-api/src/db/repository/comics/comic.py +++ /dev/null @@ -1,87 +0,0 @@ -from typing import Dict, List - -from sqlalchemy.orm import Session - -from src.core.log_conf import logger -from src.db.models.comic import Comic, Issue -from src.schema.comics.artist import ArtistResponse -from src.schema.comics.comic import ComicResponse, ComicSchema -from src.schema.comics.comic_details import ComicDetailsResponse, ComicWorktypeArtistResponse -from src.schema.comics.issue import IssueResponse -from src.schema.comics.issue_details import IssueDetailsResponse -from src.schema.comics.publisher import PublisherResponse -from src.schema.comics.volume import VolumeResponse -from src.schema.comics.worktype import WorktypeResponse - - -def list_comics(db: Session) -> List[Comic]: - comics = db.query(Comic).all() - return comics - - -def get_issue_details(issue: Issue) -> IssueDetailsResponse: - response = IssueDetailsResponse( - id=issue.id, - issue_number=str(issue.issue_number), - in_stock=bool(issue.in_stock), - is_read=bool(issue.is_read), - comic=ComicResponse(id=issue.comic.id, title=issue.comic.title, completed=issue.comic.completed), - volume=VolumeResponse(id=issue.volume.id, name=issue.volume.name) - ) - return response - - -def update_comic(comic: ComicSchema, comic_id: str, db: Session) -> type[Comic] | None: - logger.info(f"update_comic: {comic} with {comic_id}") - comic = db.get(Comic, comic_id) # type: ignore - return comic # type: ignore - -def get_short_info(comic: Comic) -> ComicResponse: - response = ComicResponse( - id=comic.id, - title=str(comic.title), - completed=bool(comic.completed == 1) - ) - return response - -def get_comic_details(comic: Comic) -> ComicDetailsResponse: - volumes: List[VolumeResponse] = [] - for volume in comic.volumes: - volumes.append(VolumeResponse(id=volume.id, name=volume.name)) - issues: List[IssueResponse] = [] - for issue in comic.issues: - issues.append(IssueResponse( - id=issue.id, - issue_number=issue.issue_number, - in_stock=issue.in_stock, - is_read=issue.is_read - )) - works: List[ComicWorktypeArtistResponse] = [] - works_map: Dict[str, ComicWorktypeArtistResponse] = {} - for work in comic.comic_works: - worktype_id = work.work_type.id - if worktype_id in works_map: - artist = ArtistResponse(id=work.artist.id, name=work.artist.name) - works_map[worktype_id].artists.append(artist) - logger.info(f"add artist to response map: {artist} -> {works_map}") - print(f"add artist to response map: {artist} -> {works_map}") - else: - works_map[worktype_id] = ComicWorktypeArtistResponse( - worktype=WorktypeResponse(id=worktype_id, name=work.work_type.name), - artists=[ArtistResponse(id=work.artist.id, name=work.artist.name)] - ) - for value in works_map.values(): - works.append(value) - response = ComicDetailsResponse( - id=str(comic.id), - created=str(comic.created_date), - title=str(comic.title), - completed=bool(comic.completed), - current_order=bool(comic.current_order), - weblink=str(comic.weblink), - publisher=PublisherResponse(id=comic.publisher.id, name=comic.publisher.name), - issues=issues, - volumes=volumes, - works=works - ) - return response diff --git a/kontor-api/src/db/repository/comics/publisher.py b/kontor-api/src/db/repository/comics/publisher.py deleted file mode 100644 index a17da64..0000000 --- a/kontor-api/src/db/repository/comics/publisher.py +++ /dev/null @@ -1,24 +0,0 @@ -from typing import List - -from src.db.models.comic import Publisher -from src.schema.comics.comic import ComicResponse -from src.schema.comics.publisher import PublisherResponse -from src.schema.comics.publisher_details import PublisherDetailsResponse - - -def get_publisher_details(publisher: Publisher) -> PublisherDetailsResponse: - imprints: List[PublisherResponse] = [] - for imprint in publisher.imprints: - imprints.append(PublisherResponse(id=imprint.id, name=str(imprint.name))) - comics: List[ComicResponse] = [] - for comic in publisher.comics: - comics.append( - ComicResponse(id=comic.id, title=comic.title, completed=comic.completed) - ) - parent_publisher: PublisherResponse | None = None - if publisher.parent_publisher: - parent_publisher = PublisherResponse(id=publisher.parent_publisher.id, name=str(publisher.parent_publisher.name)) - response: PublisherDetailsResponse = PublisherDetailsResponse( - id=publisher.id, name=str(publisher.name), parent_publisher=parent_publisher, imprints=imprints, comics=comics - ) - return response diff --git a/kontor-api/src/db/repository/comics/worktype.py b/kontor-api/src/db/repository/comics/worktype.py deleted file mode 100644 index cb545ad..0000000 --- a/kontor-api/src/db/repository/comics/worktype.py +++ /dev/null @@ -1,32 +0,0 @@ -import uuid -from datetime import datetime -from typing import AnyStr - -from sqlalchemy.orm import Session - -from src.core.log_conf import logger -from src.db.models.comic import WorkType -from src.schema.comics.worktype import AddWorkType - - -def create_new_worktype(work: AddWorkType, db: Session) -> WorkType: - worktype = WorkType() - worktype.id = str(uuid.uuid4()) - worktype.created_date = datetime.now() - worktype.last_modified_date = datetime.now() - worktype.name = work.worktype - db.add(worktype) - db.commit() - db.refresh(worktype) - logger.info(f"create_new_worktype: {worktype}") - return worktype - - -def update_worktype(work: AddWorkType, worktype_id: AnyStr, db: Session) -> WorkType: - logger.info("update worktype") - worktype = db.get(WorkType, worktype_id) - worktype.name = work.worktype - db.add(worktype) - db.commit() - db.refresh(worktype) - return worktype diff --git a/kontor-api/src/db/repository/media.py b/kontor-api/src/db/repository/media.py deleted file mode 100644 index e7f3acd..0000000 --- a/kontor-api/src/db/repository/media.py +++ /dev/null @@ -1,86 +0,0 @@ -from sqlalchemy.orm import Session -import uuid -from datetime import datetime -from src.core.log_conf import logger -from src.db.models.media import MediaActor, MediaActorFile, MediaFile, MediaVideo -from src.schema.media.actor import Actor -from src.webapps.media.forms import AddLinkForm - - -def create_new_video(video: AddLinkForm, db: Session) -> MediaVideo: - print(video.url) - media_video = MediaVideo() - media_video.id = str(uuid.uuid4()) - media_video.url = video.url # type: ignore - media_video.created_date = datetime.now() - media_video.last_modified_date = datetime.now() - media_video.review = True # type: ignore - media_video.should_download = True # type: ignore - db.add(media_video) - db.commit() - db.refresh(media_video) - print(media_video) - return media_video - -def create_new_mediafile(link: str, db: Session) -> MediaFile: - logger.info("create MediaFile with url {link}") - media_file: MediaFile = MediaFile() - media_file.id = str(uuid.uuid4()) - media_file.url = link # type: ignore - media_file.created_date = datetime.now() - media_file.last_modified_date = datetime.now() - media_file.version = 0 - media_file.review = True - media_file.should_download = True - db.add(media_file) - db.commit() - db.refresh(media_file) - logger.info(f"created {media_file}") - return media_file - -def delete_mediafile(db: Session, media_file_id: str): - logger.info(f"delete MediaFile with id {media_file_id}") - media_file = db.get(MediaFile, media_file_id) - db.delete(media_file) - db.commit() - -def create_new_mediaactor(new_actor: Actor, db: Session) -> MediaActor: - logger.info(f"create MediaActor with url {new_actor.url}") - media_actor: MediaActor = MediaActor() - media_actor.id = str(uuid.uuid4()) - media_actor.name = str(new_actor.name) # type: ignore - media_actor.url = str(new_actor.url) # type: ignore - media_actor.created_date = datetime.now() - media_actor.last_modified_date = datetime.now() - media_actor.version = 0 - db.add(media_actor) - db.commit() - db.refresh(media_actor) - logger.info(f"created {media_actor}") - return media_actor - -def delete_mediaactor(db: Session, actor_id: str): - logger.info(f"delete MediaActor with id {actor_id}") - media_actor = db.get(MediaActor, actor_id) - db.delete(media_actor) - db.commit() - -def create_new_mediaactorfile(db: Session, actor_id: str, file_id: str) -> MediaActorFile: - logger.info(f"create MediaActorFile with actor {actor_id} and file {file_id}") - media_actor_file: MediaActorFile = MediaActorFile() - media_actor_file.id = str(uuid.uuid4()) - media_actor_file.created_date = datetime.now() - media_actor_file.last_modified_date = datetime.now() - media_actor_file.version = 0 - media_actor_file.media_actor_id = actor_id # type: ignore - media_actor_file.media_file_id = file_id # type: ignore - db.add(media_actor_file) - db.commit() - db.refresh(media_actor_file) - return media_actor_file - -def delete_mediaactorfile(db: Session, actorfile_id: str): - logger.info(f"delete MediaActorFile with id {actorfile_id}") - media_actorfile = db.get(MediaActorFile, actorfile_id) - db.delete(media_actorfile) - db.commit() \ No newline at end of file diff --git a/kontor-api/src/db/repository/user.py b/kontor-api/src/db/repository/user.py new file mode 100644 index 0000000..96deafa --- /dev/null +++ b/kontor-api/src/db/repository/user.py @@ -0,0 +1,42 @@ +from datetime import datetime +from typing import Optional +import uuid +from src.core.log_conf import logger +from kontor_model.db.models.admin import Assignment, Profile +from sqlalchemy.orm import Session + +from kontor_model.schema.user.profile import ProfileModel + + +def create_new_profile(new_profile: ProfileModel, db: Session) -> Profile: + logger.info(f"create MediaActor with url {new_profile.username}") + profile: Profile = Profile() + profile.id = str(uuid.uuid4()) + profile.user_name = new_profile.username + profile.first_name = new_profile.first_name + profile.last_name = new_profile.last_name + profile.created_date = datetime.now() + profile.last_modified_date = datetime.now() + profile.version = 0 + db.add(profile) + db.commit() + db.refresh(profile) + logger.info(f"created {profile}") + return profile + +def delete_profile(db: Session, profile_id: str): + logger.info(f"delete Profile with id {profile_id}") + profile: Optional[Profile] = db.get(Profile, profile_id) + if profile is not None: + assignments = profile.assignments + for assignment in assignments: + delete_assignment(db, assignment.id) + db.delete(profile) + db.commit() + +def delete_assignment(db: Session, assignment_id: str) -> None: + logger.info(f"delete Assignment with id {assignment_id}") + assignment: Optional[Assignment] = db.get(Assignment, assignment_id) + if assignment is not None: + db.delete(assignment) + db.commit() diff --git a/kontor-api/src/db/session.py b/kontor-api/src/db/session.py index db8c1c0..43c732e 100644 --- a/kontor-api/src/db/session.py +++ b/kontor-api/src/db/session.py @@ -12,8 +12,10 @@ engine = create_engine(SQLALCHEMY_DATABASE_URL) SessionLocal = sessionmaker(bind=engine) -def get_db() -> Generator: +def get_db() -> Generator[Session, None, None]: + """ """ with SessionLocal() as db: yield db -SessionDep: type[Session] = Annotated[Session, Depends(get_db)] + +SessionDep = Annotated[Session, Depends(get_db)] diff --git a/kontor-api/src/main.py b/kontor-api/src/main.py index b0301f2..f1e715d 100644 --- a/kontor-api/src/main.py +++ b/kontor-api/src/main.py @@ -6,10 +6,11 @@ from fastapi.staticfiles import StaticFiles from src.apis.base import api_router from src.apis.version1.healthcheck import health_router -from src.apis.version1.login import login_router +from src.apis.version1.admin.login import login_router from src.core.config import settings from src.core.log_conf import logger -from src.db.models.base import Base +from src.core.middleware import RequestLoggingMiddleware +from kontor_model.db.models.base import Base from src.db.session import engine from src.db.utils import check_db_connected, check_db_disconnected from src.webapps.base import api_router as web_app_router @@ -23,10 +24,10 @@ async def lifespan(app: FastAPI): def include_router(app: FastAPI): - app.include_router(api_router) - app.include_router(web_app_router) - app.include_router(health_router) - app.include_router(login_router) + app.include_router(api_router, tags=["api"]) + app.include_router(web_app_router, tags=["webapp"]) + app.include_router(health_router, tags=["admin"]) + app.include_router(login_router, tags=["webapp"]) def configure_static(app: FastAPI): @@ -41,6 +42,7 @@ def add_middle_ware(app: FastAPI): allow_methods=["*"], allow_headers=["*"], ) + app.add_middleware(RequestLoggingMiddleware) def create_tables(): diff --git a/kontor-api/src/schema/admin.py b/kontor-api/src/schema/admin.py deleted file mode 100644 index 5f9c3b4..0000000 --- a/kontor-api/src/schema/admin.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Optional, List - -from pydantic import BaseModel - - -class Token(BaseModel): - access_token: str - token_type: str - - -class TokenData(BaseModel): - username: Optional[str] = None - scopes: List[str] = [] - - -class ProfileModel(BaseModel): - username: str - email: str - first_name: str - last_name: str - active: bool - -class HealthCheck(BaseModel): - """ - Health check model - """ - status: str = "ok" diff --git a/kontor-api/src/schema/comics/artist.py b/kontor-api/src/schema/comics/artist.py deleted file mode 100644 index e369737..0000000 --- a/kontor-api/src/schema/comics/artist.py +++ /dev/null @@ -1,14 +0,0 @@ -from pydantic import BaseModel - - -class ArtistCreation(BaseModel): - id: str - name: str - -class ArtistResponse(BaseModel): - id: str - name: str - -class AddArtist(BaseModel): - id: str - name: str diff --git a/kontor-api/src/schema/comics/artist_details.py b/kontor-api/src/schema/comics/artist_details.py deleted file mode 100644 index 416257c..0000000 --- a/kontor-api/src/schema/comics/artist_details.py +++ /dev/null @@ -1,22 +0,0 @@ -from typing import List -from pydantic import BaseModel - -from src.schema.comics.comic import ComicResponse -from src.schema.comics.issue_details import IssueDetailsResponse -from src.schema.comics.worktype import WorktypeResponse - - -class ArtistWorktypeComicResponse(BaseModel): - worktype: WorktypeResponse - comics: List[ComicResponse] - -class ArtistWorktypeIssueResponse(BaseModel): - worktype: WorktypeResponse - issues: List[IssueDetailsResponse] - -class ArtistDetailResponse(BaseModel): - id: str - name: str - weblink: str - comic_works: List[ArtistWorktypeComicResponse] - issue_works: List[ArtistWorktypeIssueResponse] diff --git a/kontor-api/src/schema/comics/comic.py b/kontor-api/src/schema/comics/comic.py deleted file mode 100644 index a57c7ff..0000000 --- a/kontor-api/src/schema/comics/comic.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import Optional -from pydantic import BaseModel, AnyUrl -from src.core.log_conf import logger - - -class ComicResponse(BaseModel): - id: str - title: str - completed: bool - - -class ComicSchema(BaseModel): - id: str - title: str - weblink: Optional[AnyUrl] - completed: Optional[bool] - current_order: Optional[bool] diff --git a/kontor-api/src/schema/comics/comic_details.py b/kontor-api/src/schema/comics/comic_details.py deleted file mode 100644 index 16de453..0000000 --- a/kontor-api/src/schema/comics/comic_details.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import List -from pydantic import BaseModel - -from src.schema.comics.artist import ArtistResponse -from src.schema.comics.issue import IssueResponse -from src.schema.comics.publisher import PublisherResponse -from src.schema.comics.volume import VolumeResponse -from src.schema.comics.worktype import WorktypeResponse - - -class ComicWorktypeArtistResponse(BaseModel): - worktype: WorktypeResponse - artists: List[ArtistResponse] - - -class ComicDetailsResponse(BaseModel): - id: str - created: str - title: str - completed : bool - current_order : bool - weblink: str - publisher: PublisherResponse - issues: List[IssueResponse] - volumes: List[VolumeResponse] - works: List[ComicWorktypeArtistResponse] diff --git a/kontor-api/src/schema/comics/issue.py b/kontor-api/src/schema/comics/issue.py deleted file mode 100644 index 719114c..0000000 --- a/kontor-api/src/schema/comics/issue.py +++ /dev/null @@ -1,8 +0,0 @@ -from pydantic import BaseModel - - -class IssueResponse(BaseModel): - id: str - issue_number: str - in_stock: bool - is_read: bool diff --git a/kontor-api/src/schema/comics/issue_details.py b/kontor-api/src/schema/comics/issue_details.py deleted file mode 100644 index 3c39799..0000000 --- a/kontor-api/src/schema/comics/issue_details.py +++ /dev/null @@ -1,13 +0,0 @@ -from pydantic import BaseModel - -from src.schema.comics.comic import ComicResponse -from src.schema.comics.volume import VolumeResponse - - -class IssueDetailsResponse(BaseModel): - id: str - issue_number: str - in_stock: bool - is_read: bool - comic: ComicResponse - volume: VolumeResponse | None diff --git a/kontor-api/src/schema/comics/publisher.py b/kontor-api/src/schema/comics/publisher.py deleted file mode 100644 index bbbe175..0000000 --- a/kontor-api/src/schema/comics/publisher.py +++ /dev/null @@ -1,6 +0,0 @@ -from pydantic import BaseModel - - -class PublisherResponse(BaseModel): - id: str - name: str diff --git a/kontor-api/src/schema/comics/publisher_details.py b/kontor-api/src/schema/comics/publisher_details.py deleted file mode 100644 index 5c4444e..0000000 --- a/kontor-api/src/schema/comics/publisher_details.py +++ /dev/null @@ -1,14 +0,0 @@ -from typing import List - -from pydantic import BaseModel - -from src.schema.comics.comic import ComicResponse -from src.schema.comics.publisher import PublisherResponse - - -class PublisherDetailsResponse(BaseModel): - id: str - name: str - parent_publisher: PublisherResponse | None - imprints: List[PublisherResponse] - comics: List[ComicResponse] diff --git a/kontor-api/src/schema/comics/volume.py b/kontor-api/src/schema/comics/volume.py deleted file mode 100644 index 81d7985..0000000 --- a/kontor-api/src/schema/comics/volume.py +++ /dev/null @@ -1,6 +0,0 @@ -from pydantic import BaseModel - - -class VolumeResponse(BaseModel): - id: str - name: str diff --git a/kontor-api/src/schema/comics/worktype.py b/kontor-api/src/schema/comics/worktype.py deleted file mode 100644 index a072938..0000000 --- a/kontor-api/src/schema/comics/worktype.py +++ /dev/null @@ -1,9 +0,0 @@ -from pydantic import BaseModel - -class AddWorkType(BaseModel): - worktype: str - -class WorktypeResponse(BaseModel): - id: str - name: str - diff --git a/kontor-api/src/schema/media/actor.py b/kontor-api/src/schema/media/actor.py deleted file mode 100644 index 3ad8408..0000000 --- a/kontor-api/src/schema/media/actor.py +++ /dev/null @@ -1,18 +0,0 @@ -from datetime import datetime - -from src.db.models.media import MediaActor -from pydantic import BaseModel - - -class MediaActorResponse(BaseModel): - id: str - name: str | None - url: str - -class Actor(BaseModel): - name: str | None - url: str - -def get_actor_details(media_actor: MediaActor) -> MediaActorResponse: - reponse: MediaActorResponse = MediaActorResponse(id=media_actor.id, name=str(media_actor.name), url=str(media_actor.url)) - return reponse diff --git a/kontor-api/src/schema/media/actorfile.py b/kontor-api/src/schema/media/actorfile.py deleted file mode 100644 index 9d135f1..0000000 --- a/kontor-api/src/schema/media/actorfile.py +++ /dev/null @@ -1,16 +0,0 @@ -from datetime import datetime - -from src.db.models.media import MediaActorFile, MediaFile -from pydantic import BaseModel - - -class MediaActorFileResponse(BaseModel): - id: str - file_id: str - actor_id: str - -def get_actorfile_details(media_actorfile: MediaActorFile) -> MediaActorFileResponse: - response: MediaActorFileResponse = MediaActorFileResponse(id=media_actorfile.id, - file_id=str(media_actorfile.media_file_id), - actor_id=str(media_actorfile.media_actor_id)) - return response diff --git a/kontor-api/src/schema/media/file.py b/kontor-api/src/schema/media/file.py deleted file mode 100644 index 32de2c6..0000000 --- a/kontor-api/src/schema/media/file.py +++ /dev/null @@ -1,38 +0,0 @@ -from datetime import datetime - -from src.db.models.media import MediaFile -from pydantic import BaseModel - - -class MediaFileResponse(BaseModel): - id: str - title: str | None = None - file_name: str | None = None - cloud_link: str | None = None - url: str | None = None - review: bool = False - should_download: bool = False - -class Link(BaseModel): - url: str - -def get_file_details(mediafile: MediaFile) -> MediaFileResponse: - response = MediaFileResponse(id=mediafile.id, - title=mediafile.title, - file_name=mediafile.file_name, - cloud_link=mediafile.cloud_link, - url=str(mediafile.url), - review=mediafile.review, - should_download=mediafile.should_download) - #print(f"id: {mediafile.id}: review: {response.review} <- {mediafile.review}") - #print(f"id: {mediafile.id}: download: {response.should_download} <- {mediafile.should_download}") - return response - -def set_file(model: MediaFileResponse, mediafile: MediaFile) -> None: - mediafile.file_name = model.file_name - mediafile.cloud_link = model.cloud_link # type: ignore - mediafile.url = model.url # type: ignore - mediafile.title = model.title - mediafile.last_modified_date = datetime.now() - mediafile.review = model.review - mediafile.should_download = model.should_download diff --git a/kontor-api/src/schema/media/video.py b/kontor-api/src/schema/media/video.py deleted file mode 100644 index ed4319a..0000000 --- a/kontor-api/src/schema/media/video.py +++ /dev/null @@ -1,5 +0,0 @@ -from pydantic import BaseModel - - -class AddLink(BaseModel): - url: str diff --git a/kontor-api/src/schema/tysc/sport.py b/kontor-api/src/schema/tysc/sport.py deleted file mode 100644 index 017d169..0000000 --- a/kontor-api/src/schema/tysc/sport.py +++ /dev/null @@ -1,8 +0,0 @@ - -from typing import AnyStr -from pydantic import BaseModel - - -class SportResponse(BaseModel): - id: AnyStr - name: str diff --git a/kontor-api/src/templates/media/add_lofi_link.html b/kontor-api/src/templates/media/add_lofi_link.html new file mode 100644 index 0000000..f38bbb1 --- /dev/null +++ b/kontor-api/src/templates/media/add_lofi_link.html @@ -0,0 +1,29 @@ +{% extends "shared/base.html" %} + + +{% block title %} + Add a Lofi Link +{% endblock %} + +{% block content %} +
+
+
+ {% for error in errors %} +
  • {{error}}
  • + {% endfor %} +
    +
    + +
    +

    Add a Lofi Link

    +
    +
    + +
    + +
    +
    +
    +{% endblock %} + diff --git a/kontor-api/src/templates/media/lofi_detail.html b/kontor-api/src/templates/media/lofi_detail.html new file mode 100644 index 0000000..e6397db --- /dev/null +++ b/kontor-api/src/templates/media/lofi_detail.html @@ -0,0 +1,51 @@ +{% extends "shared/base.html" %} + + +{% block title %} + MediaLofi Detail +{% endblock %} + +{% block content %} +
    +
    +
    +

    MediaLofi Detail

    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MediaLofi Title{{medialofi.title}}
    MediaLofi URL{{medialofi.url}}
    MediaLofi Download?{{medialofi.should_download}}
    MediaLofi Review?{{medialofi.review}}
    Data Created{{medialofi.created_date}}
    Data Modified{{medialofi.last_modified_date}}
    Data Version{{medialofi.version}}
    +
    +
    +{% endblock %} diff --git a/kontor-api/src/templates/media/lofi_list.html b/kontor-api/src/templates/media/lofi_list.html new file mode 100644 index 0000000..76d3de4 --- /dev/null +++ b/kontor-api/src/templates/media/lofi_list.html @@ -0,0 +1,29 @@ +{% extends "shared/base.html" %} + +{% block title %} + Lofi Links +{% endblock %} + +{% block content %} + {% with msg=msg %} + {% include "components/alerts.html" %} + {% endwith %} +
    + + + + + + + + {% for medialofi in medialofis %} + + + + + + {% endfor %} + +
    TitelReviewDownload
    {{medialofi.title}}{% with check=medialofi.review %}{% include "components/check.html" %}{% endwith %}{% with check=medialofi.should_download %}{% include "components/check.html" %}{% endwith %}
    +
    +{% endblock %} diff --git a/kontor-api/src/templates/media/media_nav.html b/kontor-api/src/templates/media/media_nav.html index 104176b..a9758ac 100644 --- a/kontor-api/src/templates/media/media_nav.html +++ b/kontor-api/src/templates/media/media_nav.html @@ -2,4 +2,5 @@ MediaFiles MediaActors MediaVideos + MediaLofi diff --git a/kontor-api/src/webapps/admin/route_admin.py b/kontor-api/src/webapps/admin/route_admin.py index 0e7f611..114ad09 100644 --- a/kontor-api/src/webapps/admin/route_admin.py +++ b/kontor-api/src/webapps/admin/route_admin.py @@ -2,7 +2,7 @@ from typing import Optional from fastapi import APIRouter, Request from fastapi.templating import Jinja2Templates -from src.db.models.admin import Permission, Profile +from kontor_model.db.models.admin import Permission, Profile from src.db.session import SessionDep templates = Jinja2Templates(directory="src/templates") diff --git a/kontor-api/src/webapps/auth/route_login.py b/kontor-api/src/webapps/auth/route_login.py index a3c54e9..5d65a67 100644 --- a/kontor-api/src/webapps/auth/route_login.py +++ b/kontor-api/src/webapps/auth/route_login.py @@ -1,9 +1,5 @@ -# from src.apis.version1.admin import login_for_access_token -from fastapi.security import OAuth2PasswordRequestForm - -from src.apis.version1.admin import login_for_token_cookie -from src.db.session import SessionDep -from fastapi import APIRouter, Depends +from src.apis.version1.admin.login import login_for_token_cookie +from fastapi import APIRouter from fastapi import HTTPException from fastapi import Request from fastapi.templating import Jinja2Templates @@ -20,7 +16,7 @@ def login(request: Request): @router.post("/login/") -async def login(request: Request): +async def validate_login(request: Request): form = LoginForm(request) await form.load_data() if await form.is_valid(): @@ -31,6 +27,8 @@ async def login(request: Request): return response except HTTPException: form.__dict__.update(msg="") - form.__dict__.get("errors").append("Incorrect Email or Password") + errors = form.__dict__.get("errors") + if errors: + errors.append("Incorrect Email or Password") return templates.TemplateResponse("auth/login.html", form.__dict__) return templates.TemplateResponse("auth/login.html", form.__dict__) \ No newline at end of file diff --git a/kontor-api/src/webapps/base.py b/kontor-api/src/webapps/base.py index 3206a94..16a1ad0 100644 --- a/kontor-api/src/webapps/base.py +++ b/kontor-api/src/webapps/base.py @@ -4,20 +4,21 @@ from fastapi.templating import Jinja2Templates from src.webapps.admin import route_admin from src.webapps.auth import route_login from src.webapps.comic import route_comics, route_worktype, route_artists -from src.webapps.media import route_actors, route_media, route_videos +from src.webapps.media import route_actors, route_lofi, route_media, route_videos templates = Jinja2Templates(directory="src/templates") api_router = APIRouter() -api_router.include_router(route_comics.router) -api_router.include_router(route_artists.router) -api_router.include_router(route_worktype.router) -api_router.include_router(route_media.router) -api_router.include_router(route_actors.router) -api_router.include_router(route_videos.router) -api_router.include_router(route_login.router) -api_router.include_router(route_admin.router) +api_router.include_router(route_comics.router, tags=["webapp"]) +api_router.include_router(route_artists.router, tags=["webapp"]) +api_router.include_router(route_worktype.router, tags=["webapp"]) +api_router.include_router(route_media.router, tags=["webapp"]) +api_router.include_router(route_actors.router, tags=["webapp"]) +api_router.include_router(route_videos.router, tags=["webapp"]) +api_router.include_router(route_lofi.router, tags=["webapp"]) +api_router.include_router(route_login.router, tags=["webapp"]) +api_router.include_router(route_admin.router, tags=["webapp"]) -@api_router.get("/") +@api_router.get("/", tags=["webapp"]) def home(request: Request, msg: str | None = None): return templates.TemplateResponse("index.html", {"request": request, "msg": msg}) diff --git a/kontor-api/src/webapps/comic/route_artists.py b/kontor-api/src/webapps/comic/route_artists.py index d6735d9..94d2729 100644 --- a/kontor-api/src/webapps/comic/route_artists.py +++ b/kontor-api/src/webapps/comic/route_artists.py @@ -2,14 +2,13 @@ from fastapi import APIRouter, Request, status, Form from fastapi.templating import Jinja2Templates from fastapi.responses import RedirectResponse -from src.db.models.comic import Artist +from kontor_model.db.models.comic import Artist from typing import AnyStr -from src.db.repository.comics.artist import update_artist +from kontor_model.db.repository.comics.artist import update_artist from src.db.session import SessionDep #from src.db.repository.comic import create_new_worktype, update_worktype -from src.main import logger -from src.schema.comics.artist import AddArtist +from kontor_model.schema.comics.artist import AddArtist from src.webapps.comic.forms.artist import AddArtistForm #from src.schema.comics.worktype import AddWorkType @@ -35,7 +34,7 @@ def edit_artist(db: SessionDep, request: Request, artist_id: str): return templates.TemplateResponse("comic/artist_edit.html", {"request": request, "artist_name": artist.name, "artist_link": artist.weblink}) @router.post("/artist/edit/{artist_id}") -async def edit_artist(request: Request, db: SessionDep, artist_id: str, action: str = Form(...), artist_name: str = Form(...), artist_link: str = Form(...)): +async def edit_artist_post(request: Request, db: SessionDep, artist_id: str, action: str = Form(...), artist_name: str = Form(...), artist_link: str = Form(...)): if action == "cancel": return RedirectResponse(f"/comic/artists/{artist_id}", status_code=status.HTTP_303_SEE_OTHER) form = AddArtistForm(request, artist_id, artist_name, artist_link) diff --git a/kontor-api/src/webapps/comic/route_comics.py b/kontor-api/src/webapps/comic/route_comics.py index 6dd4725..cb1c572 100644 --- a/kontor-api/src/webapps/comic/route_comics.py +++ b/kontor-api/src/webapps/comic/route_comics.py @@ -2,16 +2,16 @@ from fastapi import APIRouter, Form, Request, status from fastapi.templating import Jinja2Templates from fastapi.responses import RedirectResponse -from src.db.models.comic import Comic, Publisher, Issue +from kontor_model.db.models.comic import Comic, Publisher, Issue from typing import AnyStr from src.core.log_conf import logger -from src.db.repository.comics.comic import update_comic +from kontor_model.db.repository.comics.comic import update_comic from src.db.session import SessionDep -from src.schema.comics.comic import ComicSchema +from kontor_model.schema.comics.comic import ComicSchema from src.webapps.comic.forms.comic import ValidateComicForm templates = Jinja2Templates(directory="src/templates") -router = APIRouter(include_in_schema=False, prefix="/comic") +router = APIRouter(include_in_schema=True, prefix="/comic") @router.get("/comics") def get_comics(db: SessionDep, request: Request, msg: str | None = None): @@ -58,7 +58,7 @@ async def validate_comic(request: Request, db: SessionDep, comic_id: str, action if form.is_valid(): try: comic = ComicSchema(**form.__dict__) - comic = update_comic(comic=comic, comic_id=comic_id, db=db) + comic = update_comic(new_comic=comic, comic_id=comic_id, db=db) return RedirectResponse(f"/comic/comics/{comic.id}", status_code=status.HTTP_303_SEE_OTHER) except Exception as e: print(e) diff --git a/kontor-api/src/webapps/comic/route_worktype.py b/kontor-api/src/webapps/comic/route_worktype.py index 365dc76..bff9025 100644 --- a/kontor-api/src/webapps/comic/route_worktype.py +++ b/kontor-api/src/webapps/comic/route_worktype.py @@ -2,13 +2,13 @@ from fastapi import APIRouter, Request, status from fastapi.templating import Jinja2Templates from fastapi.responses import RedirectResponse -from src.db.models.comic import WorkType +from kontor_model.db.models.comic import WorkType from typing import AnyStr -from src.db.repository.comics.worktype import create_new_worktype, update_worktype +from kontor_model.db.repository.comics.worktype import create_new_worktype, update_worktype from src.db.session import SessionDep from src.main import logger -from src.schema.comics.worktype import AddWorkType +from kontor_model.schema.comics.worktype import AddWorkType from src.webapps.comic.forms.worktype import AddWorktypeForm templates = Jinja2Templates(directory="src/templates") diff --git a/kontor-api/src/webapps/media/forms.py b/kontor-api/src/webapps/media/forms.py index 142f978..333f5e3 100644 --- a/kontor-api/src/webapps/media/forms.py +++ b/kontor-api/src/webapps/media/forms.py @@ -10,7 +10,7 @@ class AddLinkForm: async def load_data(self): form = await self.request.form() - self.url = form.get("url") + self.url = str(form.get("url")) def is_valid(self): if not self.url or not (self.url.__contains__("http")): diff --git a/kontor-api/src/webapps/media/route_actors.py b/kontor-api/src/webapps/media/route_actors.py index 63bcce8..9624e3a 100644 --- a/kontor-api/src/webapps/media/route_actors.py +++ b/kontor-api/src/webapps/media/route_actors.py @@ -2,7 +2,7 @@ from typing import AnyStr from fastapi import APIRouter, Request from fastapi.templating import Jinja2Templates -from src.db.models.media import MediaActor +from kontor_model.db.models.media import MediaActor from src.db.session import SessionDep templates = Jinja2Templates(directory="src/templates") diff --git a/kontor-api/src/webapps/media/route_lofi.py b/kontor-api/src/webapps/media/route_lofi.py new file mode 100644 index 0000000..9b934a7 --- /dev/null +++ b/kontor-api/src/webapps/media/route_lofi.py @@ -0,0 +1,51 @@ +from typing import Optional + +from fastapi import APIRouter, Request, status, responses +from fastapi.security.utils import get_authorization_scheme_param +from fastapi.templating import Jinja2Templates + +from src.core.security import get_current_user_from_token +from kontor_model.db.models.media import MediaLofi +from kontor_model.db.models.admin import Profile +from kontor_model.db.repository.media.lofi import create_new_lofi +from src.db.session import SessionDep +from src.webapps.media.forms import AddLinkForm + +templates = Jinja2Templates(directory="src/templates") +router = APIRouter(include_in_schema=False, prefix="/media") + +@router.get("/lofi") +def get_medialofis(db: SessionDep, request: Request, msg: Optional[str] = None): + medialofis = db.query(MediaLofi).all() + try: + token = request.cookies.get("access_token") + _, param = get_authorization_scheme_param(token) # scheme will hold "Bearer" and param will hold actual token value + current_user: Profile = get_current_user_from_token(token=param) + return templates.TemplateResponse("media/lofi_list.html", {"request": request, "msg": msg, "user": current_user, "medialofis": medialofis}) + except Exception as e: + print(e) + return templates.TemplateResponse("media/lofi_list.html", {"request": request, "msg": msg, "user": None, "medialofis": medialofis}) + +@router.get("/lofi/{lofi_id}") +def lofi_details(lofi_id: str, request: Request, db: SessionDep): + medialofi = db.get(MediaLofi, lofi_id) + return templates.TemplateResponse("media/lofi_detail.html", {"request": request, "medialofi":medialofi}) + +@router.get("/add-lofi") +def add_lofi_link(request: Request, db: SessionDep): + return templates.TemplateResponse("media/add_lofi_link.html", {"request": request}) + +@router.post("/add-lofi") +async def post_lofi_link(request: Request, db: SessionDep): + form = AddLinkForm(request) + await form.load_data() + if form.is_valid(): + try: + #video = AddLink(**form.__dict__) + medialofi = create_new_lofi(url=str(form.url), db=db) + return responses.RedirectResponse(f"media/lofi/{medialofi.id}", status_code=status.HTTP_302_FOUND) + except Exception as e: + print(e) + form.__dict__.get("errors").append("Link already added") + return templates.TemplateResponse("media/add_lofi_link.html", form.__dict__) + return templates.TemplateResponse("media/add_lofi_link.html", form.__dict__) diff --git a/kontor-api/src/webapps/media/route_media.py b/kontor-api/src/webapps/media/route_media.py index 9b1e7a8..1ffbefd 100644 --- a/kontor-api/src/webapps/media/route_media.py +++ b/kontor-api/src/webapps/media/route_media.py @@ -6,8 +6,8 @@ from fastapi.templating import Jinja2Templates from sqlalchemy import or_ from src.core.security import get_current_user_from_token -from src.db.models.admin import Profile -from src.db.models.media import MediaFile +from kontor_model.db.models.admin import Profile +from kontor_model.db.models.media import MediaFile from src.core.log_conf import logger from src.db.session import SessionDep @@ -37,7 +37,7 @@ def get_mediafiles(db: SessionDep, request: Request, msg: str | None = None): try: token = request.cookies.get("access_token") scheme, param = get_authorization_scheme_param(token) # scheme will hold "Bearer" and param will hold actual token value - current_user: Profile = get_current_user_from_token(token=param) + #current_user: Profile = get_current_user_from_token(token=param) return templates.TemplateResponse("media/files.html", {"request": request, "msg": msg, "mediafiles": mediafiles}) except Exception as e: print(e) diff --git a/kontor-api/src/webapps/media/route_videos.py b/kontor-api/src/webapps/media/route_videos.py index 5e70d39..b4c3cd2 100644 --- a/kontor-api/src/webapps/media/route_videos.py +++ b/kontor-api/src/webapps/media/route_videos.py @@ -1,25 +1,26 @@ +from typing import Optional + from fastapi import APIRouter, Request, status, responses from fastapi.security.utils import get_authorization_scheme_param from fastapi.templating import Jinja2Templates from src.core.security import get_current_user_from_token -from src.db.models.media import MediaVideo -from src.db.repository.media import create_new_video -from src.db.models.admin import Profile +from kontor_model.db.models.media import MediaVideo +from kontor_model.db.models.admin import Profile +from kontor_model.db.repository.media.video import create_new_video from src.db.session import SessionDep -from src.schema.media.video import AddLink from src.webapps.media.forms import AddLinkForm templates = Jinja2Templates(directory="src/templates") router = APIRouter(include_in_schema=False, prefix="/media") @router.get("/videos") -def get_mediavideos(db: SessionDep, request: Request, msg: str = None): +def get_mediavideos(db: SessionDep, request: Request, msg: Optional[str] = None): mediavideos = db.query(MediaVideo).all() try: token = request.cookies.get("access_token") _, param = get_authorization_scheme_param(token) # scheme will hold "Bearer" and param will hold actual token value - current_user: Profile = get_current_user_from_token(token=param, db=db) + current_user: Profile = get_current_user_from_token(token=param) return templates.TemplateResponse("media/videos.html", {"request": request, "msg": msg, "user": current_user, "mediavideos": mediavideos}) except Exception as e: print(e) @@ -40,8 +41,8 @@ async def post_video_link(request: Request, db: SessionDep): await form.load_data() if form.is_valid(): try: - video = AddLink(**form.__dict__) - mediavideo = create_new_video(video=video, db=db) + #video = AddLink(**form.__dict__) + mediavideo = create_new_video(url=str(form.url), db=db) return responses.RedirectResponse(f"media/videos/{mediavideo.id}", status_code=status.HTTP_302_FOUND) except Exception as e: print(e) diff --git a/kontor-api/tests/conftest.py b/kontor-api/tests/conftest.py index 6a1146e..ffb24d6 100644 --- a/kontor-api/tests/conftest.py +++ b/kontor-api/tests/conftest.py @@ -8,10 +8,10 @@ import pytest from fastapi import FastAPI from fastapi.testclient import TestClient from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm import Session, sessionmaker from src.apis.base import api_router -from src.db.models.base import Base +from kontor_model.db.models.base import Base from src.db.session import get_db sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) @@ -45,7 +45,7 @@ def app() -> Generator[FastAPI, Any, None]: @pytest.fixture(scope="module") -def db_session(app: FastAPI) -> Generator[SessionTesting, Any, None]: +def db_session(app: FastAPI) -> Generator[Session, Any, None]: connection = engine.connect() transaction = connection.begin() session = SessionTesting(bind=connection) @@ -57,7 +57,7 @@ def db_session(app: FastAPI) -> Generator[SessionTesting, Any, None]: @pytest.fixture(scope="module") def client( - app: FastAPI, db_session: SessionTesting + app: FastAPI, db_session: Session ) -> Generator[TestClient, Any, None]: """ Create a new FastAPI TestClient that uses the `db_session` fixture to override diff --git a/kontor-api/uv.lock b/kontor-api/uv.lock index 8172823..0669c43 100644 --- a/kontor-api/uv.lock +++ b/kontor-api/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 2 +revision = 3 requires-python = ">=3.13" [[package]] @@ -9,18 +9,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/13/7d/8bca2bf9a247c2c5dfeec1d7a5f40db6518f88d314b8bca9da29670d2671/aiosqlite-0.21.0.tar.gz", hash = "sha256:131bb8056daa3bc875608c631c678cda73922a2d4ba8aec373b19f18c17e7aa3", size = 13454, upload_time = "2025-02-03T07:30:16.235Z" } +sdist = { url = "https://files.pythonhosted.org/packages/13/7d/8bca2bf9a247c2c5dfeec1d7a5f40db6518f88d314b8bca9da29670d2671/aiosqlite-0.21.0.tar.gz", hash = "sha256:131bb8056daa3bc875608c631c678cda73922a2d4ba8aec373b19f18c17e7aa3", size = 13454, upload-time = "2025-02-03T07:30:16.235Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f5/10/6c25ed6de94c49f88a91fa5018cb4c0f3625f31d5be9f771ebe5cc7cd506/aiosqlite-0.21.0-py3-none-any.whl", hash = "sha256:2549cf4057f95f53dcba16f2b64e8e2791d7e1adedb13197dd8ed77bb226d7d0", size = 15792, upload_time = "2025-02-03T07:30:13.6Z" }, + { url = "https://files.pythonhosted.org/packages/f5/10/6c25ed6de94c49f88a91fa5018cb4c0f3625f31d5be9f771ebe5cc7cd506/aiosqlite-0.21.0-py3-none-any.whl", hash = "sha256:2549cf4057f95f53dcba16f2b64e8e2791d7e1adedb13197dd8ed77bb226d7d0", size = 15792, upload-time = "2025-02-03T07:30:13.6Z" }, ] [[package]] name = "annotated-types" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload_time = "2024-05-20T21:33:25.928Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload_time = "2024-05-20T21:33:24.1Z" }, + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] [[package]] @@ -31,75 +31,75 @@ dependencies = [ { name = "idna" }, { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload_time = "2025-03-17T00:02:54.77Z" } +sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload-time = "2025-03-17T00:02:54.77Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload_time = "2025-03-17T00:02:52.713Z" }, + { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" }, ] [[package]] name = "asyncpg" version = "0.30.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746, upload_time = "2024-10-20T00:30:41.127Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746, upload-time = "2024-10-20T00:30:41.127Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373, upload_time = "2024-10-20T00:29:55.165Z" }, - { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745, upload_time = "2024-10-20T00:29:57.14Z" }, - { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103, upload_time = "2024-10-20T00:29:58.499Z" }, - { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471, upload_time = "2024-10-20T00:30:00.354Z" }, - { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253, upload_time = "2024-10-20T00:30:02.794Z" }, - { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720, upload_time = "2024-10-20T00:30:04.501Z" }, - { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404, upload_time = "2024-10-20T00:30:06.537Z" }, - { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623, upload_time = "2024-10-20T00:30:09.024Z" }, + { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373, upload-time = "2024-10-20T00:29:55.165Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745, upload-time = "2024-10-20T00:29:57.14Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103, upload-time = "2024-10-20T00:29:58.499Z" }, + { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471, upload-time = "2024-10-20T00:30:00.354Z" }, + { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253, upload-time = "2024-10-20T00:30:02.794Z" }, + { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720, upload-time = "2024-10-20T00:30:04.501Z" }, + { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404, upload-time = "2024-10-20T00:30:06.537Z" }, + { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623, upload-time = "2024-10-20T00:30:09.024Z" }, ] [[package]] name = "bcrypt" version = "4.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/5d/6d7433e0f3cd46ce0b43cd65e1db465ea024dbb8216fb2404e919c2ad77b/bcrypt-4.3.0.tar.gz", hash = "sha256:3a3fd2204178b6d2adcf09cb4f6426ffef54762577a7c9b54c159008cb288c18", size = 25697, upload_time = "2025-02-28T01:24:09.174Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/5d/6d7433e0f3cd46ce0b43cd65e1db465ea024dbb8216fb2404e919c2ad77b/bcrypt-4.3.0.tar.gz", hash = "sha256:3a3fd2204178b6d2adcf09cb4f6426ffef54762577a7c9b54c159008cb288c18", size = 25697, upload-time = "2025-02-28T01:24:09.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/2c/3d44e853d1fe969d229bd58d39ae6902b3d924af0e2b5a60d17d4b809ded/bcrypt-4.3.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f01e060f14b6b57bbb72fc5b4a83ac21c443c9a2ee708e04a10e9192f90a6281", size = 483719, upload_time = "2025-02-28T01:22:34.539Z" }, - { url = "https://files.pythonhosted.org/packages/a1/e2/58ff6e2a22eca2e2cff5370ae56dba29d70b1ea6fc08ee9115c3ae367795/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5eeac541cefd0bb887a371ef73c62c3cd78535e4887b310626036a7c0a817bb", size = 272001, upload_time = "2025-02-28T01:22:38.078Z" }, - { url = "https://files.pythonhosted.org/packages/37/1f/c55ed8dbe994b1d088309e366749633c9eb90d139af3c0a50c102ba68a1a/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59e1aa0e2cd871b08ca146ed08445038f42ff75968c7ae50d2fdd7860ade2180", size = 277451, upload_time = "2025-02-28T01:22:40.787Z" }, - { url = "https://files.pythonhosted.org/packages/d7/1c/794feb2ecf22fe73dcfb697ea7057f632061faceb7dcf0f155f3443b4d79/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:0042b2e342e9ae3d2ed22727c1262f76cc4f345683b5c1715f0250cf4277294f", size = 272792, upload_time = "2025-02-28T01:22:43.144Z" }, - { url = "https://files.pythonhosted.org/packages/13/b7/0b289506a3f3598c2ae2bdfa0ea66969812ed200264e3f61df77753eee6d/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74a8d21a09f5e025a9a23e7c0fd2c7fe8e7503e4d356c0a2c1486ba010619f09", size = 289752, upload_time = "2025-02-28T01:22:45.56Z" }, - { url = "https://files.pythonhosted.org/packages/dc/24/d0fb023788afe9e83cc118895a9f6c57e1044e7e1672f045e46733421fe6/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:0142b2cb84a009f8452c8c5a33ace5e3dfec4159e7735f5afe9a4d50a8ea722d", size = 277762, upload_time = "2025-02-28T01:22:47.023Z" }, - { url = "https://files.pythonhosted.org/packages/e4/38/cde58089492e55ac4ef6c49fea7027600c84fd23f7520c62118c03b4625e/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:12fa6ce40cde3f0b899729dbd7d5e8811cb892d31b6f7d0334a1f37748b789fd", size = 272384, upload_time = "2025-02-28T01:22:49.221Z" }, - { url = "https://files.pythonhosted.org/packages/de/6a/d5026520843490cfc8135d03012a413e4532a400e471e6188b01b2de853f/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:5bd3cca1f2aa5dbcf39e2aa13dd094ea181f48959e1071265de49cc2b82525af", size = 277329, upload_time = "2025-02-28T01:22:51.603Z" }, - { url = "https://files.pythonhosted.org/packages/b3/a3/4fc5255e60486466c389e28c12579d2829b28a527360e9430b4041df4cf9/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:335a420cfd63fc5bc27308e929bee231c15c85cc4c496610ffb17923abf7f231", size = 305241, upload_time = "2025-02-28T01:22:53.283Z" }, - { url = "https://files.pythonhosted.org/packages/c7/15/2b37bc07d6ce27cc94e5b10fd5058900eb8fb11642300e932c8c82e25c4a/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:0e30e5e67aed0187a1764911af023043b4542e70a7461ad20e837e94d23e1d6c", size = 309617, upload_time = "2025-02-28T01:22:55.461Z" }, - { url = "https://files.pythonhosted.org/packages/5f/1f/99f65edb09e6c935232ba0430c8c13bb98cb3194b6d636e61d93fe60ac59/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b8d62290ebefd49ee0b3ce7500f5dbdcf13b81402c05f6dafab9a1e1b27212f", size = 335751, upload_time = "2025-02-28T01:22:57.81Z" }, - { url = "https://files.pythonhosted.org/packages/00/1b/b324030c706711c99769988fcb694b3cb23f247ad39a7823a78e361bdbb8/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2ef6630e0ec01376f59a006dc72918b1bf436c3b571b80fa1968d775fa02fe7d", size = 355965, upload_time = "2025-02-28T01:22:59.181Z" }, - { url = "https://files.pythonhosted.org/packages/aa/dd/20372a0579dd915dfc3b1cd4943b3bca431866fcb1dfdfd7518c3caddea6/bcrypt-4.3.0-cp313-cp313t-win32.whl", hash = "sha256:7a4be4cbf241afee43f1c3969b9103a41b40bcb3a3f467ab19f891d9bc4642e4", size = 155316, upload_time = "2025-02-28T01:23:00.763Z" }, - { url = "https://files.pythonhosted.org/packages/6d/52/45d969fcff6b5577c2bf17098dc36269b4c02197d551371c023130c0f890/bcrypt-4.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c1949bf259a388863ced887c7861da1df681cb2388645766c89fdfd9004c669", size = 147752, upload_time = "2025-02-28T01:23:02.908Z" }, - { url = "https://files.pythonhosted.org/packages/11/22/5ada0b9af72b60cbc4c9a399fdde4af0feaa609d27eb0adc61607997a3fa/bcrypt-4.3.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:f81b0ed2639568bf14749112298f9e4e2b28853dab50a8b357e31798686a036d", size = 498019, upload_time = "2025-02-28T01:23:05.838Z" }, - { url = "https://files.pythonhosted.org/packages/b8/8c/252a1edc598dc1ce57905be173328eda073083826955ee3c97c7ff5ba584/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:864f8f19adbe13b7de11ba15d85d4a428c7e2f344bac110f667676a0ff84924b", size = 279174, upload_time = "2025-02-28T01:23:07.274Z" }, - { url = "https://files.pythonhosted.org/packages/29/5b/4547d5c49b85f0337c13929f2ccbe08b7283069eea3550a457914fc078aa/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e36506d001e93bffe59754397572f21bb5dc7c83f54454c990c74a468cd589e", size = 283870, upload_time = "2025-02-28T01:23:09.151Z" }, - { url = "https://files.pythonhosted.org/packages/be/21/7dbaf3fa1745cb63f776bb046e481fbababd7d344c5324eab47f5ca92dd2/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:842d08d75d9fe9fb94b18b071090220697f9f184d4547179b60734846461ed59", size = 279601, upload_time = "2025-02-28T01:23:11.461Z" }, - { url = "https://files.pythonhosted.org/packages/6d/64/e042fc8262e971347d9230d9abbe70d68b0a549acd8611c83cebd3eaec67/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7c03296b85cb87db865d91da79bf63d5609284fc0cab9472fdd8367bbd830753", size = 297660, upload_time = "2025-02-28T01:23:12.989Z" }, - { url = "https://files.pythonhosted.org/packages/50/b8/6294eb84a3fef3b67c69b4470fcdd5326676806bf2519cda79331ab3c3a9/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:62f26585e8b219cdc909b6a0069efc5e4267e25d4a3770a364ac58024f62a761", size = 284083, upload_time = "2025-02-28T01:23:14.5Z" }, - { url = "https://files.pythonhosted.org/packages/62/e6/baff635a4f2c42e8788fe1b1633911c38551ecca9a749d1052d296329da6/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:beeefe437218a65322fbd0069eb437e7c98137e08f22c4660ac2dc795c31f8bb", size = 279237, upload_time = "2025-02-28T01:23:16.686Z" }, - { url = "https://files.pythonhosted.org/packages/39/48/46f623f1b0c7dc2e5de0b8af5e6f5ac4cc26408ac33f3d424e5ad8da4a90/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:97eea7408db3a5bcce4a55d13245ab3fa566e23b4c67cd227062bb49e26c585d", size = 283737, upload_time = "2025-02-28T01:23:18.897Z" }, - { url = "https://files.pythonhosted.org/packages/49/8b/70671c3ce9c0fca4a6cc3cc6ccbaa7e948875a2e62cbd146e04a4011899c/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:191354ebfe305e84f344c5964c7cd5f924a3bfc5d405c75ad07f232b6dffb49f", size = 312741, upload_time = "2025-02-28T01:23:21.041Z" }, - { url = "https://files.pythonhosted.org/packages/27/fb/910d3a1caa2d249b6040a5caf9f9866c52114d51523ac2fb47578a27faee/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:41261d64150858eeb5ff43c753c4b216991e0ae16614a308a15d909503617732", size = 316472, upload_time = "2025-02-28T01:23:23.183Z" }, - { url = "https://files.pythonhosted.org/packages/dc/cf/7cf3a05b66ce466cfb575dbbda39718d45a609daa78500f57fa9f36fa3c0/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:33752b1ba962ee793fa2b6321404bf20011fe45b9afd2a842139de3011898fef", size = 343606, upload_time = "2025-02-28T01:23:25.361Z" }, - { url = "https://files.pythonhosted.org/packages/e3/b8/e970ecc6d7e355c0d892b7f733480f4aa8509f99b33e71550242cf0b7e63/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:50e6e80a4bfd23a25f5c05b90167c19030cf9f87930f7cb2eacb99f45d1c3304", size = 362867, upload_time = "2025-02-28T01:23:26.875Z" }, - { url = "https://files.pythonhosted.org/packages/a9/97/8d3118efd8354c555a3422d544163f40d9f236be5b96c714086463f11699/bcrypt-4.3.0-cp38-abi3-win32.whl", hash = "sha256:67a561c4d9fb9465ec866177e7aebcad08fe23aaf6fbd692a6fab69088abfc51", size = 160589, upload_time = "2025-02-28T01:23:28.381Z" }, - { url = "https://files.pythonhosted.org/packages/29/07/416f0b99f7f3997c69815365babbc2e8754181a4b1899d921b3c7d5b6f12/bcrypt-4.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:584027857bc2843772114717a7490a37f68da563b3620f78a849bcb54dc11e62", size = 152794, upload_time = "2025-02-28T01:23:30.187Z" }, - { url = "https://files.pythonhosted.org/packages/6e/c1/3fa0e9e4e0bfd3fd77eb8b52ec198fd6e1fd7e9402052e43f23483f956dd/bcrypt-4.3.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0d3efb1157edebfd9128e4e46e2ac1a64e0c1fe46fb023158a407c7892b0f8c3", size = 498969, upload_time = "2025-02-28T01:23:31.945Z" }, - { url = "https://files.pythonhosted.org/packages/ce/d4/755ce19b6743394787fbd7dff6bf271b27ee9b5912a97242e3caf125885b/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08bacc884fd302b611226c01014eca277d48f0a05187666bca23aac0dad6fe24", size = 279158, upload_time = "2025-02-28T01:23:34.161Z" }, - { url = "https://files.pythonhosted.org/packages/9b/5d/805ef1a749c965c46b28285dfb5cd272a7ed9fa971f970435a5133250182/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6746e6fec103fcd509b96bacdfdaa2fbde9a553245dbada284435173a6f1aef", size = 284285, upload_time = "2025-02-28T01:23:35.765Z" }, - { url = "https://files.pythonhosted.org/packages/ab/2b/698580547a4a4988e415721b71eb45e80c879f0fb04a62da131f45987b96/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:afe327968aaf13fc143a56a3360cb27d4ad0345e34da12c7290f1b00b8fe9a8b", size = 279583, upload_time = "2025-02-28T01:23:38.021Z" }, - { url = "https://files.pythonhosted.org/packages/f2/87/62e1e426418204db520f955ffd06f1efd389feca893dad7095bf35612eec/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d9af79d322e735b1fc33404b5765108ae0ff232d4b54666d46730f8ac1a43676", size = 297896, upload_time = "2025-02-28T01:23:39.575Z" }, - { url = "https://files.pythonhosted.org/packages/cb/c6/8fedca4c2ada1b6e889c52d2943b2f968d3427e5d65f595620ec4c06fa2f/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f1e3ffa1365e8702dc48c8b360fef8d7afeca482809c5e45e653af82ccd088c1", size = 284492, upload_time = "2025-02-28T01:23:40.901Z" }, - { url = "https://files.pythonhosted.org/packages/4d/4d/c43332dcaaddb7710a8ff5269fcccba97ed3c85987ddaa808db084267b9a/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3004df1b323d10021fda07a813fd33e0fd57bef0e9a480bb143877f6cba996fe", size = 279213, upload_time = "2025-02-28T01:23:42.653Z" }, - { url = "https://files.pythonhosted.org/packages/dc/7f/1e36379e169a7df3a14a1c160a49b7b918600a6008de43ff20d479e6f4b5/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:531457e5c839d8caea9b589a1bcfe3756b0547d7814e9ce3d437f17da75c32b0", size = 284162, upload_time = "2025-02-28T01:23:43.964Z" }, - { url = "https://files.pythonhosted.org/packages/1c/0a/644b2731194b0d7646f3210dc4d80c7fee3ecb3a1f791a6e0ae6bb8684e3/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:17a854d9a7a476a89dcef6c8bd119ad23e0f82557afbd2c442777a16408e614f", size = 312856, upload_time = "2025-02-28T01:23:46.011Z" }, - { url = "https://files.pythonhosted.org/packages/dc/62/2a871837c0bb6ab0c9a88bf54de0fc021a6a08832d4ea313ed92a669d437/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6fb1fd3ab08c0cbc6826a2e0447610c6f09e983a281b919ed721ad32236b8b23", size = 316726, upload_time = "2025-02-28T01:23:47.575Z" }, - { url = "https://files.pythonhosted.org/packages/0c/a1/9898ea3faac0b156d457fd73a3cb9c2855c6fd063e44b8522925cdd8ce46/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e965a9c1e9a393b8005031ff52583cedc15b7884fce7deb8b0346388837d6cfe", size = 343664, upload_time = "2025-02-28T01:23:49.059Z" }, - { url = "https://files.pythonhosted.org/packages/40/f2/71b4ed65ce38982ecdda0ff20c3ad1b15e71949c78b2c053df53629ce940/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:79e70b8342a33b52b55d93b3a59223a844962bef479f6a0ea318ebbcadf71505", size = 363128, upload_time = "2025-02-28T01:23:50.399Z" }, - { url = "https://files.pythonhosted.org/packages/11/99/12f6a58eca6dea4be992d6c681b7ec9410a1d9f5cf368c61437e31daa879/bcrypt-4.3.0-cp39-abi3-win32.whl", hash = "sha256:b4d4e57f0a63fd0b358eb765063ff661328f69a04494427265950c71b992a39a", size = 160598, upload_time = "2025-02-28T01:23:51.775Z" }, - { url = "https://files.pythonhosted.org/packages/a9/cf/45fb5261ece3e6b9817d3d82b2f343a505fd58674a92577923bc500bd1aa/bcrypt-4.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b", size = 152799, upload_time = "2025-02-28T01:23:53.139Z" }, + { url = "https://files.pythonhosted.org/packages/bf/2c/3d44e853d1fe969d229bd58d39ae6902b3d924af0e2b5a60d17d4b809ded/bcrypt-4.3.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f01e060f14b6b57bbb72fc5b4a83ac21c443c9a2ee708e04a10e9192f90a6281", size = 483719, upload-time = "2025-02-28T01:22:34.539Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e2/58ff6e2a22eca2e2cff5370ae56dba29d70b1ea6fc08ee9115c3ae367795/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5eeac541cefd0bb887a371ef73c62c3cd78535e4887b310626036a7c0a817bb", size = 272001, upload-time = "2025-02-28T01:22:38.078Z" }, + { url = "https://files.pythonhosted.org/packages/37/1f/c55ed8dbe994b1d088309e366749633c9eb90d139af3c0a50c102ba68a1a/bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59e1aa0e2cd871b08ca146ed08445038f42ff75968c7ae50d2fdd7860ade2180", size = 277451, upload-time = "2025-02-28T01:22:40.787Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1c/794feb2ecf22fe73dcfb697ea7057f632061faceb7dcf0f155f3443b4d79/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:0042b2e342e9ae3d2ed22727c1262f76cc4f345683b5c1715f0250cf4277294f", size = 272792, upload-time = "2025-02-28T01:22:43.144Z" }, + { url = "https://files.pythonhosted.org/packages/13/b7/0b289506a3f3598c2ae2bdfa0ea66969812ed200264e3f61df77753eee6d/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74a8d21a09f5e025a9a23e7c0fd2c7fe8e7503e4d356c0a2c1486ba010619f09", size = 289752, upload-time = "2025-02-28T01:22:45.56Z" }, + { url = "https://files.pythonhosted.org/packages/dc/24/d0fb023788afe9e83cc118895a9f6c57e1044e7e1672f045e46733421fe6/bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:0142b2cb84a009f8452c8c5a33ace5e3dfec4159e7735f5afe9a4d50a8ea722d", size = 277762, upload-time = "2025-02-28T01:22:47.023Z" }, + { url = "https://files.pythonhosted.org/packages/e4/38/cde58089492e55ac4ef6c49fea7027600c84fd23f7520c62118c03b4625e/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:12fa6ce40cde3f0b899729dbd7d5e8811cb892d31b6f7d0334a1f37748b789fd", size = 272384, upload-time = "2025-02-28T01:22:49.221Z" }, + { url = "https://files.pythonhosted.org/packages/de/6a/d5026520843490cfc8135d03012a413e4532a400e471e6188b01b2de853f/bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:5bd3cca1f2aa5dbcf39e2aa13dd094ea181f48959e1071265de49cc2b82525af", size = 277329, upload-time = "2025-02-28T01:22:51.603Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a3/4fc5255e60486466c389e28c12579d2829b28a527360e9430b4041df4cf9/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:335a420cfd63fc5bc27308e929bee231c15c85cc4c496610ffb17923abf7f231", size = 305241, upload-time = "2025-02-28T01:22:53.283Z" }, + { url = "https://files.pythonhosted.org/packages/c7/15/2b37bc07d6ce27cc94e5b10fd5058900eb8fb11642300e932c8c82e25c4a/bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:0e30e5e67aed0187a1764911af023043b4542e70a7461ad20e837e94d23e1d6c", size = 309617, upload-time = "2025-02-28T01:22:55.461Z" }, + { url = "https://files.pythonhosted.org/packages/5f/1f/99f65edb09e6c935232ba0430c8c13bb98cb3194b6d636e61d93fe60ac59/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b8d62290ebefd49ee0b3ce7500f5dbdcf13b81402c05f6dafab9a1e1b27212f", size = 335751, upload-time = "2025-02-28T01:22:57.81Z" }, + { url = "https://files.pythonhosted.org/packages/00/1b/b324030c706711c99769988fcb694b3cb23f247ad39a7823a78e361bdbb8/bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2ef6630e0ec01376f59a006dc72918b1bf436c3b571b80fa1968d775fa02fe7d", size = 355965, upload-time = "2025-02-28T01:22:59.181Z" }, + { url = "https://files.pythonhosted.org/packages/aa/dd/20372a0579dd915dfc3b1cd4943b3bca431866fcb1dfdfd7518c3caddea6/bcrypt-4.3.0-cp313-cp313t-win32.whl", hash = "sha256:7a4be4cbf241afee43f1c3969b9103a41b40bcb3a3f467ab19f891d9bc4642e4", size = 155316, upload-time = "2025-02-28T01:23:00.763Z" }, + { url = "https://files.pythonhosted.org/packages/6d/52/45d969fcff6b5577c2bf17098dc36269b4c02197d551371c023130c0f890/bcrypt-4.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c1949bf259a388863ced887c7861da1df681cb2388645766c89fdfd9004c669", size = 147752, upload-time = "2025-02-28T01:23:02.908Z" }, + { url = "https://files.pythonhosted.org/packages/11/22/5ada0b9af72b60cbc4c9a399fdde4af0feaa609d27eb0adc61607997a3fa/bcrypt-4.3.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:f81b0ed2639568bf14749112298f9e4e2b28853dab50a8b357e31798686a036d", size = 498019, upload-time = "2025-02-28T01:23:05.838Z" }, + { url = "https://files.pythonhosted.org/packages/b8/8c/252a1edc598dc1ce57905be173328eda073083826955ee3c97c7ff5ba584/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:864f8f19adbe13b7de11ba15d85d4a428c7e2f344bac110f667676a0ff84924b", size = 279174, upload-time = "2025-02-28T01:23:07.274Z" }, + { url = "https://files.pythonhosted.org/packages/29/5b/4547d5c49b85f0337c13929f2ccbe08b7283069eea3550a457914fc078aa/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e36506d001e93bffe59754397572f21bb5dc7c83f54454c990c74a468cd589e", size = 283870, upload-time = "2025-02-28T01:23:09.151Z" }, + { url = "https://files.pythonhosted.org/packages/be/21/7dbaf3fa1745cb63f776bb046e481fbababd7d344c5324eab47f5ca92dd2/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:842d08d75d9fe9fb94b18b071090220697f9f184d4547179b60734846461ed59", size = 279601, upload-time = "2025-02-28T01:23:11.461Z" }, + { url = "https://files.pythonhosted.org/packages/6d/64/e042fc8262e971347d9230d9abbe70d68b0a549acd8611c83cebd3eaec67/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7c03296b85cb87db865d91da79bf63d5609284fc0cab9472fdd8367bbd830753", size = 297660, upload-time = "2025-02-28T01:23:12.989Z" }, + { url = "https://files.pythonhosted.org/packages/50/b8/6294eb84a3fef3b67c69b4470fcdd5326676806bf2519cda79331ab3c3a9/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:62f26585e8b219cdc909b6a0069efc5e4267e25d4a3770a364ac58024f62a761", size = 284083, upload-time = "2025-02-28T01:23:14.5Z" }, + { url = "https://files.pythonhosted.org/packages/62/e6/baff635a4f2c42e8788fe1b1633911c38551ecca9a749d1052d296329da6/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:beeefe437218a65322fbd0069eb437e7c98137e08f22c4660ac2dc795c31f8bb", size = 279237, upload-time = "2025-02-28T01:23:16.686Z" }, + { url = "https://files.pythonhosted.org/packages/39/48/46f623f1b0c7dc2e5de0b8af5e6f5ac4cc26408ac33f3d424e5ad8da4a90/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:97eea7408db3a5bcce4a55d13245ab3fa566e23b4c67cd227062bb49e26c585d", size = 283737, upload-time = "2025-02-28T01:23:18.897Z" }, + { url = "https://files.pythonhosted.org/packages/49/8b/70671c3ce9c0fca4a6cc3cc6ccbaa7e948875a2e62cbd146e04a4011899c/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:191354ebfe305e84f344c5964c7cd5f924a3bfc5d405c75ad07f232b6dffb49f", size = 312741, upload-time = "2025-02-28T01:23:21.041Z" }, + { url = "https://files.pythonhosted.org/packages/27/fb/910d3a1caa2d249b6040a5caf9f9866c52114d51523ac2fb47578a27faee/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:41261d64150858eeb5ff43c753c4b216991e0ae16614a308a15d909503617732", size = 316472, upload-time = "2025-02-28T01:23:23.183Z" }, + { url = "https://files.pythonhosted.org/packages/dc/cf/7cf3a05b66ce466cfb575dbbda39718d45a609daa78500f57fa9f36fa3c0/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:33752b1ba962ee793fa2b6321404bf20011fe45b9afd2a842139de3011898fef", size = 343606, upload-time = "2025-02-28T01:23:25.361Z" }, + { url = "https://files.pythonhosted.org/packages/e3/b8/e970ecc6d7e355c0d892b7f733480f4aa8509f99b33e71550242cf0b7e63/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:50e6e80a4bfd23a25f5c05b90167c19030cf9f87930f7cb2eacb99f45d1c3304", size = 362867, upload-time = "2025-02-28T01:23:26.875Z" }, + { url = "https://files.pythonhosted.org/packages/a9/97/8d3118efd8354c555a3422d544163f40d9f236be5b96c714086463f11699/bcrypt-4.3.0-cp38-abi3-win32.whl", hash = "sha256:67a561c4d9fb9465ec866177e7aebcad08fe23aaf6fbd692a6fab69088abfc51", size = 160589, upload-time = "2025-02-28T01:23:28.381Z" }, + { url = "https://files.pythonhosted.org/packages/29/07/416f0b99f7f3997c69815365babbc2e8754181a4b1899d921b3c7d5b6f12/bcrypt-4.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:584027857bc2843772114717a7490a37f68da563b3620f78a849bcb54dc11e62", size = 152794, upload-time = "2025-02-28T01:23:30.187Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c1/3fa0e9e4e0bfd3fd77eb8b52ec198fd6e1fd7e9402052e43f23483f956dd/bcrypt-4.3.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0d3efb1157edebfd9128e4e46e2ac1a64e0c1fe46fb023158a407c7892b0f8c3", size = 498969, upload-time = "2025-02-28T01:23:31.945Z" }, + { url = "https://files.pythonhosted.org/packages/ce/d4/755ce19b6743394787fbd7dff6bf271b27ee9b5912a97242e3caf125885b/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08bacc884fd302b611226c01014eca277d48f0a05187666bca23aac0dad6fe24", size = 279158, upload-time = "2025-02-28T01:23:34.161Z" }, + { url = "https://files.pythonhosted.org/packages/9b/5d/805ef1a749c965c46b28285dfb5cd272a7ed9fa971f970435a5133250182/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6746e6fec103fcd509b96bacdfdaa2fbde9a553245dbada284435173a6f1aef", size = 284285, upload-time = "2025-02-28T01:23:35.765Z" }, + { url = "https://files.pythonhosted.org/packages/ab/2b/698580547a4a4988e415721b71eb45e80c879f0fb04a62da131f45987b96/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:afe327968aaf13fc143a56a3360cb27d4ad0345e34da12c7290f1b00b8fe9a8b", size = 279583, upload-time = "2025-02-28T01:23:38.021Z" }, + { url = "https://files.pythonhosted.org/packages/f2/87/62e1e426418204db520f955ffd06f1efd389feca893dad7095bf35612eec/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d9af79d322e735b1fc33404b5765108ae0ff232d4b54666d46730f8ac1a43676", size = 297896, upload-time = "2025-02-28T01:23:39.575Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c6/8fedca4c2ada1b6e889c52d2943b2f968d3427e5d65f595620ec4c06fa2f/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f1e3ffa1365e8702dc48c8b360fef8d7afeca482809c5e45e653af82ccd088c1", size = 284492, upload-time = "2025-02-28T01:23:40.901Z" }, + { url = "https://files.pythonhosted.org/packages/4d/4d/c43332dcaaddb7710a8ff5269fcccba97ed3c85987ddaa808db084267b9a/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3004df1b323d10021fda07a813fd33e0fd57bef0e9a480bb143877f6cba996fe", size = 279213, upload-time = "2025-02-28T01:23:42.653Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7f/1e36379e169a7df3a14a1c160a49b7b918600a6008de43ff20d479e6f4b5/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:531457e5c839d8caea9b589a1bcfe3756b0547d7814e9ce3d437f17da75c32b0", size = 284162, upload-time = "2025-02-28T01:23:43.964Z" }, + { url = "https://files.pythonhosted.org/packages/1c/0a/644b2731194b0d7646f3210dc4d80c7fee3ecb3a1f791a6e0ae6bb8684e3/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:17a854d9a7a476a89dcef6c8bd119ad23e0f82557afbd2c442777a16408e614f", size = 312856, upload-time = "2025-02-28T01:23:46.011Z" }, + { url = "https://files.pythonhosted.org/packages/dc/62/2a871837c0bb6ab0c9a88bf54de0fc021a6a08832d4ea313ed92a669d437/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6fb1fd3ab08c0cbc6826a2e0447610c6f09e983a281b919ed721ad32236b8b23", size = 316726, upload-time = "2025-02-28T01:23:47.575Z" }, + { url = "https://files.pythonhosted.org/packages/0c/a1/9898ea3faac0b156d457fd73a3cb9c2855c6fd063e44b8522925cdd8ce46/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e965a9c1e9a393b8005031ff52583cedc15b7884fce7deb8b0346388837d6cfe", size = 343664, upload-time = "2025-02-28T01:23:49.059Z" }, + { url = "https://files.pythonhosted.org/packages/40/f2/71b4ed65ce38982ecdda0ff20c3ad1b15e71949c78b2c053df53629ce940/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:79e70b8342a33b52b55d93b3a59223a844962bef479f6a0ea318ebbcadf71505", size = 363128, upload-time = "2025-02-28T01:23:50.399Z" }, + { url = "https://files.pythonhosted.org/packages/11/99/12f6a58eca6dea4be992d6c681b7ec9410a1d9f5cf368c61437e31daa879/bcrypt-4.3.0-cp39-abi3-win32.whl", hash = "sha256:b4d4e57f0a63fd0b358eb765063ff661328f69a04494427265950c71b992a39a", size = 160598, upload-time = "2025-02-28T01:23:51.775Z" }, + { url = "https://files.pythonhosted.org/packages/a9/cf/45fb5261ece3e6b9817d3d82b2f343a505fd58674a92577923bc500bd1aa/bcrypt-4.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b", size = 152799, upload-time = "2025-02-28T01:23:53.139Z" }, ] [[package]] @@ -110,18 +110,18 @@ dependencies = [ { name = "soupsieve" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067, upload_time = "2025-04-15T17:05:13.836Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067, upload-time = "2025-04-15T17:05:13.836Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload_time = "2025-04-15T17:05:12.221Z" }, + { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload-time = "2025-04-15T17:05:12.221Z" }, ] [[package]] name = "certifi" version = "2025.1.31" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577, upload_time = "2025-01-31T02:16:47.166Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577, upload-time = "2025-01-31T02:16:47.166Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393, upload_time = "2025-01-31T02:16:45.015Z" }, + { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393, upload-time = "2025-01-31T02:16:45.015Z" }, ] [[package]] @@ -131,64 +131,64 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser", marker = "implementation_name != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload_time = "2025-09-08T23:24:04.541Z" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload_time = "2025-09-08T23:23:00.879Z" }, - { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload_time = "2025-09-08T23:23:02.231Z" }, - { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload_time = "2025-09-08T23:23:03.472Z" }, - { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload_time = "2025-09-08T23:23:04.792Z" }, - { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload_time = "2025-09-08T23:23:06.127Z" }, - { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload_time = "2025-09-08T23:23:07.753Z" }, - { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload_time = "2025-09-08T23:23:09.648Z" }, - { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload_time = "2025-09-08T23:23:10.928Z" }, - { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload_time = "2025-09-08T23:23:12.42Z" }, - { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload_time = "2025-09-08T23:23:14.32Z" }, - { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload_time = "2025-09-08T23:23:15.535Z" }, - { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload_time = "2025-09-08T23:23:16.761Z" }, - { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload_time = "2025-09-08T23:23:18.087Z" }, - { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload_time = "2025-09-08T23:23:19.622Z" }, - { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload_time = "2025-09-08T23:23:20.853Z" }, - { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload_time = "2025-09-08T23:23:22.08Z" }, - { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload_time = "2025-09-08T23:23:23.314Z" }, - { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload_time = "2025-09-08T23:23:24.541Z" }, - { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload_time = "2025-09-08T23:23:26.143Z" }, - { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload_time = "2025-09-08T23:23:27.873Z" }, - { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload_time = "2025-09-08T23:23:44.61Z" }, - { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload_time = "2025-09-08T23:23:45.848Z" }, - { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload_time = "2025-09-08T23:23:47.105Z" }, - { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload_time = "2025-09-08T23:23:29.347Z" }, - { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload_time = "2025-09-08T23:23:30.63Z" }, - { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload_time = "2025-09-08T23:23:31.91Z" }, - { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload_time = "2025-09-08T23:23:33.214Z" }, - { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload_time = "2025-09-08T23:23:34.495Z" }, - { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload_time = "2025-09-08T23:23:36.096Z" }, - { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload_time = "2025-09-08T23:23:37.328Z" }, - { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload_time = "2025-09-08T23:23:38.945Z" }, - { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload_time = "2025-09-08T23:23:40.423Z" }, - { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload_time = "2025-09-08T23:23:41.742Z" }, - { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload_time = "2025-09-08T23:23:43.004Z" }, + { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, + { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, + { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, + { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" }, + { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" }, + { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" }, + { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" }, + { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" }, + { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" }, + { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, + { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, + { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" }, + { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" }, + { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" }, + { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" }, + { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, + { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, ] [[package]] name = "charset-normalizer" version = "3.4.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188, upload_time = "2024-12-24T18:12:35.43Z" } +sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188, upload-time = "2024-12-24T18:12:35.43Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698, upload_time = "2024-12-24T18:11:05.834Z" }, - { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162, upload_time = "2024-12-24T18:11:07.064Z" }, - { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263, upload_time = "2024-12-24T18:11:08.374Z" }, - { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966, upload_time = "2024-12-24T18:11:09.831Z" }, - { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992, upload_time = "2024-12-24T18:11:12.03Z" }, - { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162, upload_time = "2024-12-24T18:11:13.372Z" }, - { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972, upload_time = "2024-12-24T18:11:14.628Z" }, - { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095, upload_time = "2024-12-24T18:11:17.672Z" }, - { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668, upload_time = "2024-12-24T18:11:18.989Z" }, - { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073, upload_time = "2024-12-24T18:11:21.507Z" }, - { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732, upload_time = "2024-12-24T18:11:22.774Z" }, - { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391, upload_time = "2024-12-24T18:11:24.139Z" }, - { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702, upload_time = "2024-12-24T18:11:26.535Z" }, - { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767, upload_time = "2024-12-24T18:12:32.852Z" }, + { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698, upload-time = "2024-12-24T18:11:05.834Z" }, + { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162, upload-time = "2024-12-24T18:11:07.064Z" }, + { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263, upload-time = "2024-12-24T18:11:08.374Z" }, + { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966, upload-time = "2024-12-24T18:11:09.831Z" }, + { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992, upload-time = "2024-12-24T18:11:12.03Z" }, + { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162, upload-time = "2024-12-24T18:11:13.372Z" }, + { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972, upload-time = "2024-12-24T18:11:14.628Z" }, + { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095, upload-time = "2024-12-24T18:11:17.672Z" }, + { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668, upload-time = "2024-12-24T18:11:18.989Z" }, + { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073, upload-time = "2024-12-24T18:11:21.507Z" }, + { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732, upload-time = "2024-12-24T18:11:22.774Z" }, + { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391, upload-time = "2024-12-24T18:11:24.139Z" }, + { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702, upload-time = "2024-12-24T18:11:26.535Z" }, + { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767, upload-time = "2024-12-24T18:12:32.852Z" }, ] [[package]] @@ -198,47 +198,47 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload_time = "2024-12-21T18:38:44.339Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload_time = "2024-12-21T18:38:41.666Z" }, + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload_time = "2022-10-25T02:36:22.414Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload_time = "2022-10-25T02:36:20.889Z" }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "coverage" version = "7.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/4f/2251e65033ed2ce1e68f00f91a0294e0f80c80ae8c3ebbe2f12828c4cd53/coverage-7.8.0.tar.gz", hash = "sha256:7a3d62b3b03b4b6fd41a085f3574874cf946cb4604d2b4d3e8dca8cd570ca501", size = 811872, upload_time = "2025-03-30T20:36:45.376Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/4f/2251e65033ed2ce1e68f00f91a0294e0f80c80ae8c3ebbe2f12828c4cd53/coverage-7.8.0.tar.gz", hash = "sha256:7a3d62b3b03b4b6fd41a085f3574874cf946cb4604d2b4d3e8dca8cd570ca501", size = 811872, upload-time = "2025-03-30T20:36:45.376Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/21/87e9b97b568e223f3438d93072479c2f36cc9b3f6b9f7094b9d50232acc0/coverage-7.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ac46d0c2dd5820ce93943a501ac5f6548ea81594777ca585bf002aa8854cacd", size = 211708, upload_time = "2025-03-30T20:35:47.417Z" }, - { url = "https://files.pythonhosted.org/packages/75/be/882d08b28a0d19c9c4c2e8a1c6ebe1f79c9c839eb46d4fca3bd3b34562b9/coverage-7.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:771eb7587a0563ca5bb6f622b9ed7f9d07bd08900f7589b4febff05f469bea00", size = 211981, upload_time = "2025-03-30T20:35:49.002Z" }, - { url = "https://files.pythonhosted.org/packages/7a/1d/ce99612ebd58082fbe3f8c66f6d8d5694976c76a0d474503fa70633ec77f/coverage-7.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42421e04069fb2cbcbca5a696c4050b84a43b05392679d4068acbe65449b5c64", size = 245495, upload_time = "2025-03-30T20:35:51.073Z" }, - { url = "https://files.pythonhosted.org/packages/dc/8d/6115abe97df98db6b2bd76aae395fcc941d039a7acd25f741312ced9a78f/coverage-7.8.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:554fec1199d93ab30adaa751db68acec2b41c5602ac944bb19187cb9a41a8067", size = 242538, upload_time = "2025-03-30T20:35:52.941Z" }, - { url = "https://files.pythonhosted.org/packages/cb/74/2f8cc196643b15bc096d60e073691dadb3dca48418f08bc78dd6e899383e/coverage-7.8.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008", size = 244561, upload_time = "2025-03-30T20:35:54.658Z" }, - { url = "https://files.pythonhosted.org/packages/22/70/c10c77cd77970ac965734fe3419f2c98665f6e982744a9bfb0e749d298f4/coverage-7.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:581a40c7b94921fffd6457ffe532259813fc68eb2bdda60fa8cc343414ce3733", size = 244633, upload_time = "2025-03-30T20:35:56.221Z" }, - { url = "https://files.pythonhosted.org/packages/38/5a/4f7569d946a07c952688debee18c2bb9ab24f88027e3d71fd25dbc2f9dca/coverage-7.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f319bae0321bc838e205bf9e5bc28f0a3165f30c203b610f17ab5552cff90323", size = 242712, upload_time = "2025-03-30T20:35:57.801Z" }, - { url = "https://files.pythonhosted.org/packages/bb/a1/03a43b33f50475a632a91ea8c127f7e35e53786dbe6781c25f19fd5a65f8/coverage-7.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04bfec25a8ef1c5f41f5e7e5c842f6b615599ca8ba8391ec33a9290d9d2db3a3", size = 244000, upload_time = "2025-03-30T20:35:59.378Z" }, - { url = "https://files.pythonhosted.org/packages/6a/89/ab6c43b1788a3128e4d1b7b54214548dcad75a621f9d277b14d16a80d8a1/coverage-7.8.0-cp313-cp313-win32.whl", hash = "sha256:dd19608788b50eed889e13a5d71d832edc34fc9dfce606f66e8f9f917eef910d", size = 214195, upload_time = "2025-03-30T20:36:01.005Z" }, - { url = "https://files.pythonhosted.org/packages/12/12/6bf5f9a8b063d116bac536a7fb594fc35cb04981654cccb4bbfea5dcdfa0/coverage-7.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:a9abbccd778d98e9c7e85038e35e91e67f5b520776781d9a1e2ee9d400869487", size = 214998, upload_time = "2025-03-30T20:36:03.006Z" }, - { url = "https://files.pythonhosted.org/packages/2a/e6/1e9df74ef7a1c983a9c7443dac8aac37a46f1939ae3499424622e72a6f78/coverage-7.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:18c5ae6d061ad5b3e7eef4363fb27a0576012a7447af48be6c75b88494c6cf25", size = 212541, upload_time = "2025-03-30T20:36:04.638Z" }, - { url = "https://files.pythonhosted.org/packages/04/51/c32174edb7ee49744e2e81c4b1414ac9df3dacfcb5b5f273b7f285ad43f6/coverage-7.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:95aa6ae391a22bbbce1b77ddac846c98c5473de0372ba5c463480043a07bff42", size = 212767, upload_time = "2025-03-30T20:36:06.503Z" }, - { url = "https://files.pythonhosted.org/packages/e9/8f/f454cbdb5212f13f29d4a7983db69169f1937e869a5142bce983ded52162/coverage-7.8.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e013b07ba1c748dacc2a80e69a46286ff145935f260eb8c72df7185bf048f502", size = 256997, upload_time = "2025-03-30T20:36:08.137Z" }, - { url = "https://files.pythonhosted.org/packages/e6/74/2bf9e78b321216d6ee90a81e5c22f912fc428442c830c4077b4a071db66f/coverage-7.8.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d766a4f0e5aa1ba056ec3496243150698dc0481902e2b8559314368717be82b1", size = 252708, upload_time = "2025-03-30T20:36:09.781Z" }, - { url = "https://files.pythonhosted.org/packages/92/4d/50d7eb1e9a6062bee6e2f92e78b0998848a972e9afad349b6cdde6fa9e32/coverage-7.8.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad80e6b4a0c3cb6f10f29ae4c60e991f424e6b14219d46f1e7d442b938ee68a4", size = 255046, upload_time = "2025-03-30T20:36:11.409Z" }, - { url = "https://files.pythonhosted.org/packages/40/9e/71fb4e7402a07c4198ab44fc564d09d7d0ffca46a9fb7b0a7b929e7641bd/coverage-7.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b87eb6fc9e1bb8f98892a2458781348fa37e6925f35bb6ceb9d4afd54ba36c73", size = 256139, upload_time = "2025-03-30T20:36:13.86Z" }, - { url = "https://files.pythonhosted.org/packages/49/1a/78d37f7a42b5beff027e807c2843185961fdae7fe23aad5a4837c93f9d25/coverage-7.8.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d1ba00ae33be84066cfbe7361d4e04dec78445b2b88bdb734d0d1cbab916025a", size = 254307, upload_time = "2025-03-30T20:36:16.074Z" }, - { url = "https://files.pythonhosted.org/packages/58/e9/8fb8e0ff6bef5e170ee19d59ca694f9001b2ec085dc99b4f65c128bb3f9a/coverage-7.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f3c38e4e5ccbdc9198aecc766cedbb134b2d89bf64533973678dfcf07effd883", size = 255116, upload_time = "2025-03-30T20:36:18.033Z" }, - { url = "https://files.pythonhosted.org/packages/56/b0/d968ecdbe6fe0a863de7169bbe9e8a476868959f3af24981f6a10d2b6924/coverage-7.8.0-cp313-cp313t-win32.whl", hash = "sha256:379fe315e206b14e21db5240f89dc0774bdd3e25c3c58c2c733c99eca96f1ada", size = 214909, upload_time = "2025-03-30T20:36:19.644Z" }, - { url = "https://files.pythonhosted.org/packages/87/e9/d6b7ef9fecf42dfb418d93544af47c940aa83056c49e6021a564aafbc91f/coverage-7.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2e4b6b87bb0c846a9315e3ab4be2d52fac905100565f4b92f02c445c8799e257", size = 216068, upload_time = "2025-03-30T20:36:21.282Z" }, - { url = "https://files.pythonhosted.org/packages/59/f1/4da7717f0063a222db253e7121bd6a56f6fb1ba439dcc36659088793347c/coverage-7.8.0-py3-none-any.whl", hash = "sha256:dbf364b4c5e7bae9250528167dfe40219b62e2d573c854d74be213e1e52069f7", size = 203435, upload_time = "2025-03-30T20:36:43.61Z" }, + { url = "https://files.pythonhosted.org/packages/f3/21/87e9b97b568e223f3438d93072479c2f36cc9b3f6b9f7094b9d50232acc0/coverage-7.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ac46d0c2dd5820ce93943a501ac5f6548ea81594777ca585bf002aa8854cacd", size = 211708, upload-time = "2025-03-30T20:35:47.417Z" }, + { url = "https://files.pythonhosted.org/packages/75/be/882d08b28a0d19c9c4c2e8a1c6ebe1f79c9c839eb46d4fca3bd3b34562b9/coverage-7.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:771eb7587a0563ca5bb6f622b9ed7f9d07bd08900f7589b4febff05f469bea00", size = 211981, upload-time = "2025-03-30T20:35:49.002Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1d/ce99612ebd58082fbe3f8c66f6d8d5694976c76a0d474503fa70633ec77f/coverage-7.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42421e04069fb2cbcbca5a696c4050b84a43b05392679d4068acbe65449b5c64", size = 245495, upload-time = "2025-03-30T20:35:51.073Z" }, + { url = "https://files.pythonhosted.org/packages/dc/8d/6115abe97df98db6b2bd76aae395fcc941d039a7acd25f741312ced9a78f/coverage-7.8.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:554fec1199d93ab30adaa751db68acec2b41c5602ac944bb19187cb9a41a8067", size = 242538, upload-time = "2025-03-30T20:35:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/cb/74/2f8cc196643b15bc096d60e073691dadb3dca48418f08bc78dd6e899383e/coverage-7.8.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008", size = 244561, upload-time = "2025-03-30T20:35:54.658Z" }, + { url = "https://files.pythonhosted.org/packages/22/70/c10c77cd77970ac965734fe3419f2c98665f6e982744a9bfb0e749d298f4/coverage-7.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:581a40c7b94921fffd6457ffe532259813fc68eb2bdda60fa8cc343414ce3733", size = 244633, upload-time = "2025-03-30T20:35:56.221Z" }, + { url = "https://files.pythonhosted.org/packages/38/5a/4f7569d946a07c952688debee18c2bb9ab24f88027e3d71fd25dbc2f9dca/coverage-7.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f319bae0321bc838e205bf9e5bc28f0a3165f30c203b610f17ab5552cff90323", size = 242712, upload-time = "2025-03-30T20:35:57.801Z" }, + { url = "https://files.pythonhosted.org/packages/bb/a1/03a43b33f50475a632a91ea8c127f7e35e53786dbe6781c25f19fd5a65f8/coverage-7.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04bfec25a8ef1c5f41f5e7e5c842f6b615599ca8ba8391ec33a9290d9d2db3a3", size = 244000, upload-time = "2025-03-30T20:35:59.378Z" }, + { url = "https://files.pythonhosted.org/packages/6a/89/ab6c43b1788a3128e4d1b7b54214548dcad75a621f9d277b14d16a80d8a1/coverage-7.8.0-cp313-cp313-win32.whl", hash = "sha256:dd19608788b50eed889e13a5d71d832edc34fc9dfce606f66e8f9f917eef910d", size = 214195, upload-time = "2025-03-30T20:36:01.005Z" }, + { url = "https://files.pythonhosted.org/packages/12/12/6bf5f9a8b063d116bac536a7fb594fc35cb04981654cccb4bbfea5dcdfa0/coverage-7.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:a9abbccd778d98e9c7e85038e35e91e67f5b520776781d9a1e2ee9d400869487", size = 214998, upload-time = "2025-03-30T20:36:03.006Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e6/1e9df74ef7a1c983a9c7443dac8aac37a46f1939ae3499424622e72a6f78/coverage-7.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:18c5ae6d061ad5b3e7eef4363fb27a0576012a7447af48be6c75b88494c6cf25", size = 212541, upload-time = "2025-03-30T20:36:04.638Z" }, + { url = "https://files.pythonhosted.org/packages/04/51/c32174edb7ee49744e2e81c4b1414ac9df3dacfcb5b5f273b7f285ad43f6/coverage-7.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:95aa6ae391a22bbbce1b77ddac846c98c5473de0372ba5c463480043a07bff42", size = 212767, upload-time = "2025-03-30T20:36:06.503Z" }, + { url = "https://files.pythonhosted.org/packages/e9/8f/f454cbdb5212f13f29d4a7983db69169f1937e869a5142bce983ded52162/coverage-7.8.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e013b07ba1c748dacc2a80e69a46286ff145935f260eb8c72df7185bf048f502", size = 256997, upload-time = "2025-03-30T20:36:08.137Z" }, + { url = "https://files.pythonhosted.org/packages/e6/74/2bf9e78b321216d6ee90a81e5c22f912fc428442c830c4077b4a071db66f/coverage-7.8.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d766a4f0e5aa1ba056ec3496243150698dc0481902e2b8559314368717be82b1", size = 252708, upload-time = "2025-03-30T20:36:09.781Z" }, + { url = "https://files.pythonhosted.org/packages/92/4d/50d7eb1e9a6062bee6e2f92e78b0998848a972e9afad349b6cdde6fa9e32/coverage-7.8.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad80e6b4a0c3cb6f10f29ae4c60e991f424e6b14219d46f1e7d442b938ee68a4", size = 255046, upload-time = "2025-03-30T20:36:11.409Z" }, + { url = "https://files.pythonhosted.org/packages/40/9e/71fb4e7402a07c4198ab44fc564d09d7d0ffca46a9fb7b0a7b929e7641bd/coverage-7.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b87eb6fc9e1bb8f98892a2458781348fa37e6925f35bb6ceb9d4afd54ba36c73", size = 256139, upload-time = "2025-03-30T20:36:13.86Z" }, + { url = "https://files.pythonhosted.org/packages/49/1a/78d37f7a42b5beff027e807c2843185961fdae7fe23aad5a4837c93f9d25/coverage-7.8.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d1ba00ae33be84066cfbe7361d4e04dec78445b2b88bdb734d0d1cbab916025a", size = 254307, upload-time = "2025-03-30T20:36:16.074Z" }, + { url = "https://files.pythonhosted.org/packages/58/e9/8fb8e0ff6bef5e170ee19d59ca694f9001b2ec085dc99b4f65c128bb3f9a/coverage-7.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f3c38e4e5ccbdc9198aecc766cedbb134b2d89bf64533973678dfcf07effd883", size = 255116, upload-time = "2025-03-30T20:36:18.033Z" }, + { url = "https://files.pythonhosted.org/packages/56/b0/d968ecdbe6fe0a863de7169bbe9e8a476868959f3af24981f6a10d2b6924/coverage-7.8.0-cp313-cp313t-win32.whl", hash = "sha256:379fe315e206b14e21db5240f89dc0774bdd3e25c3c58c2c733c99eca96f1ada", size = 214909, upload-time = "2025-03-30T20:36:19.644Z" }, + { url = "https://files.pythonhosted.org/packages/87/e9/d6b7ef9fecf42dfb418d93544af47c940aa83056c49e6021a564aafbc91f/coverage-7.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2e4b6b87bb0c846a9315e3ab4be2d52fac905100565f4b92f02c445c8799e257", size = 216068, upload-time = "2025-03-30T20:36:21.282Z" }, + { url = "https://files.pythonhosted.org/packages/59/f1/4da7717f0063a222db253e7121bd6a56f6fb1ba439dcc36659088793347c/coverage-7.8.0-py3-none-any.whl", hash = "sha256:dbf364b4c5e7bae9250528167dfe40219b62e2d573c854d74be213e1e52069f7", size = 203435, upload-time = "2025-03-30T20:36:43.61Z" }, ] [[package]] @@ -248,53 +248,53 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/33/c00162f49c0e2fe8064a62cb92b93e50c74a72bc370ab92f86112b33ff62/cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1", size = 749258, upload_time = "2025-10-15T23:18:31.74Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/33/c00162f49c0e2fe8064a62cb92b93e50c74a72bc370ab92f86112b33ff62/cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1", size = 749258, upload-time = "2025-10-15T23:18:31.74Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/42/9c391dd801d6cf0d561b5890549d4b27bafcc53b39c31a817e69d87c625b/cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a", size = 7225004, upload_time = "2025-10-15T23:16:52.239Z" }, - { url = "https://files.pythonhosted.org/packages/1c/67/38769ca6b65f07461eb200e85fc1639b438bdc667be02cf7f2cd6a64601c/cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc", size = 4296667, upload_time = "2025-10-15T23:16:54.369Z" }, - { url = "https://files.pythonhosted.org/packages/5c/49/498c86566a1d80e978b42f0d702795f69887005548c041636df6ae1ca64c/cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d", size = 4450807, upload_time = "2025-10-15T23:16:56.414Z" }, - { url = "https://files.pythonhosted.org/packages/4b/0a/863a3604112174c8624a2ac3c038662d9e59970c7f926acdcfaed8d61142/cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb", size = 4299615, upload_time = "2025-10-15T23:16:58.442Z" }, - { url = "https://files.pythonhosted.org/packages/64/02/b73a533f6b64a69f3cd3872acb6ebc12aef924d8d103133bb3ea750dc703/cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849", size = 4016800, upload_time = "2025-10-15T23:17:00.378Z" }, - { url = "https://files.pythonhosted.org/packages/25/d5/16e41afbfa450cde85a3b7ec599bebefaef16b5c6ba4ec49a3532336ed72/cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8", size = 4984707, upload_time = "2025-10-15T23:17:01.98Z" }, - { url = "https://files.pythonhosted.org/packages/c9/56/e7e69b427c3878352c2fb9b450bd0e19ed552753491d39d7d0a2f5226d41/cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec", size = 4482541, upload_time = "2025-10-15T23:17:04.078Z" }, - { url = "https://files.pythonhosted.org/packages/78/f6/50736d40d97e8483172f1bb6e698895b92a223dba513b0ca6f06b2365339/cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91", size = 4299464, upload_time = "2025-10-15T23:17:05.483Z" }, - { url = "https://files.pythonhosted.org/packages/00/de/d8e26b1a855f19d9994a19c702fa2e93b0456beccbcfe437eda00e0701f2/cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e", size = 4950838, upload_time = "2025-10-15T23:17:07.425Z" }, - { url = "https://files.pythonhosted.org/packages/8f/29/798fc4ec461a1c9e9f735f2fc58741b0daae30688f41b2497dcbc9ed1355/cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926", size = 4481596, upload_time = "2025-10-15T23:17:09.343Z" }, - { url = "https://files.pythonhosted.org/packages/15/8d/03cd48b20a573adfff7652b76271078e3045b9f49387920e7f1f631d125e/cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71", size = 4426782, upload_time = "2025-10-15T23:17:11.22Z" }, - { url = "https://files.pythonhosted.org/packages/fa/b1/ebacbfe53317d55cf33165bda24c86523497a6881f339f9aae5c2e13e57b/cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac", size = 4698381, upload_time = "2025-10-15T23:17:12.829Z" }, - { url = "https://files.pythonhosted.org/packages/96/92/8a6a9525893325fc057a01f654d7efc2c64b9de90413adcf605a85744ff4/cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018", size = 3055988, upload_time = "2025-10-15T23:17:14.65Z" }, - { url = "https://files.pythonhosted.org/packages/7e/bf/80fbf45253ea585a1e492a6a17efcb93467701fa79e71550a430c5e60df0/cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb", size = 3514451, upload_time = "2025-10-15T23:17:16.142Z" }, - { url = "https://files.pythonhosted.org/packages/2e/af/9b302da4c87b0beb9db4e756386a7c6c5b8003cd0e742277888d352ae91d/cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c", size = 2928007, upload_time = "2025-10-15T23:17:18.04Z" }, - { url = "https://files.pythonhosted.org/packages/f5/e2/a510aa736755bffa9d2f75029c229111a1d02f8ecd5de03078f4c18d91a3/cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217", size = 7158012, upload_time = "2025-10-15T23:17:19.982Z" }, - { url = "https://files.pythonhosted.org/packages/73/dc/9aa866fbdbb95b02e7f9d086f1fccfeebf8953509b87e3f28fff927ff8a0/cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5", size = 4288728, upload_time = "2025-10-15T23:17:21.527Z" }, - { url = "https://files.pythonhosted.org/packages/c5/fd/bc1daf8230eaa075184cbbf5f8cd00ba9db4fd32d63fb83da4671b72ed8a/cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715", size = 4435078, upload_time = "2025-10-15T23:17:23.042Z" }, - { url = "https://files.pythonhosted.org/packages/82/98/d3bd5407ce4c60017f8ff9e63ffee4200ab3e23fe05b765cab805a7db008/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54", size = 4293460, upload_time = "2025-10-15T23:17:24.885Z" }, - { url = "https://files.pythonhosted.org/packages/26/e9/e23e7900983c2b8af7a08098db406cf989d7f09caea7897e347598d4cd5b/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459", size = 3995237, upload_time = "2025-10-15T23:17:26.449Z" }, - { url = "https://files.pythonhosted.org/packages/91/15/af68c509d4a138cfe299d0d7ddb14afba15233223ebd933b4bbdbc7155d3/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422", size = 4967344, upload_time = "2025-10-15T23:17:28.06Z" }, - { url = "https://files.pythonhosted.org/packages/ca/e3/8643d077c53868b681af077edf6b3cb58288b5423610f21c62aadcbe99f4/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7", size = 4466564, upload_time = "2025-10-15T23:17:29.665Z" }, - { url = "https://files.pythonhosted.org/packages/0e/43/c1e8726fa59c236ff477ff2b5dc071e54b21e5a1e51aa2cee1676f1c986f/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044", size = 4292415, upload_time = "2025-10-15T23:17:31.686Z" }, - { url = "https://files.pythonhosted.org/packages/42/f9/2f8fefdb1aee8a8e3256a0568cffc4e6d517b256a2fe97a029b3f1b9fe7e/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665", size = 4931457, upload_time = "2025-10-15T23:17:33.478Z" }, - { url = "https://files.pythonhosted.org/packages/79/30/9b54127a9a778ccd6d27c3da7563e9f2d341826075ceab89ae3b41bf5be2/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3", size = 4466074, upload_time = "2025-10-15T23:17:35.158Z" }, - { url = "https://files.pythonhosted.org/packages/ac/68/b4f4a10928e26c941b1b6a179143af9f4d27d88fe84a6a3c53592d2e76bf/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20", size = 4420569, upload_time = "2025-10-15T23:17:37.188Z" }, - { url = "https://files.pythonhosted.org/packages/a3/49/3746dab4c0d1979888f125226357d3262a6dd40e114ac29e3d2abdf1ec55/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de", size = 4681941, upload_time = "2025-10-15T23:17:39.236Z" }, - { url = "https://files.pythonhosted.org/packages/fd/30/27654c1dbaf7e4a3531fa1fc77986d04aefa4d6d78259a62c9dc13d7ad36/cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914", size = 3022339, upload_time = "2025-10-15T23:17:40.888Z" }, - { url = "https://files.pythonhosted.org/packages/f6/30/640f34ccd4d2a1bc88367b54b926b781b5a018d65f404d409aba76a84b1c/cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db", size = 3494315, upload_time = "2025-10-15T23:17:42.769Z" }, - { url = "https://files.pythonhosted.org/packages/ba/8b/88cc7e3bd0a8e7b861f26981f7b820e1f46aa9d26cc482d0feba0ecb4919/cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21", size = 2919331, upload_time = "2025-10-15T23:17:44.468Z" }, - { url = "https://files.pythonhosted.org/packages/fd/23/45fe7f376a7df8daf6da3556603b36f53475a99ce4faacb6ba2cf3d82021/cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936", size = 7218248, upload_time = "2025-10-15T23:17:46.294Z" }, - { url = "https://files.pythonhosted.org/packages/27/32/b68d27471372737054cbd34c84981f9edbc24fe67ca225d389799614e27f/cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683", size = 4294089, upload_time = "2025-10-15T23:17:48.269Z" }, - { url = "https://files.pythonhosted.org/packages/26/42/fa8389d4478368743e24e61eea78846a0006caffaf72ea24a15159215a14/cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d", size = 4440029, upload_time = "2025-10-15T23:17:49.837Z" }, - { url = "https://files.pythonhosted.org/packages/5f/eb/f483db0ec5ac040824f269e93dd2bd8a21ecd1027e77ad7bdf6914f2fd80/cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0", size = 4297222, upload_time = "2025-10-15T23:17:51.357Z" }, - { url = "https://files.pythonhosted.org/packages/fd/cf/da9502c4e1912cb1da3807ea3618a6829bee8207456fbbeebc361ec38ba3/cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc", size = 4012280, upload_time = "2025-10-15T23:17:52.964Z" }, - { url = "https://files.pythonhosted.org/packages/6b/8f/9adb86b93330e0df8b3dcf03eae67c33ba89958fc2e03862ef1ac2b42465/cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3", size = 4978958, upload_time = "2025-10-15T23:17:54.965Z" }, - { url = "https://files.pythonhosted.org/packages/d1/a0/5fa77988289c34bdb9f913f5606ecc9ada1adb5ae870bd0d1054a7021cc4/cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971", size = 4473714, upload_time = "2025-10-15T23:17:56.754Z" }, - { url = "https://files.pythonhosted.org/packages/14/e5/fc82d72a58d41c393697aa18c9abe5ae1214ff6f2a5c18ac470f92777895/cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac", size = 4296970, upload_time = "2025-10-15T23:17:58.588Z" }, - { url = "https://files.pythonhosted.org/packages/78/06/5663ed35438d0b09056973994f1aec467492b33bd31da36e468b01ec1097/cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04", size = 4940236, upload_time = "2025-10-15T23:18:00.897Z" }, - { url = "https://files.pythonhosted.org/packages/fc/59/873633f3f2dcd8a053b8dd1d38f783043b5fce589c0f6988bf55ef57e43e/cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506", size = 4472642, upload_time = "2025-10-15T23:18:02.749Z" }, - { url = "https://files.pythonhosted.org/packages/3d/39/8e71f3930e40f6877737d6f69248cf74d4e34b886a3967d32f919cc50d3b/cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963", size = 4423126, upload_time = "2025-10-15T23:18:04.85Z" }, - { url = "https://files.pythonhosted.org/packages/cd/c7/f65027c2810e14c3e7268353b1681932b87e5a48e65505d8cc17c99e36ae/cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4", size = 4686573, upload_time = "2025-10-15T23:18:06.908Z" }, - { url = "https://files.pythonhosted.org/packages/0a/6e/1c8331ddf91ca4730ab3086a0f1be19c65510a33b5a441cb334e7a2d2560/cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df", size = 3036695, upload_time = "2025-10-15T23:18:08.672Z" }, - { url = "https://files.pythonhosted.org/packages/90/45/b0d691df20633eff80955a0fc7695ff9051ffce8b69741444bd9ed7bd0db/cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f", size = 3501720, upload_time = "2025-10-15T23:18:10.632Z" }, - { url = "https://files.pythonhosted.org/packages/e8/cb/2da4cc83f5edb9c3257d09e1e7ab7b23f049c7962cae8d842bbef0a9cec9/cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372", size = 2918740, upload_time = "2025-10-15T23:18:12.277Z" }, + { url = "https://files.pythonhosted.org/packages/1d/42/9c391dd801d6cf0d561b5890549d4b27bafcc53b39c31a817e69d87c625b/cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a", size = 7225004, upload-time = "2025-10-15T23:16:52.239Z" }, + { url = "https://files.pythonhosted.org/packages/1c/67/38769ca6b65f07461eb200e85fc1639b438bdc667be02cf7f2cd6a64601c/cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc", size = 4296667, upload-time = "2025-10-15T23:16:54.369Z" }, + { url = "https://files.pythonhosted.org/packages/5c/49/498c86566a1d80e978b42f0d702795f69887005548c041636df6ae1ca64c/cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d", size = 4450807, upload-time = "2025-10-15T23:16:56.414Z" }, + { url = "https://files.pythonhosted.org/packages/4b/0a/863a3604112174c8624a2ac3c038662d9e59970c7f926acdcfaed8d61142/cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb", size = 4299615, upload-time = "2025-10-15T23:16:58.442Z" }, + { url = "https://files.pythonhosted.org/packages/64/02/b73a533f6b64a69f3cd3872acb6ebc12aef924d8d103133bb3ea750dc703/cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849", size = 4016800, upload-time = "2025-10-15T23:17:00.378Z" }, + { url = "https://files.pythonhosted.org/packages/25/d5/16e41afbfa450cde85a3b7ec599bebefaef16b5c6ba4ec49a3532336ed72/cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8", size = 4984707, upload-time = "2025-10-15T23:17:01.98Z" }, + { url = "https://files.pythonhosted.org/packages/c9/56/e7e69b427c3878352c2fb9b450bd0e19ed552753491d39d7d0a2f5226d41/cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec", size = 4482541, upload-time = "2025-10-15T23:17:04.078Z" }, + { url = "https://files.pythonhosted.org/packages/78/f6/50736d40d97e8483172f1bb6e698895b92a223dba513b0ca6f06b2365339/cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91", size = 4299464, upload-time = "2025-10-15T23:17:05.483Z" }, + { url = "https://files.pythonhosted.org/packages/00/de/d8e26b1a855f19d9994a19c702fa2e93b0456beccbcfe437eda00e0701f2/cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e", size = 4950838, upload-time = "2025-10-15T23:17:07.425Z" }, + { url = "https://files.pythonhosted.org/packages/8f/29/798fc4ec461a1c9e9f735f2fc58741b0daae30688f41b2497dcbc9ed1355/cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926", size = 4481596, upload-time = "2025-10-15T23:17:09.343Z" }, + { url = "https://files.pythonhosted.org/packages/15/8d/03cd48b20a573adfff7652b76271078e3045b9f49387920e7f1f631d125e/cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71", size = 4426782, upload-time = "2025-10-15T23:17:11.22Z" }, + { url = "https://files.pythonhosted.org/packages/fa/b1/ebacbfe53317d55cf33165bda24c86523497a6881f339f9aae5c2e13e57b/cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac", size = 4698381, upload-time = "2025-10-15T23:17:12.829Z" }, + { url = "https://files.pythonhosted.org/packages/96/92/8a6a9525893325fc057a01f654d7efc2c64b9de90413adcf605a85744ff4/cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018", size = 3055988, upload-time = "2025-10-15T23:17:14.65Z" }, + { url = "https://files.pythonhosted.org/packages/7e/bf/80fbf45253ea585a1e492a6a17efcb93467701fa79e71550a430c5e60df0/cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb", size = 3514451, upload-time = "2025-10-15T23:17:16.142Z" }, + { url = "https://files.pythonhosted.org/packages/2e/af/9b302da4c87b0beb9db4e756386a7c6c5b8003cd0e742277888d352ae91d/cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c", size = 2928007, upload-time = "2025-10-15T23:17:18.04Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e2/a510aa736755bffa9d2f75029c229111a1d02f8ecd5de03078f4c18d91a3/cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217", size = 7158012, upload-time = "2025-10-15T23:17:19.982Z" }, + { url = "https://files.pythonhosted.org/packages/73/dc/9aa866fbdbb95b02e7f9d086f1fccfeebf8953509b87e3f28fff927ff8a0/cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5", size = 4288728, upload-time = "2025-10-15T23:17:21.527Z" }, + { url = "https://files.pythonhosted.org/packages/c5/fd/bc1daf8230eaa075184cbbf5f8cd00ba9db4fd32d63fb83da4671b72ed8a/cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715", size = 4435078, upload-time = "2025-10-15T23:17:23.042Z" }, + { url = "https://files.pythonhosted.org/packages/82/98/d3bd5407ce4c60017f8ff9e63ffee4200ab3e23fe05b765cab805a7db008/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54", size = 4293460, upload-time = "2025-10-15T23:17:24.885Z" }, + { url = "https://files.pythonhosted.org/packages/26/e9/e23e7900983c2b8af7a08098db406cf989d7f09caea7897e347598d4cd5b/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459", size = 3995237, upload-time = "2025-10-15T23:17:26.449Z" }, + { url = "https://files.pythonhosted.org/packages/91/15/af68c509d4a138cfe299d0d7ddb14afba15233223ebd933b4bbdbc7155d3/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422", size = 4967344, upload-time = "2025-10-15T23:17:28.06Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e3/8643d077c53868b681af077edf6b3cb58288b5423610f21c62aadcbe99f4/cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7", size = 4466564, upload-time = "2025-10-15T23:17:29.665Z" }, + { url = "https://files.pythonhosted.org/packages/0e/43/c1e8726fa59c236ff477ff2b5dc071e54b21e5a1e51aa2cee1676f1c986f/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044", size = 4292415, upload-time = "2025-10-15T23:17:31.686Z" }, + { url = "https://files.pythonhosted.org/packages/42/f9/2f8fefdb1aee8a8e3256a0568cffc4e6d517b256a2fe97a029b3f1b9fe7e/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665", size = 4931457, upload-time = "2025-10-15T23:17:33.478Z" }, + { url = "https://files.pythonhosted.org/packages/79/30/9b54127a9a778ccd6d27c3da7563e9f2d341826075ceab89ae3b41bf5be2/cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3", size = 4466074, upload-time = "2025-10-15T23:17:35.158Z" }, + { url = "https://files.pythonhosted.org/packages/ac/68/b4f4a10928e26c941b1b6a179143af9f4d27d88fe84a6a3c53592d2e76bf/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20", size = 4420569, upload-time = "2025-10-15T23:17:37.188Z" }, + { url = "https://files.pythonhosted.org/packages/a3/49/3746dab4c0d1979888f125226357d3262a6dd40e114ac29e3d2abdf1ec55/cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de", size = 4681941, upload-time = "2025-10-15T23:17:39.236Z" }, + { url = "https://files.pythonhosted.org/packages/fd/30/27654c1dbaf7e4a3531fa1fc77986d04aefa4d6d78259a62c9dc13d7ad36/cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914", size = 3022339, upload-time = "2025-10-15T23:17:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/f6/30/640f34ccd4d2a1bc88367b54b926b781b5a018d65f404d409aba76a84b1c/cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db", size = 3494315, upload-time = "2025-10-15T23:17:42.769Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8b/88cc7e3bd0a8e7b861f26981f7b820e1f46aa9d26cc482d0feba0ecb4919/cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21", size = 2919331, upload-time = "2025-10-15T23:17:44.468Z" }, + { url = "https://files.pythonhosted.org/packages/fd/23/45fe7f376a7df8daf6da3556603b36f53475a99ce4faacb6ba2cf3d82021/cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936", size = 7218248, upload-time = "2025-10-15T23:17:46.294Z" }, + { url = "https://files.pythonhosted.org/packages/27/32/b68d27471372737054cbd34c84981f9edbc24fe67ca225d389799614e27f/cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683", size = 4294089, upload-time = "2025-10-15T23:17:48.269Z" }, + { url = "https://files.pythonhosted.org/packages/26/42/fa8389d4478368743e24e61eea78846a0006caffaf72ea24a15159215a14/cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d", size = 4440029, upload-time = "2025-10-15T23:17:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/5f/eb/f483db0ec5ac040824f269e93dd2bd8a21ecd1027e77ad7bdf6914f2fd80/cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0", size = 4297222, upload-time = "2025-10-15T23:17:51.357Z" }, + { url = "https://files.pythonhosted.org/packages/fd/cf/da9502c4e1912cb1da3807ea3618a6829bee8207456fbbeebc361ec38ba3/cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc", size = 4012280, upload-time = "2025-10-15T23:17:52.964Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8f/9adb86b93330e0df8b3dcf03eae67c33ba89958fc2e03862ef1ac2b42465/cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3", size = 4978958, upload-time = "2025-10-15T23:17:54.965Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a0/5fa77988289c34bdb9f913f5606ecc9ada1adb5ae870bd0d1054a7021cc4/cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971", size = 4473714, upload-time = "2025-10-15T23:17:56.754Z" }, + { url = "https://files.pythonhosted.org/packages/14/e5/fc82d72a58d41c393697aa18c9abe5ae1214ff6f2a5c18ac470f92777895/cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac", size = 4296970, upload-time = "2025-10-15T23:17:58.588Z" }, + { url = "https://files.pythonhosted.org/packages/78/06/5663ed35438d0b09056973994f1aec467492b33bd31da36e468b01ec1097/cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04", size = 4940236, upload-time = "2025-10-15T23:18:00.897Z" }, + { url = "https://files.pythonhosted.org/packages/fc/59/873633f3f2dcd8a053b8dd1d38f783043b5fce589c0f6988bf55ef57e43e/cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506", size = 4472642, upload-time = "2025-10-15T23:18:02.749Z" }, + { url = "https://files.pythonhosted.org/packages/3d/39/8e71f3930e40f6877737d6f69248cf74d4e34b886a3967d32f919cc50d3b/cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963", size = 4423126, upload-time = "2025-10-15T23:18:04.85Z" }, + { url = "https://files.pythonhosted.org/packages/cd/c7/f65027c2810e14c3e7268353b1681932b87e5a48e65505d8cc17c99e36ae/cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4", size = 4686573, upload-time = "2025-10-15T23:18:06.908Z" }, + { url = "https://files.pythonhosted.org/packages/0a/6e/1c8331ddf91ca4730ab3086a0f1be19c65510a33b5a441cb334e7a2d2560/cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df", size = 3036695, upload-time = "2025-10-15T23:18:08.672Z" }, + { url = "https://files.pythonhosted.org/packages/90/45/b0d691df20633eff80955a0fc7695ff9051ffce8b69741444bd9ed7bd0db/cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f", size = 3501720, upload-time = "2025-10-15T23:18:10.632Z" }, + { url = "https://files.pythonhosted.org/packages/e8/cb/2da4cc83f5edb9c3257d09e1e7ab7b23f049c7962cae8d842bbef0a9cec9/cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372", size = 2918740, upload-time = "2025-10-15T23:18:12.277Z" }, ] [[package]] @@ -304,9 +304,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/76/de/ea55722907bd1b2389b01e362faa3c66a09d5a8463c13d44c80da7b32497/databases-0.9.0.tar.gz", hash = "sha256:d2f259677609bf187737644c95fa41701072e995dfeb8d2882f335795c5b61b0", size = 31084, upload_time = "2024-03-01T17:39:28.378Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/de/ea55722907bd1b2389b01e362faa3c66a09d5a8463c13d44c80da7b32497/databases-0.9.0.tar.gz", hash = "sha256:d2f259677609bf187737644c95fa41701072e995dfeb8d2882f335795c5b61b0", size = 31084, upload-time = "2024-03-01T17:39:28.378Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/43/6035922af5471f1a196851831a1d5f403447401b395f474bf673efa8959f/databases-0.9.0-py3-none-any.whl", hash = "sha256:9ee657c9863b34f8d3a06c06eafbe1bda68af2a434b56996312edf1f1c0b6297", size = 25580, upload_time = "2024-03-01T17:39:26.352Z" }, + { url = "https://files.pythonhosted.org/packages/d5/43/6035922af5471f1a196851831a1d5f403447401b395f474bf673efa8959f/databases-0.9.0-py3-none-any.whl", hash = "sha256:9ee657c9863b34f8d3a06c06eafbe1bda68af2a434b56996312edf1f1c0b6297", size = 25580, upload-time = "2024-03-01T17:39:26.352Z" }, ] [package.optional-dependencies] @@ -318,9 +318,9 @@ sqlite = [ name = "dnspython" version = "2.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/4a/263763cb2ba3816dd94b08ad3a33d5fdae34ecb856678773cc40a3605829/dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1", size = 345197, upload_time = "2024-10-05T20:14:59.362Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/4a/263763cb2ba3816dd94b08ad3a33d5fdae34ecb856678773cc40a3605829/dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1", size = 345197, upload-time = "2024-10-05T20:14:59.362Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", size = 313632, upload_time = "2024-10-05T20:14:57.687Z" }, + { url = "https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", size = 313632, upload-time = "2024-10-05T20:14:57.687Z" }, ] [[package]] @@ -330,9 +330,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c0/1f/924e3caae75f471eae4b26bd13b698f6af2c44279f67af317439c2f4c46a/ecdsa-0.19.1.tar.gz", hash = "sha256:478cba7b62555866fcb3bb3fe985e06decbdb68ef55713c4e5ab98c57d508e61", size = 201793, upload_time = "2025-03-13T11:52:43.25Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c0/1f/924e3caae75f471eae4b26bd13b698f6af2c44279f67af317439c2f4c46a/ecdsa-0.19.1.tar.gz", hash = "sha256:478cba7b62555866fcb3bb3fe985e06decbdb68ef55713c4e5ab98c57d508e61", size = 201793, upload-time = "2025-03-13T11:52:43.25Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/a3/460c57f094a4a165c84a1341c373b0a4f5ec6ac244b998d5021aade89b77/ecdsa-0.19.1-py2.py3-none-any.whl", hash = "sha256:30638e27cf77b7e15c4c4cc1973720149e1033827cfd00661ca5c8cc0cdb24c3", size = 150607, upload_time = "2025-03-13T11:52:41.757Z" }, + { url = "https://files.pythonhosted.org/packages/cb/a3/460c57f094a4a165c84a1341c373b0a4f5ec6ac244b998d5021aade89b77/ecdsa-0.19.1-py2.py3-none-any.whl", hash = "sha256:30638e27cf77b7e15c4c4cc1973720149e1033827cfd00661ca5c8cc0cdb24c3", size = 150607, upload-time = "2025-03-13T11:52:41.757Z" }, ] [[package]] @@ -343,9 +343,9 @@ dependencies = [ { name = "dnspython" }, { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/48/ce/13508a1ec3f8bb981ae4ca79ea40384becc868bfae97fd1c942bb3a001b1/email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7", size = 48967, upload_time = "2024-06-20T11:30:30.034Z" } +sdist = { url = "https://files.pythonhosted.org/packages/48/ce/13508a1ec3f8bb981ae4ca79ea40384becc868bfae97fd1c942bb3a001b1/email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7", size = 48967, upload-time = "2024-06-20T11:30:30.034Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", size = 33521, upload_time = "2024-06-20T11:30:28.248Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", size = 33521, upload-time = "2024-06-20T11:30:28.248Z" }, ] [[package]] @@ -357,9 +357,9 @@ dependencies = [ { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f4/55/ae499352d82338331ca1e28c7f4a63bfd09479b16395dce38cf50a39e2c2/fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681", size = 295236, upload_time = "2025-03-23T22:55:43.822Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f4/55/ae499352d82338331ca1e28c7f4a63bfd09479b16395dce38cf50a39e2c2/fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681", size = 295236, upload-time = "2025-03-23T22:55:43.822Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/b3/b51f09c2ba432a576fe63758bddc81f78f0c6309d9e5c10d194313bf021e/fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d", size = 95164, upload_time = "2025-03-23T22:55:42.101Z" }, + { url = "https://files.pythonhosted.org/packages/50/b3/b51f09c2ba432a576fe63758bddc81f78f0c6309d9e5c10d194313bf021e/fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d", size = 95164, upload-time = "2025-03-23T22:55:42.101Z" }, ] [package.optional-dependencies] @@ -381,9 +381,9 @@ dependencies = [ { name = "typer" }, { name = "uvicorn", extra = ["standard"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/73/82a5831fbbf8ed75905bacf5b2d9d3dfd6f04d6968b29fe6f72a5ae9ceb1/fastapi_cli-0.0.7.tar.gz", hash = "sha256:02b3b65956f526412515907a0793c9094abd4bfb5457b389f645b0ea6ba3605e", size = 16753, upload_time = "2024-12-15T14:28:10.028Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/73/82a5831fbbf8ed75905bacf5b2d9d3dfd6f04d6968b29fe6f72a5ae9ceb1/fastapi_cli-0.0.7.tar.gz", hash = "sha256:02b3b65956f526412515907a0793c9094abd4bfb5457b389f645b0ea6ba3605e", size = 16753, upload-time = "2024-12-15T14:28:10.028Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a1/e6/5daefc851b514ce2287d8f5d358ae4341089185f78f3217a69d0ce3a390c/fastapi_cli-0.0.7-py3-none-any.whl", hash = "sha256:d549368ff584b2804336c61f192d86ddea080c11255f375959627911944804f4", size = 10705, upload_time = "2024-12-15T14:28:06.18Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e6/5daefc851b514ce2287d8f5d358ae4341089185f78f3217a69d0ce3a390c/fastapi_cli-0.0.7-py3-none-any.whl", hash = "sha256:d549368ff584b2804336c61f192d86ddea080c11255f375959627911944804f4", size = 10705, upload-time = "2024-12-15T14:28:06.18Z" }, ] [package.optional-dependencies] @@ -399,43 +399,41 @@ dependencies = [ { name = "fastapi" }, { name = "pyjwt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/87/92/cce264b1a065e9f498358669abb6806a1c4e1c3c32e3f5e2c4060281932b/fastapi-jwt-auth-0.5.0.tar.gz", hash = "sha256:d98068a9e828fe5909a1f338efabc3bb53149f11a9d2d395ab9d90fbb486b375", size = 40727, upload_time = "2020-11-06T11:11:00.646Z" } +sdist = { url = "https://files.pythonhosted.org/packages/87/92/cce264b1a065e9f498358669abb6806a1c4e1c3c32e3f5e2c4060281932b/fastapi-jwt-auth-0.5.0.tar.gz", hash = "sha256:d98068a9e828fe5909a1f338efabc3bb53149f11a9d2d395ab9d90fbb486b375", size = 40727, upload-time = "2020-11-06T11:11:00.646Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/14/90/fb0ab938d2536d12b26abbb5cb404d1039d317351adb31cb06f4c2263b04/fastapi_jwt_auth-0.5.0-py3-none-any.whl", hash = "sha256:43110a227e36f93b99257a1c79e66df8ed3d4c893291db8f9db2686192011f17", size = 12496, upload_time = "2020-11-06T11:10:56.254Z" }, + { url = "https://files.pythonhosted.org/packages/14/90/fb0ab938d2536d12b26abbb5cb404d1039d317351adb31cb06f4c2263b04/fastapi_jwt_auth-0.5.0-py3-none-any.whl", hash = "sha256:43110a227e36f93b99257a1c79e66df8ed3d4c893291db8f9db2686192011f17", size = 12496, upload-time = "2020-11-06T11:10:56.254Z" }, ] [[package]] name = "greenlet" version = "3.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/9c/666d8c71b18d0189cf801c0e0b31c4bfc609ac823883286045b1f3ae8994/greenlet-3.2.0.tar.gz", hash = "sha256:1d2d43bd711a43db8d9b9187500e6432ddb4fafe112d082ffabca8660a9e01a7", size = 183685, upload_time = "2025-04-15T16:21:26.141Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/9c/666d8c71b18d0189cf801c0e0b31c4bfc609ac823883286045b1f3ae8994/greenlet-3.2.0.tar.gz", hash = "sha256:1d2d43bd711a43db8d9b9187500e6432ddb4fafe112d082ffabca8660a9e01a7", size = 183685, upload-time = "2025-04-15T16:21:26.141Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c9/43/c0b655d4d7eae19282b028bcec449e5c80626ad0d8d0ca3703f9b1c29258/greenlet-3.2.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:b86a3ccc865ae601f446af042707b749eebc297928ea7bd0c5f60c56525850be", size = 269131, upload_time = "2025-04-15T16:19:19.469Z" }, - { url = "https://files.pythonhosted.org/packages/7c/7d/c8f51c373c7f7ac0f73d04a6fd77ab34f6f643cb41a0d186d05ba96708e7/greenlet-3.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:144283ad88ed77f3ebd74710dd419b55dd15d18704b0ae05935766a93f5671c5", size = 637323, upload_time = "2025-04-15T16:49:02.677Z" }, - { url = "https://files.pythonhosted.org/packages/89/65/c3ee41b2e56586737d6e124b250583695628ffa6b324855b3a1267a8d1d9/greenlet-3.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5be69cd50994b8465c3ad1467f9e63001f76e53a89440ad4440d1b6d52591280", size = 651430, upload_time = "2025-04-15T16:50:43.445Z" }, - { url = "https://files.pythonhosted.org/packages/f0/07/33bd7a3dcde1db7259371d026ce76be1eb653d2d892334fc79a500b3c5ee/greenlet-3.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:47aeadd1e8fbdef8fdceb8fb4edc0cbb398a57568d56fd68f2bc00d0d809e6b6", size = 645798, upload_time = "2025-04-15T16:55:03.795Z" }, - { url = "https://files.pythonhosted.org/packages/35/5b/33c221a6a867030b0b770513a1b78f6c30e04294131dafdc8da78906bbe6/greenlet-3.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18adc14ab154ca6e53eecc9dc50ff17aeb7ba70b7e14779b26e16d71efa90038", size = 648271, upload_time = "2025-04-15T16:22:42.458Z" }, - { url = "https://files.pythonhosted.org/packages/4d/dd/d6452248fa6093504e3b7525dc2bdc4e55a4296ec6ee74ba241a51d852e2/greenlet-3.2.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8622b33d8694ec373ad55050c3d4e49818132b44852158442e1931bb02af336", size = 606779, upload_time = "2025-04-15T16:22:41.417Z" }, - { url = "https://files.pythonhosted.org/packages/9d/24/160f04d2589bcb15b8661dcd1763437b22e01643626899a4139bf98f02af/greenlet-3.2.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:e8ac9a2c20fbff3d0b853e9ef705cdedb70d9276af977d1ec1cde86a87a4c821", size = 1117968, upload_time = "2025-04-15T16:52:53.627Z" }, - { url = "https://files.pythonhosted.org/packages/6c/ff/c6e3f3a5168fef5209cfd9498b2b5dd77a0bf29dfc686a03dcc614cf4432/greenlet-3.2.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:cd37273dc7ca1d5da149b58c8b3ce0711181672ba1b09969663905a765affe21", size = 1145510, upload_time = "2025-04-15T16:23:01.873Z" }, - { url = "https://files.pythonhosted.org/packages/dc/62/5215e374819052e542b5bde06bd7d4a171454b6938c96a2384f21cb94279/greenlet-3.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8a8940a8d301828acd8b9f3f85db23069a692ff2933358861b19936e29946b95", size = 296004, upload_time = "2025-04-15T16:55:46.007Z" }, - { url = "https://files.pythonhosted.org/packages/62/6d/dc9c909cba5cbf4b0833fce69912927a8ca74791c23c47b9fd4f28092108/greenlet-3.2.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee59db626760f1ca8da697a086454210d36a19f7abecc9922a2374c04b47735b", size = 629900, upload_time = "2025-04-15T16:49:04.099Z" }, - { url = "https://files.pythonhosted.org/packages/5e/a9/f3f304fbbbd604858ff3df303d7fa1d8f7f9e45a6ef74481aaf03aaac021/greenlet-3.2.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7154b13ef87a8b62fc05419f12d75532d7783586ad016c57b5de8a1c6feeb517", size = 635270, upload_time = "2025-04-15T16:50:44.769Z" }, - { url = "https://files.pythonhosted.org/packages/34/92/4b7b4e2e23ecc723cceef9fe3898e78c8e14e106cc7ba2f276a66161da3e/greenlet-3.2.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:199453d64b02d0c9d139e36d29681efd0e407ed8e2c0bf89d88878d6a787c28f", size = 632534, upload_time = "2025-04-15T16:55:05.203Z" }, - { url = "https://files.pythonhosted.org/packages/da/7f/91f0ecbe72c9d789fb7f400b39da9d1e87fcc2cf8746a9636479ba79ab01/greenlet-3.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0010e928e1901d36625f21d008618273f9dda26b516dbdecf873937d39c9dff0", size = 628826, upload_time = "2025-04-15T16:22:44.545Z" }, - { url = "https://files.pythonhosted.org/packages/9f/59/e449a44ce52b13751f55376d85adc155dd311608f6d2aa5b6bd2c8d15486/greenlet-3.2.0-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6005f7a86de836a1dc4b8d824a2339cdd5a1ca7cb1af55ea92575401f9952f4c", size = 593697, upload_time = "2025-04-15T16:22:43.796Z" }, - { url = "https://files.pythonhosted.org/packages/bb/09/cca3392927c5c990b7a8ede64ccd0712808438d6490d63ce6b8704d6df5f/greenlet-3.2.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:17fd241c0d50bacb7ce8ff77a30f94a2d0ca69434ba2e0187cf95a5414aeb7e1", size = 1105762, upload_time = "2025-04-15T16:52:55.245Z" }, - { url = "https://files.pythonhosted.org/packages/4d/b9/3d201f819afc3b7a8cd7ebe645f1a17799603e2d62c968154518f79f4881/greenlet-3.2.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:7b17a26abc6a1890bf77d5d6b71c0999705386b00060d15c10b8182679ff2790", size = 1125173, upload_time = "2025-04-15T16:23:03.009Z" }, - { url = "https://files.pythonhosted.org/packages/80/7b/773a30602234597fc2882091f8e1d1a38ea0b4419d99ca7ed82c827e2c3a/greenlet-3.2.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:397b6bbda06f8fe895893d96218cd6f6d855a6701dc45012ebe12262423cec8b", size = 269908, upload_time = "2025-04-15T16:20:33.58Z" }, + { url = "https://files.pythonhosted.org/packages/c9/43/c0b655d4d7eae19282b028bcec449e5c80626ad0d8d0ca3703f9b1c29258/greenlet-3.2.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:b86a3ccc865ae601f446af042707b749eebc297928ea7bd0c5f60c56525850be", size = 269131, upload-time = "2025-04-15T16:19:19.469Z" }, + { url = "https://files.pythonhosted.org/packages/7c/7d/c8f51c373c7f7ac0f73d04a6fd77ab34f6f643cb41a0d186d05ba96708e7/greenlet-3.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:144283ad88ed77f3ebd74710dd419b55dd15d18704b0ae05935766a93f5671c5", size = 637323, upload-time = "2025-04-15T16:49:02.677Z" }, + { url = "https://files.pythonhosted.org/packages/89/65/c3ee41b2e56586737d6e124b250583695628ffa6b324855b3a1267a8d1d9/greenlet-3.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5be69cd50994b8465c3ad1467f9e63001f76e53a89440ad4440d1b6d52591280", size = 651430, upload-time = "2025-04-15T16:50:43.445Z" }, + { url = "https://files.pythonhosted.org/packages/35/5b/33c221a6a867030b0b770513a1b78f6c30e04294131dafdc8da78906bbe6/greenlet-3.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18adc14ab154ca6e53eecc9dc50ff17aeb7ba70b7e14779b26e16d71efa90038", size = 648271, upload-time = "2025-04-15T16:22:42.458Z" }, + { url = "https://files.pythonhosted.org/packages/4d/dd/d6452248fa6093504e3b7525dc2bdc4e55a4296ec6ee74ba241a51d852e2/greenlet-3.2.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8622b33d8694ec373ad55050c3d4e49818132b44852158442e1931bb02af336", size = 606779, upload-time = "2025-04-15T16:22:41.417Z" }, + { url = "https://files.pythonhosted.org/packages/9d/24/160f04d2589bcb15b8661dcd1763437b22e01643626899a4139bf98f02af/greenlet-3.2.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:e8ac9a2c20fbff3d0b853e9ef705cdedb70d9276af977d1ec1cde86a87a4c821", size = 1117968, upload-time = "2025-04-15T16:52:53.627Z" }, + { url = "https://files.pythonhosted.org/packages/6c/ff/c6e3f3a5168fef5209cfd9498b2b5dd77a0bf29dfc686a03dcc614cf4432/greenlet-3.2.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:cd37273dc7ca1d5da149b58c8b3ce0711181672ba1b09969663905a765affe21", size = 1145510, upload-time = "2025-04-15T16:23:01.873Z" }, + { url = "https://files.pythonhosted.org/packages/dc/62/5215e374819052e542b5bde06bd7d4a171454b6938c96a2384f21cb94279/greenlet-3.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8a8940a8d301828acd8b9f3f85db23069a692ff2933358861b19936e29946b95", size = 296004, upload-time = "2025-04-15T16:55:46.007Z" }, + { url = "https://files.pythonhosted.org/packages/62/6d/dc9c909cba5cbf4b0833fce69912927a8ca74791c23c47b9fd4f28092108/greenlet-3.2.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee59db626760f1ca8da697a086454210d36a19f7abecc9922a2374c04b47735b", size = 629900, upload-time = "2025-04-15T16:49:04.099Z" }, + { url = "https://files.pythonhosted.org/packages/5e/a9/f3f304fbbbd604858ff3df303d7fa1d8f7f9e45a6ef74481aaf03aaac021/greenlet-3.2.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7154b13ef87a8b62fc05419f12d75532d7783586ad016c57b5de8a1c6feeb517", size = 635270, upload-time = "2025-04-15T16:50:44.769Z" }, + { url = "https://files.pythonhosted.org/packages/da/7f/91f0ecbe72c9d789fb7f400b39da9d1e87fcc2cf8746a9636479ba79ab01/greenlet-3.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0010e928e1901d36625f21d008618273f9dda26b516dbdecf873937d39c9dff0", size = 628826, upload-time = "2025-04-15T16:22:44.545Z" }, + { url = "https://files.pythonhosted.org/packages/9f/59/e449a44ce52b13751f55376d85adc155dd311608f6d2aa5b6bd2c8d15486/greenlet-3.2.0-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6005f7a86de836a1dc4b8d824a2339cdd5a1ca7cb1af55ea92575401f9952f4c", size = 593697, upload-time = "2025-04-15T16:22:43.796Z" }, + { url = "https://files.pythonhosted.org/packages/bb/09/cca3392927c5c990b7a8ede64ccd0712808438d6490d63ce6b8704d6df5f/greenlet-3.2.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:17fd241c0d50bacb7ce8ff77a30f94a2d0ca69434ba2e0187cf95a5414aeb7e1", size = 1105762, upload-time = "2025-04-15T16:52:55.245Z" }, + { url = "https://files.pythonhosted.org/packages/4d/b9/3d201f819afc3b7a8cd7ebe645f1a17799603e2d62c968154518f79f4881/greenlet-3.2.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:7b17a26abc6a1890bf77d5d6b71c0999705386b00060d15c10b8182679ff2790", size = 1125173, upload-time = "2025-04-15T16:23:03.009Z" }, + { url = "https://files.pythonhosted.org/packages/80/7b/773a30602234597fc2882091f8e1d1a38ea0b4419d99ca7ed82c827e2c3a/greenlet-3.2.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:397b6bbda06f8fe895893d96218cd6f6d855a6701dc45012ebe12262423cec8b", size = 269908, upload-time = "2025-04-15T16:20:33.58Z" }, ] [[package]] name = "h11" version = "0.14.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418, upload_time = "2022-09-25T15:40:01.519Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418, upload-time = "2022-09-25T15:40:01.519Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259, upload_time = "2022-09-25T15:39:59.68Z" }, + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259, upload-time = "2022-09-25T15:39:59.68Z" }, ] [[package]] @@ -448,24 +446,24 @@ dependencies = [ { name = "h11" }, { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/ad/c98ecdbfe04417e71e143bf2f2fb29128e4787d78d1cedba21bd250c7e7a/httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888", size = 62676, upload_time = "2023-07-05T12:09:31.29Z" } +sdist = { url = "https://files.pythonhosted.org/packages/63/ad/c98ecdbfe04417e71e143bf2f2fb29128e4787d78d1cedba21bd250c7e7a/httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888", size = 62676, upload-time = "2023-07-05T12:09:31.29Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/2c/2bde7ff8dd2064395555220cbf7cba79991172bf5315a07eb3ac7688d9f1/httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87", size = 74513, upload_time = "2023-07-05T12:09:29.425Z" }, + { url = "https://files.pythonhosted.org/packages/94/2c/2bde7ff8dd2064395555220cbf7cba79991172bf5315a07eb3ac7688d9f1/httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87", size = 74513, upload-time = "2023-07-05T12:09:29.425Z" }, ] [[package]] name = "httptools" version = "0.6.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a7/9a/ce5e1f7e131522e6d3426e8e7a490b3a01f39a6696602e1c4f33f9e94277/httptools-0.6.4.tar.gz", hash = "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c", size = 240639, upload_time = "2024-10-16T19:45:08.902Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/9a/ce5e1f7e131522e6d3426e8e7a490b3a01f39a6696602e1c4f33f9e94277/httptools-0.6.4.tar.gz", hash = "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c", size = 240639, upload-time = "2024-10-16T19:45:08.902Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/a3/9fe9ad23fd35f7de6b91eeb60848986058bd8b5a5c1e256f5860a160cc3e/httptools-0.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660", size = 197214, upload_time = "2024-10-16T19:44:38.738Z" }, - { url = "https://files.pythonhosted.org/packages/ea/d9/82d5e68bab783b632023f2fa31db20bebb4e89dfc4d2293945fd68484ee4/httptools-0.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083", size = 102431, upload_time = "2024-10-16T19:44:39.818Z" }, - { url = "https://files.pythonhosted.org/packages/96/c1/cb499655cbdbfb57b577734fde02f6fa0bbc3fe9fb4d87b742b512908dff/httptools-0.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3", size = 473121, upload_time = "2024-10-16T19:44:41.189Z" }, - { url = "https://files.pythonhosted.org/packages/af/71/ee32fd358f8a3bb199b03261f10921716990808a675d8160b5383487a317/httptools-0.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071", size = 473805, upload_time = "2024-10-16T19:44:42.384Z" }, - { url = "https://files.pythonhosted.org/packages/8a/0a/0d4df132bfca1507114198b766f1737d57580c9ad1cf93c1ff673e3387be/httptools-0.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5", size = 448858, upload_time = "2024-10-16T19:44:43.959Z" }, - { url = "https://files.pythonhosted.org/packages/1e/6a/787004fdef2cabea27bad1073bf6a33f2437b4dbd3b6fb4a9d71172b1c7c/httptools-0.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0", size = 452042, upload_time = "2024-10-16T19:44:45.071Z" }, - { url = "https://files.pythonhosted.org/packages/4d/dc/7decab5c404d1d2cdc1bb330b1bf70e83d6af0396fd4fc76fc60c0d522bf/httptools-0.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8", size = 87682, upload_time = "2024-10-16T19:44:46.46Z" }, + { url = "https://files.pythonhosted.org/packages/94/a3/9fe9ad23fd35f7de6b91eeb60848986058bd8b5a5c1e256f5860a160cc3e/httptools-0.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660", size = 197214, upload-time = "2024-10-16T19:44:38.738Z" }, + { url = "https://files.pythonhosted.org/packages/ea/d9/82d5e68bab783b632023f2fa31db20bebb4e89dfc4d2293945fd68484ee4/httptools-0.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083", size = 102431, upload-time = "2024-10-16T19:44:39.818Z" }, + { url = "https://files.pythonhosted.org/packages/96/c1/cb499655cbdbfb57b577734fde02f6fa0bbc3fe9fb4d87b742b512908dff/httptools-0.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3", size = 473121, upload-time = "2024-10-16T19:44:41.189Z" }, + { url = "https://files.pythonhosted.org/packages/af/71/ee32fd358f8a3bb199b03261f10921716990808a675d8160b5383487a317/httptools-0.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071", size = 473805, upload-time = "2024-10-16T19:44:42.384Z" }, + { url = "https://files.pythonhosted.org/packages/8a/0a/0d4df132bfca1507114198b766f1737d57580c9ad1cf93c1ff673e3387be/httptools-0.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5", size = 448858, upload-time = "2024-10-16T19:44:43.959Z" }, + { url = "https://files.pythonhosted.org/packages/1e/6a/787004fdef2cabea27bad1073bf6a33f2437b4dbd3b6fb4a9d71172b1c7c/httptools-0.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0", size = 452042, upload-time = "2024-10-16T19:44:45.071Z" }, + { url = "https://files.pythonhosted.org/packages/4d/dc/7decab5c404d1d2cdc1bb330b1bf70e83d6af0396fd4fc76fc60c0d522bf/httptools-0.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8", size = 87682, upload-time = "2024-10-16T19:44:46.46Z" }, ] [[package]] @@ -478,27 +476,27 @@ dependencies = [ { name = "idna" }, { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f8/2a/114d454cb77657dbf6a293e69390b96318930ace9cd96b51b99682493276/httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd", size = 81858, upload_time = "2023-05-19T00:50:56.678Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/2a/114d454cb77657dbf6a293e69390b96318930ace9cd96b51b99682493276/httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd", size = 81858, upload-time = "2023-05-19T00:50:56.678Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/91/e41f64f03d2a13aee7e8c819d82ee3aa7cdc484d18c0ae859742597d5aa0/httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd", size = 75377, upload_time = "2023-05-19T00:50:54.91Z" }, + { url = "https://files.pythonhosted.org/packages/ec/91/e41f64f03d2a13aee7e8c819d82ee3aa7cdc484d18c0ae859742597d5aa0/httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd", size = 75377, upload-time = "2023-05-19T00:50:54.91Z" }, ] [[package]] name = "idna" version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload_time = "2024-09-15T18:07:39.745Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload_time = "2024-09-15T18:07:37.964Z" }, + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] [[package]] name = "iniconfig" version = "2.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload_time = "2025-03-19T20:09:59.721Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload_time = "2025-03-19T20:10:01.071Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] [[package]] @@ -508,9 +506,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload_time = "2025-03-05T20:05:02.478Z" } +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload_time = "2025-03-05T20:05:00.369Z" }, + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] [[package]] @@ -526,11 +524,12 @@ dependencies = [ { name = "fastapi-jwt-auth" }, { name = "httpx" }, { name = "jinja2" }, + { name = "kontor-model" }, + { name = "msgspec", extra = ["toml", "yaml"] }, { name = "natsort" }, { name = "pathlib" }, { name = "platformdirs" }, { name = "psycopg2-binary" }, - { name = "pydantic", extra = ["email"] }, { name = "pytest" }, { name = "pytest-cov" }, { name = "python-dotenv" }, @@ -552,11 +551,12 @@ requires-dist = [ { name = "fastapi-jwt-auth", specifier = ">=0.5.0" }, { name = "httpx", specifier = "==0.24.1" }, { name = "jinja2", specifier = ">=3.1.6" }, + { name = "kontor-model", editable = "../kontor-model" }, + { name = "msgspec", extras = ["toml", "yaml"], specifier = ">=0.21.1" }, { name = "natsort", specifier = ">=8.4.0" }, { name = "pathlib", specifier = ">=1.0.1" }, { name = "platformdirs", specifier = ">=4.3.7" }, { name = "psycopg2-binary", specifier = ">=2.9.10" }, - { name = "pydantic", extras = ["email"], specifier = ">=2.11.3" }, { name = "pytest", specifier = "==7.4.0" }, { name = "pytest-cov", specifier = ">=6.1.1" }, { name = "python-dotenv", specifier = ">=1.1.0" }, @@ -568,6 +568,23 @@ requires-dist = [ { name = "sqlmodel", specifier = ">=0.0.24" }, ] +[[package]] +name = "kontor-model" +version = "0.3.0" +source = { editable = "../kontor-model" } +dependencies = [ + { name = "msgspec", extra = ["toml", "yaml"] }, + { name = "pydantic", extra = ["email"] }, + { name = "sqlalchemy" }, +] + +[package.metadata] +requires-dist = [ + { name = "msgspec", extras = ["toml", "yaml"], specifier = ">=0.21.1" }, + { name = "pydantic", extras = ["email"], specifier = ">=2.13.4" }, + { name = "sqlalchemy", specifier = ">=2.0.52" }, +] + [[package]] name = "markdown-it-py" version = "3.0.0" @@ -575,133 +592,173 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload_time = "2023-06-03T06:41:14.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload_time = "2023-06-03T06:41:11.019Z" }, + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, ] [[package]] name = "markupsafe" version = "3.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload_time = "2024-10-18T15:21:54.129Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload_time = "2024-10-18T15:21:24.577Z" }, - { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload_time = "2024-10-18T15:21:25.382Z" }, - { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload_time = "2024-10-18T15:21:26.199Z" }, - { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload_time = "2024-10-18T15:21:27.029Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload_time = "2024-10-18T15:21:27.846Z" }, - { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload_time = "2024-10-18T15:21:28.744Z" }, - { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload_time = "2024-10-18T15:21:29.545Z" }, - { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload_time = "2024-10-18T15:21:30.366Z" }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload_time = "2024-10-18T15:21:31.207Z" }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload_time = "2024-10-18T15:21:32.032Z" }, - { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload_time = "2024-10-18T15:21:33.625Z" }, - { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload_time = "2024-10-18T15:21:34.611Z" }, - { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload_time = "2024-10-18T15:21:35.398Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload_time = "2024-10-18T15:21:36.231Z" }, - { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload_time = "2024-10-18T15:21:37.073Z" }, - { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload_time = "2024-10-18T15:21:37.932Z" }, - { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload_time = "2024-10-18T15:21:39.799Z" }, - { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload_time = "2024-10-18T15:21:40.813Z" }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload_time = "2024-10-18T15:21:41.814Z" }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload_time = "2024-10-18T15:21:42.784Z" }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, ] [[package]] name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload_time = "2022-08-14T12:40:10.846Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload_time = "2022-08-14T12:40:09.779Z" }, + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "msgspec" +version = "0.21.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/60/f79b9b013a16fa3a58350c9295ddc6789f2e335f36ea61ed10a21b215364/msgspec-0.21.1.tar.gz", hash = "sha256:2313508e394b0d208f8f56892ca9b2799e2561329de9763b19619595a6c0f72c", size = 319193, upload-time = "2026-04-12T21:44:50.394Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/74/f11ede02839b19ff459f88e3145df5d711626ca84da4e23520cebf819367/msgspec-0.21.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:764173717a01743f007e9f74520ed281f24672c604514f7d76c1c3a10e8edb66", size = 196176, upload-time = "2026-04-12T21:44:17.613Z" }, + { url = "https://files.pythonhosted.org/packages/bb/40/4476c1bd341418a046c4955aff632ec769315d1e3cb94e6acf86d461f9ed/msgspec-0.21.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:344c7cd0eaed1fb81d7959f99100ef71ec9b536881a376f11b9a6c4803365697", size = 188524, upload-time = "2026-04-12T21:44:18.815Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d9/9e9d7d7e5061b47540d03d640fab9b3965ba7ae49c1b2154861c8f007518/msgspec-0.21.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48943e278b3854c2f89f955ddc6f9f430d3f0784b16e47d10604ee0463cd21f5", size = 218880, upload-time = "2026-04-12T21:44:20.028Z" }, + { url = "https://files.pythonhosted.org/packages/74/66/2bb344f34abb4b57e60c7c9c761994e0417b9718ec1460bf00c296f2a7ea/msgspec-0.21.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9aa659ebb0101b1cbc31461212b87e341d961f0ab0772aaf068a99e001ec4aa", size = 225050, upload-time = "2026-04-12T21:44:21.577Z" }, + { url = "https://files.pythonhosted.org/packages/1a/84/7c1e412f76092277bf760cef12b7979d03314d259ab5b5cafde5d0c1722d/msgspec-0.21.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7b27d1a8ead2b6f5b0c4f2d07b8be1ccfcc041c8a0e704781edebe3ae13c484", size = 222713, upload-time = "2026-04-12T21:44:22.83Z" }, + { url = "https://files.pythonhosted.org/packages/4e/27/0bba04b2b4ef05f3d068429410bc71d2cea925f1596a8f41152cccd5edb8/msgspec-0.21.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38fe93e86b61328fe544cb7fd871fad5a27c8734bfda90f65e5dbe288ae50f61", size = 227259, upload-time = "2026-04-12T21:44:24.11Z" }, + { url = "https://files.pythonhosted.org/packages/b0/2d/09574b0eea02fed2c2c1383dbaae2c7f79dc16dcd6487a886000afb5d7c4/msgspec-0.21.1-cp313-cp313-win_amd64.whl", hash = "sha256:8bc666331c35fcce05a7cd2d6221adbe0f6058f8e750711413d22793c080ac6a", size = 189857, upload-time = "2026-04-12T21:44:25.359Z" }, + { url = "https://files.pythonhosted.org/packages/46/34/105b1576ad182879914f0c821f17ee1d13abb165cb060448f96fe2aff078/msgspec-0.21.1-cp313-cp313-win_arm64.whl", hash = "sha256:42bb1241e0750c1a4346f2aa84db26c5ffd99a4eb3a954927d9f149ff2f42898", size = 175403, upload-time = "2026-04-12T21:44:26.608Z" }, + { url = "https://files.pythonhosted.org/packages/5a/ad/86954e987d1d6a5c579e2c2e7832b65e0fff194179fdac4f581536086024/msgspec-0.21.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fab48eb45fdbfbdb2c0edfec00ffc53b6b6085beefc6b50b61e01659f9f8757f", size = 196261, upload-time = "2026-04-12T21:44:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a1/c5e46c3e42b866199365e35d11dddfd1fbd8bba4fdb3c52f965b1607ce94/msgspec-0.21.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3cb779ea0c35bc807ff941d415875c1f69ca0be91a2e907ab99a171811d86a9a", size = 188729, upload-time = "2026-04-12T21:44:28.99Z" }, + { url = "https://files.pythonhosted.org/packages/85/7d/1e29a319d678d6cb962ae5bdf32a6858ebdf38f73bc654c0e9c742a0c2c8/msgspec-0.21.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68604db36b3b4dd9bf160e436e12798a4738848144cea1aca1cb984011eb160f", size = 219866, upload-time = "2026-04-12T21:44:31.104Z" }, + { url = "https://files.pythonhosted.org/packages/25/1f/cca084ca2572810fff12ea9dbdcbe39eac048f40daf4a9077b49fcbe8cee/msgspec-0.21.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3d6b9dc50948eaf65df54d2fd0ff66e6d8c32f116037209ee861810eb9b676cb", size = 224993, upload-time = "2026-04-12T21:44:32.649Z" }, + { url = "https://files.pythonhosted.org/packages/71/94/d2120fc9d419a89a3a7c13e5b7078798c4b392a96a02a6e2b3ce43a8766c/msgspec-0.21.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:52c5e21930942302394429c5a582ce7e6b62c7f983b3760834c2ce107e0dd6df", size = 223535, upload-time = "2026-04-12T21:44:33.839Z" }, + { url = "https://files.pythonhosted.org/packages/75/17/42418b66a3ad972a89bab73dd78b79cc6282bb488a25e73c853cee7443b9/msgspec-0.21.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:abbb39d65681fa24ed394e01af3d59d869068324f900c61d06062b7fb9980f2f", size = 227222, upload-time = "2026-04-12T21:44:35.093Z" }, + { url = "https://files.pythonhosted.org/packages/c4/33/265c894268cca88ff67b144ca2b4c522fc8b9a6f1966a3640c70516e78e1/msgspec-0.21.1-cp314-cp314-win_amd64.whl", hash = "sha256:5666b1b560b97b6ec2eb3fca8a502298ebac56e13bbca1f88523538ce83d01ea", size = 193810, upload-time = "2026-04-12T21:44:36.612Z" }, + { url = "https://files.pythonhosted.org/packages/3b/8f/a6d35f25bf1fc63c492fdd88fdce01ba0875ead48c2b91f90f33653b4131/msgspec-0.21.1-cp314-cp314-win_arm64.whl", hash = "sha256:d8b8578e4c83b14ceea4cef0d0b747e31d9330fe4b03b2b2ad4063866a178f93", size = 179125, upload-time = "2026-04-12T21:44:38.198Z" }, + { url = "https://files.pythonhosted.org/packages/c6/39/74839641e64b99d87da55af0fc472854d42b46e2183b9e2a67fe1bb2a512/msgspec-0.21.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:15f523d51c00ebad412213bfe9f06f0a50ec2b93e0c19e824a2d267cabb48ea2", size = 200171, upload-time = "2026-04-12T21:44:39.414Z" }, + { url = "https://files.pythonhosted.org/packages/70/9b/ce0cca6d2d87fcd4b6ff97600790494e64f26a2c55d61507cd2755c16193/msgspec-0.21.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4e47390360583ba3d5c6cb44cf0a9f61b0a06a899d3c2c00627cedebb2e2884b", size = 192879, upload-time = "2026-04-12T21:44:40.882Z" }, + { url = "https://files.pythonhosted.org/packages/a7/08/673a7bb05e5702dc787ddd3011195b509f9867927970da59052211929987/msgspec-0.21.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f60800e6299b798142dc40b0644da77ceac5ea0568be58228417eae14135c847", size = 226281, upload-time = "2026-04-12T21:44:42.181Z" }, + { url = "https://files.pythonhosted.org/packages/7d/45/86508cf57283e9070b3c447e3ab25b792a7a0855a3ea4e0c6d111ac34c97/msgspec-0.21.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5f8e9dfcd98419cf7568808470c4317a3fb30bef0e3715b568730a2b272a20d7", size = 229863, upload-time = "2026-04-12T21:44:43.442Z" }, + { url = "https://files.pythonhosted.org/packages/2c/62/e7c9367cd08d590559faacd711edbae36840342843e669440363f33c7d36/msgspec-0.21.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:92d89dfad13bd1ea640dc3e37e724ed380da1030b272bdf5ecafb983c3ad7c75", size = 230445, upload-time = "2026-04-12T21:44:44.806Z" }, + { url = "https://files.pythonhosted.org/packages/42/b4/c0f54632103846b658a10930025f4de41c8724b5e4805a5f3b395586cb7e/msgspec-0.21.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0d03867786e5d7ba25d666df4b11320c27170f4aeafcb8e3a8b0a50a4fb742ca", size = 231822, upload-time = "2026-04-12T21:44:46.343Z" }, + { url = "https://files.pythonhosted.org/packages/ea/1d/0d85cc79d0ccf5508e9c846cc66552a6a16bf92abd1dbd8362617f7b35cd/msgspec-0.21.1-cp314-cp314t-win_amd64.whl", hash = "sha256:740fbf1c9d59992ca3537d6fbe9ebbf9eaf726a65fbf31448e0ecbc710697a63", size = 206650, upload-time = "2026-04-12T21:44:47.601Z" }, + { url = "https://files.pythonhosted.org/packages/90/91/56c5d560f20e6c20e9e4f55bd0e458f7f162aa689ee350346c04c48eac0b/msgspec-0.21.1-cp314-cp314t-win_arm64.whl", hash = "sha256:0d2cc73df6058d811a126ac3a8ad63a4dfa210c82f9cf5a004802eaf4712de90", size = 183149, upload-time = "2026-04-12T21:44:48.833Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli-w" }, +] +yaml = [ + { name = "pyyaml" }, ] [[package]] name = "natsort" version = "8.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e2/a9/a0c57aee75f77794adaf35322f8b6404cbd0f89ad45c87197a937764b7d0/natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581", size = 76575, upload_time = "2023-06-20T04:17:19.925Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/a9/a0c57aee75f77794adaf35322f8b6404cbd0f89ad45c87197a937764b7d0/natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581", size = 76575, upload-time = "2023-06-20T04:17:19.925Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c", size = 38268, upload_time = "2023-06-20T04:17:17.522Z" }, + { url = "https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c", size = 38268, upload-time = "2023-06-20T04:17:17.522Z" }, ] [[package]] name = "packaging" version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload_time = "2025-04-19T11:48:59.673Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload_time = "2025-04-19T11:48:57.875Z" }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] name = "pathlib" version = "1.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ac/aa/9b065a76b9af472437a0059f77e8f962fe350438b927cb80184c32f075eb/pathlib-1.0.1.tar.gz", hash = "sha256:6940718dfc3eff4258203ad5021090933e5c04707d5ca8cc9e73c94a7894ea9f", size = 49298, upload_time = "2014-09-03T15:41:57.18Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ac/aa/9b065a76b9af472437a0059f77e8f962fe350438b927cb80184c32f075eb/pathlib-1.0.1.tar.gz", hash = "sha256:6940718dfc3eff4258203ad5021090933e5c04707d5ca8cc9e73c94a7894ea9f", size = 49298, upload-time = "2014-09-03T15:41:57.18Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/f9/690a8600b93c332de3ab4a344a4ac34f00c8f104917061f779db6a918ed6/pathlib-1.0.1-py3-none-any.whl", hash = "sha256:f35f95ab8b0f59e6d354090350b44a80a80635d22efdedfa84c7ad1cf0a74147", size = 14363, upload_time = "2022-05-04T13:37:20.585Z" }, + { url = "https://files.pythonhosted.org/packages/78/f9/690a8600b93c332de3ab4a344a4ac34f00c8f104917061f779db6a918ed6/pathlib-1.0.1-py3-none-any.whl", hash = "sha256:f35f95ab8b0f59e6d354090350b44a80a80635d22efdedfa84c7ad1cf0a74147", size = 14363, upload-time = "2022-05-04T13:37:20.585Z" }, ] [[package]] name = "platformdirs" version = "4.3.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b6/2d/7d512a3913d60623e7eb945c6d1b4f0bddf1d0b7ada5225274c87e5b53d1/platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351", size = 21291, upload_time = "2025-03-19T20:36:10.989Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/2d/7d512a3913d60623e7eb945c6d1b4f0bddf1d0b7ada5225274c87e5b53d1/platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351", size = 21291, upload-time = "2025-03-19T20:36:10.989Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/45/59578566b3275b8fd9157885918fcd0c4d74162928a5310926887b856a51/platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94", size = 18499, upload_time = "2025-03-19T20:36:09.038Z" }, + { url = "https://files.pythonhosted.org/packages/6d/45/59578566b3275b8fd9157885918fcd0c4d74162928a5310926887b856a51/platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94", size = 18499, upload-time = "2025-03-19T20:36:09.038Z" }, ] [[package]] name = "pluggy" version = "1.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload_time = "2024-04-20T21:34:42.531Z" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload_time = "2024-04-20T21:34:40.434Z" }, + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" }, ] [[package]] name = "psycopg2-binary" version = "2.9.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cb/0e/bdc8274dc0585090b4e3432267d7be4dfbfd8971c0fa59167c711105a6bf/psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2", size = 385764, upload_time = "2024-10-16T11:24:58.126Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/0e/bdc8274dc0585090b4e3432267d7be4dfbfd8971c0fa59167c711105a6bf/psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2", size = 385764, upload-time = "2024-10-16T11:24:58.126Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3e/30/d41d3ba765609c0763505d565c4d12d8f3c79793f0d0f044ff5a28bf395b/psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d", size = 3044699, upload_time = "2024-10-16T11:21:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/35/44/257ddadec7ef04536ba71af6bc6a75ec05c5343004a7ec93006bee66c0bc/psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb", size = 3275245, upload_time = "2024-10-16T11:21:51.989Z" }, - { url = "https://files.pythonhosted.org/packages/1b/11/48ea1cd11de67f9efd7262085588790a95d9dfcd9b8a687d46caf7305c1a/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7", size = 2851631, upload_time = "2024-10-16T11:21:57.584Z" }, - { url = "https://files.pythonhosted.org/packages/62/e0/62ce5ee650e6c86719d621a761fe4bc846ab9eff8c1f12b1ed5741bf1c9b/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d", size = 3082140, upload_time = "2024-10-16T11:22:02.005Z" }, - { url = "https://files.pythonhosted.org/packages/27/ce/63f946c098611f7be234c0dd7cb1ad68b0b5744d34f68062bb3c5aa510c8/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73", size = 3264762, upload_time = "2024-10-16T11:22:06.412Z" }, - { url = "https://files.pythonhosted.org/packages/43/25/c603cd81402e69edf7daa59b1602bd41eb9859e2824b8c0855d748366ac9/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673", size = 3020967, upload_time = "2024-10-16T11:22:11.583Z" }, - { url = "https://files.pythonhosted.org/packages/5f/d6/8708d8c6fca531057fa170cdde8df870e8b6a9b136e82b361c65e42b841e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f", size = 2872326, upload_time = "2024-10-16T11:22:16.406Z" }, - { url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", size = 2822712, upload_time = "2024-10-16T11:22:21.366Z" }, - { url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", size = 2920155, upload_time = "2024-10-16T11:22:25.684Z" }, - { url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", size = 2959356, upload_time = "2024-10-16T11:22:30.562Z" }, - { url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", size = 2569224, upload_time = "2025-01-04T20:09:19.234Z" }, + { url = "https://files.pythonhosted.org/packages/3e/30/d41d3ba765609c0763505d565c4d12d8f3c79793f0d0f044ff5a28bf395b/psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d", size = 3044699, upload-time = "2024-10-16T11:21:42.841Z" }, + { url = "https://files.pythonhosted.org/packages/35/44/257ddadec7ef04536ba71af6bc6a75ec05c5343004a7ec93006bee66c0bc/psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb", size = 3275245, upload-time = "2024-10-16T11:21:51.989Z" }, + { url = "https://files.pythonhosted.org/packages/1b/11/48ea1cd11de67f9efd7262085588790a95d9dfcd9b8a687d46caf7305c1a/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7", size = 2851631, upload-time = "2024-10-16T11:21:57.584Z" }, + { url = "https://files.pythonhosted.org/packages/62/e0/62ce5ee650e6c86719d621a761fe4bc846ab9eff8c1f12b1ed5741bf1c9b/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d", size = 3082140, upload-time = "2024-10-16T11:22:02.005Z" }, + { url = "https://files.pythonhosted.org/packages/27/ce/63f946c098611f7be234c0dd7cb1ad68b0b5744d34f68062bb3c5aa510c8/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73", size = 3264762, upload-time = "2024-10-16T11:22:06.412Z" }, + { url = "https://files.pythonhosted.org/packages/43/25/c603cd81402e69edf7daa59b1602bd41eb9859e2824b8c0855d748366ac9/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673", size = 3020967, upload-time = "2024-10-16T11:22:11.583Z" }, + { url = "https://files.pythonhosted.org/packages/5f/d6/8708d8c6fca531057fa170cdde8df870e8b6a9b136e82b361c65e42b841e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f", size = 2872326, upload-time = "2024-10-16T11:22:16.406Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", size = 2822712, upload-time = "2024-10-16T11:22:21.366Z" }, + { url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", size = 2920155, upload-time = "2024-10-16T11:22:25.684Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", size = 2959356, upload-time = "2024-10-16T11:22:30.562Z" }, + { url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", size = 2569224, upload-time = "2025-01-04T20:09:19.234Z" }, ] [[package]] name = "pyasn1" version = "0.4.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a4/db/fffec68299e6d7bad3d504147f9094830b704527a7fc098b721d38cc7fa7/pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", size = 146820, upload_time = "2019-11-16T17:27:38.772Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a4/db/fffec68299e6d7bad3d504147f9094830b704527a7fc098b721d38cc7fa7/pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", size = 146820, upload-time = "2019-11-16T17:27:38.772Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/1e/a94a8d635fa3ce4cfc7f506003548d0a2447ae76fd5ca53932970fe3053f/pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", size = 77145, upload_time = "2019-11-16T17:27:11.07Z" }, + { url = "https://files.pythonhosted.org/packages/62/1e/a94a8d635fa3ce4cfc7f506003548d0a2447ae76fd5ca53932970fe3053f/pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", size = 77145, upload-time = "2019-11-16T17:27:11.07Z" }, ] [[package]] name = "pycparser" version = "2.23" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload_time = "2025-09-09T13:23:47.91Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload_time = "2025-09-09T13:23:46.651Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, ] [[package]] name = "pydantic" -version = "2.11.3" +version = "2.13.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -709,9 +766,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/10/2e/ca897f093ee6c5f3b0bee123ee4465c50e75431c3d5b6a3b44a47134e891/pydantic-2.11.3.tar.gz", hash = "sha256:7471657138c16adad9322fe3070c0116dd6c3ad8d649300e3cbdfe91f4db4ec3", size = 785513, upload_time = "2025-04-08T13:27:06.399Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/1d/407b29780a289868ed696d1616f4aad49d6388e5a77f567dcd2629dcd7b8/pydantic-2.11.3-py3-none-any.whl", hash = "sha256:a082753436a07f9ba1289c6ffa01cd93db3548776088aa917cc43b63f68fa60f", size = 443591, upload_time = "2025-04-08T13:27:03.789Z" }, + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, ] [package.optional-dependencies] @@ -721,48 +778,76 @@ email = [ [[package]] name = "pydantic-core" -version = "2.33.1" +version = "2.46.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/17/19/ed6a078a5287aea7922de6841ef4c06157931622c89c2a47940837b5eecd/pydantic_core-2.33.1.tar.gz", hash = "sha256:bcc9c6fdb0ced789245b02b7d6603e17d1563064ddcfc36f046b61c0c05dd9df", size = 434395, upload_time = "2025-04-02T09:49:41.8Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/24/eed3466a4308d79155f1cdd5c7432c80ddcc4530ba8623b79d5ced021641/pydantic_core-2.33.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:70af6a21237b53d1fe7b9325b20e65cbf2f0a848cf77bed492b029139701e66a", size = 2033551, upload_time = "2025-04-02T09:47:51.648Z" }, - { url = "https://files.pythonhosted.org/packages/ab/14/df54b1a0bc9b6ded9b758b73139d2c11b4e8eb43e8ab9c5847c0a2913ada/pydantic_core-2.33.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:282b3fe1bbbe5ae35224a0dbd05aed9ccabccd241e8e6b60370484234b456266", size = 1852785, upload_time = "2025-04-02T09:47:53.149Z" }, - { url = "https://files.pythonhosted.org/packages/fa/96/e275f15ff3d34bb04b0125d9bc8848bf69f25d784d92a63676112451bfb9/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b315e596282bbb5822d0c7ee9d255595bd7506d1cb20c2911a4da0b970187d3", size = 1897758, upload_time = "2025-04-02T09:47:55.006Z" }, - { url = "https://files.pythonhosted.org/packages/b7/d8/96bc536e975b69e3a924b507d2a19aedbf50b24e08c80fb00e35f9baaed8/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dfae24cf9921875ca0ca6a8ecb4bb2f13c855794ed0d468d6abbec6e6dcd44a", size = 1986109, upload_time = "2025-04-02T09:47:56.532Z" }, - { url = "https://files.pythonhosted.org/packages/90/72/ab58e43ce7e900b88cb571ed057b2fcd0e95b708a2e0bed475b10130393e/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6dd8ecfde08d8bfadaea669e83c63939af76f4cf5538a72597016edfa3fad516", size = 2129159, upload_time = "2025-04-02T09:47:58.088Z" }, - { url = "https://files.pythonhosted.org/packages/dc/3f/52d85781406886c6870ac995ec0ba7ccc028b530b0798c9080531b409fdb/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f593494876eae852dc98c43c6f260f45abdbfeec9e4324e31a481d948214764", size = 2680222, upload_time = "2025-04-02T09:47:59.591Z" }, - { url = "https://files.pythonhosted.org/packages/f4/56/6e2ef42f363a0eec0fd92f74a91e0ac48cd2e49b695aac1509ad81eee86a/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:948b73114f47fd7016088e5186d13faf5e1b2fe83f5e320e371f035557fd264d", size = 2006980, upload_time = "2025-04-02T09:48:01.397Z" }, - { url = "https://files.pythonhosted.org/packages/4c/c0/604536c4379cc78359f9ee0aa319f4aedf6b652ec2854953f5a14fc38c5a/pydantic_core-2.33.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e11f3864eb516af21b01e25fac915a82e9ddad3bb0fb9e95a246067398b435a4", size = 2120840, upload_time = "2025-04-02T09:48:03.056Z" }, - { url = "https://files.pythonhosted.org/packages/1f/46/9eb764814f508f0edfb291a0f75d10854d78113fa13900ce13729aaec3ae/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:549150be302428b56fdad0c23c2741dcdb5572413776826c965619a25d9c6bde", size = 2072518, upload_time = "2025-04-02T09:48:04.662Z" }, - { url = "https://files.pythonhosted.org/packages/42/e3/fb6b2a732b82d1666fa6bf53e3627867ea3131c5f39f98ce92141e3e3dc1/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:495bc156026efafd9ef2d82372bd38afce78ddd82bf28ef5276c469e57c0c83e", size = 2248025, upload_time = "2025-04-02T09:48:06.226Z" }, - { url = "https://files.pythonhosted.org/packages/5c/9d/fbe8fe9d1aa4dac88723f10a921bc7418bd3378a567cb5e21193a3c48b43/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ec79de2a8680b1a67a07490bddf9636d5c2fab609ba8c57597e855fa5fa4dacd", size = 2254991, upload_time = "2025-04-02T09:48:08.114Z" }, - { url = "https://files.pythonhosted.org/packages/aa/99/07e2237b8a66438d9b26482332cda99a9acccb58d284af7bc7c946a42fd3/pydantic_core-2.33.1-cp313-cp313-win32.whl", hash = "sha256:ee12a7be1742f81b8a65b36c6921022301d466b82d80315d215c4c691724986f", size = 1915262, upload_time = "2025-04-02T09:48:09.708Z" }, - { url = "https://files.pythonhosted.org/packages/8a/f4/e457a7849beeed1e5defbcf5051c6f7b3c91a0624dd31543a64fc9adcf52/pydantic_core-2.33.1-cp313-cp313-win_amd64.whl", hash = "sha256:ede9b407e39949d2afc46385ce6bd6e11588660c26f80576c11c958e6647bc40", size = 1956626, upload_time = "2025-04-02T09:48:11.288Z" }, - { url = "https://files.pythonhosted.org/packages/20/d0/e8d567a7cff7b04e017ae164d98011f1e1894269fe8e90ea187a3cbfb562/pydantic_core-2.33.1-cp313-cp313-win_arm64.whl", hash = "sha256:aa687a23d4b7871a00e03ca96a09cad0f28f443690d300500603bd0adba4b523", size = 1909590, upload_time = "2025-04-02T09:48:12.861Z" }, - { url = "https://files.pythonhosted.org/packages/ef/fd/24ea4302d7a527d672c5be06e17df16aabfb4e9fdc6e0b345c21580f3d2a/pydantic_core-2.33.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:401d7b76e1000d0dd5538e6381d28febdcacb097c8d340dde7d7fc6e13e9f95d", size = 1812963, upload_time = "2025-04-02T09:48:14.553Z" }, - { url = "https://files.pythonhosted.org/packages/5f/95/4fbc2ecdeb5c1c53f1175a32d870250194eb2fdf6291b795ab08c8646d5d/pydantic_core-2.33.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aeb055a42d734c0255c9e489ac67e75397d59c6fbe60d155851e9782f276a9c", size = 1986896, upload_time = "2025-04-02T09:48:16.222Z" }, - { url = "https://files.pythonhosted.org/packages/71/ae/fe31e7f4a62431222d8f65a3bd02e3fa7e6026d154a00818e6d30520ea77/pydantic_core-2.33.1-cp313-cp313t-win_amd64.whl", hash = "sha256:338ea9b73e6e109f15ab439e62cb3b78aa752c7fd9536794112e14bee02c8d18", size = 1931810, upload_time = "2025-04-02T09:48:17.97Z" }, + { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" }, + { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" }, + { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" }, + { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" }, + { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" }, + { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" }, + { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" }, ] [[package]] name = "pygments" version = "2.19.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload_time = "2025-01-06T17:26:30.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload_time = "2025-01-06T17:26:25.553Z" }, + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, ] [[package]] name = "pyjwt" version = "1.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2f/38/ff37a24c0243c5f45f5798bd120c0f873eeed073994133c084e1cf13b95c/PyJWT-1.7.1.tar.gz", hash = "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96", size = 41979, upload_time = "2018-12-07T13:40:09.26Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/38/ff37a24c0243c5f45f5798bd120c0f873eeed073994133c084e1cf13b95c/PyJWT-1.7.1.tar.gz", hash = "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96", size = 41979, upload-time = "2018-12-07T13:40:09.26Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/87/8b/6a9f14b5f781697e51259d81657e6048fd31a113229cf346880bb7545565/PyJWT-1.7.1-py2.py3-none-any.whl", hash = "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e", size = 18928, upload_time = "2018-12-07T13:40:06.872Z" }, + { url = "https://files.pythonhosted.org/packages/87/8b/6a9f14b5f781697e51259d81657e6048fd31a113229cf346880bb7545565/PyJWT-1.7.1-py2.py3-none-any.whl", hash = "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e", size = 18928, upload-time = "2018-12-07T13:40:06.872Z" }, ] [[package]] @@ -775,9 +860,9 @@ dependencies = [ { name = "packaging" }, { name = "pluggy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a7/f3/dadfbdbf6b6c8b5bd02adb1e08bc9fbb45ba51c68b0893fa536378cdf485/pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a", size = 1349733, upload_time = "2023-06-23T11:17:28.791Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/f3/dadfbdbf6b6c8b5bd02adb1e08bc9fbb45ba51c68b0893fa536378cdf485/pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a", size = 1349733, upload-time = "2023-06-23T11:17:28.791Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/33/b2/741130cbcf2bbfa852ed95a60dc311c9e232c7ed25bac3d9b8880a8df4ae/pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32", size = 323580, upload_time = "2023-06-23T11:17:25.738Z" }, + { url = "https://files.pythonhosted.org/packages/33/b2/741130cbcf2bbfa852ed95a60dc311c9e232c7ed25bac3d9b8880a8df4ae/pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32", size = 323580, upload-time = "2023-06-23T11:17:25.738Z" }, ] [[package]] @@ -788,18 +873,18 @@ dependencies = [ { name = "coverage" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/25/69/5f1e57f6c5a39f81411b550027bf72842c4567ff5fd572bed1edc9e4b5d9/pytest_cov-6.1.1.tar.gz", hash = "sha256:46935f7aaefba760e716c2ebfbe1c216240b9592966e7da99ea8292d4d3e2a0a", size = 66857, upload_time = "2025-04-05T14:07:51.592Z" } +sdist = { url = "https://files.pythonhosted.org/packages/25/69/5f1e57f6c5a39f81411b550027bf72842c4567ff5fd572bed1edc9e4b5d9/pytest_cov-6.1.1.tar.gz", hash = "sha256:46935f7aaefba760e716c2ebfbe1c216240b9592966e7da99ea8292d4d3e2a0a", size = 66857, upload-time = "2025-04-05T14:07:51.592Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/28/d0/def53b4a790cfb21483016430ed828f64830dd981ebe1089971cd10cab25/pytest_cov-6.1.1-py3-none-any.whl", hash = "sha256:bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde", size = 23841, upload_time = "2025-04-05T14:07:49.641Z" }, + { url = "https://files.pythonhosted.org/packages/28/d0/def53b4a790cfb21483016430ed828f64830dd981ebe1089971cd10cab25/pytest_cov-6.1.1-py3-none-any.whl", hash = "sha256:bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde", size = 23841, upload-time = "2025-04-05T14:07:49.641Z" }, ] [[package]] name = "python-dotenv" version = "1.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920, upload_time = "2025-03-25T10:14:56.835Z" } +sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920, upload-time = "2025-03-25T10:14:56.835Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256, upload_time = "2025-03-25T10:14:55.034Z" }, + { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256, upload-time = "2025-03-25T10:14:55.034Z" }, ] [[package]] @@ -811,9 +896,9 @@ dependencies = [ { name = "pyasn1" }, { name = "rsa" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8e/a0/c49687cf40cb6128ea4e0559855aff92cd5ebd1a60a31c08526818c0e51e/python-jose-3.4.0.tar.gz", hash = "sha256:9a9a40f418ced8ecaf7e3b28d69887ceaa76adad3bcaa6dae0d9e596fec1d680", size = 92145, upload_time = "2025-02-18T17:26:41.985Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/a0/c49687cf40cb6128ea4e0559855aff92cd5ebd1a60a31c08526818c0e51e/python-jose-3.4.0.tar.gz", hash = "sha256:9a9a40f418ced8ecaf7e3b28d69887ceaa76adad3bcaa6dae0d9e596fec1d680", size = 92145, upload-time = "2025-02-18T17:26:41.985Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/63/b0/2586ea6b6fd57a994ece0b56418cbe93fff0efb85e2c9eb6b0caf24a4e37/python_jose-3.4.0-py2.py3-none-any.whl", hash = "sha256:9c9f616819652d109bd889ecd1e15e9a162b9b94d682534c9c2146092945b78f", size = 34616, upload_time = "2025-02-18T17:26:40.826Z" }, + { url = "https://files.pythonhosted.org/packages/63/b0/2586ea6b6fd57a994ece0b56418cbe93fff0efb85e2c9eb6b0caf24a4e37/python_jose-3.4.0-py2.py3-none-any.whl", hash = "sha256:9c9f616819652d109bd889ecd1e15e9a162b9b94d682534c9c2146092945b78f", size = 34616, upload-time = "2025-02-18T17:26:40.826Z" }, ] [package.optional-dependencies] @@ -825,26 +910,26 @@ cryptography = [ name = "python-multipart" version = "0.0.20" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload_time = "2024-12-16T19:45:46.972Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload-time = "2024-12-16T19:45:46.972Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload_time = "2024-12-16T19:45:44.423Z" }, + { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload-time = "2024-12-16T19:45:44.423Z" }, ] [[package]] name = "pyyaml" version = "6.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload_time = "2024-08-06T20:33:50.674Z" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload_time = "2024-08-06T20:32:43.4Z" }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload_time = "2024-08-06T20:32:44.801Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload_time = "2024-08-06T20:32:46.432Z" }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload_time = "2024-08-06T20:32:51.188Z" }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload_time = "2024-08-06T20:32:53.019Z" }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload_time = "2024-08-06T20:32:54.708Z" }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload_time = "2024-08-06T20:32:56.985Z" }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload_time = "2024-08-06T20:33:03.001Z" }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload_time = "2024-08-06T20:33:04.33Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, ] [[package]] @@ -857,9 +942,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload_time = "2024-05-29T15:37:49.536Z" } +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload_time = "2024-05-29T15:37:47.027Z" }, + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, ] [[package]] @@ -870,9 +955,9 @@ dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078, upload_time = "2025-03-30T14:15:14.23Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078, upload-time = "2025-03-30T14:15:14.23Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229, upload_time = "2025-03-30T14:15:12.283Z" }, + { url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229, upload-time = "2025-03-30T14:15:12.283Z" }, ] [[package]] @@ -884,9 +969,9 @@ dependencies = [ { name = "rich" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2e/ea/13945d58d556a28dfb0f774ad5c8af759527390e59505a40d164bf8ce1ce/rich_toolkit-0.14.1.tar.gz", hash = "sha256:9248e2d087bfc01f3e4c5c8987e05f7fa744d00dd22fa2be3aa6e50255790b3f", size = 104416, upload_time = "2025-03-30T12:19:08.623Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2e/ea/13945d58d556a28dfb0f774ad5c8af759527390e59505a40d164bf8ce1ce/rich_toolkit-0.14.1.tar.gz", hash = "sha256:9248e2d087bfc01f3e4c5c8987e05f7fa744d00dd22fa2be3aa6e50255790b3f", size = 104416, upload-time = "2025-03-30T12:19:08.623Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/66/e8/61c5b12d1567fdba41a6775db12a090d88b8305424ee7c47259c70d33cb4/rich_toolkit-0.14.1-py3-none-any.whl", hash = "sha256:dc92c0117d752446d04fdc828dbca5873bcded213a091a5d3742a2beec2e6559", size = 24177, upload_time = "2025-03-30T12:19:07.307Z" }, + { url = "https://files.pythonhosted.org/packages/66/e8/61c5b12d1567fdba41a6775db12a090d88b8305424ee7c47259c70d33cb4/rich_toolkit-0.14.1-py3-none-any.whl", hash = "sha256:dc92c0117d752446d04fdc828dbca5873bcded213a091a5d3742a2beec2e6559", size = 24177, upload-time = "2025-03-30T12:19:07.307Z" }, ] [[package]] @@ -896,66 +981,73 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyasn1" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload_time = "2025-04-16T09:51:18.218Z" } +sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload-time = "2025-04-16T09:51:18.218Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload_time = "2025-04-16T09:51:17.142Z" }, + { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload-time = "2025-04-16T09:51:17.142Z" }, ] [[package]] name = "shellingham" version = "1.5.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload_time = "2023-10-24T04:13:40.426Z" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload_time = "2023-10-24T04:13:38.866Z" }, + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, ] [[package]] name = "six" version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload_time = "2024-12-04T17:35:28.174Z" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload_time = "2024-12-04T17:35:26.475Z" }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "sniffio" version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload_time = "2024-02-25T23:20:04.057Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload_time = "2024-02-25T23:20:01.196Z" }, + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] [[package]] name = "soupsieve" version = "2.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418, upload_time = "2025-04-20T18:50:08.518Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418, upload-time = "2025-04-20T18:50:08.518Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload_time = "2025-04-20T18:50:07.196Z" }, + { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload-time = "2025-04-20T18:50:07.196Z" }, ] [[package]] name = "sqlalchemy" -version = "2.0.40" +version = "2.0.52" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" }, + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/68/c3/3f2bfa5e4dcd9938405fe2fab5b6ab94a9248a4f9536ea2fd497da20525f/sqlalchemy-2.0.40.tar.gz", hash = "sha256:d827099289c64589418ebbcaead0145cd19f4e3e8a93919a0100247af245fa00", size = 9664299, upload_time = "2025-03-27T17:52:31.876Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/21/77b4c147963073040dc3c3a5cb7a8c3001a1893c0209432cb77f9df836aa/sqlalchemy-2.0.52.tar.gz", hash = "sha256:5e2d46356ac2ccb7d268ab6c2319ac6a2b42f1b8d5fd8bd3d46855cd82abee97", size = 9945637, upload-time = "2026-08-11T19:07:09.829Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/18/4e3a86cc0232377bc48c373a9ba6a1b3fb79ba32dbb4eda0b357f5a2c59d/sqlalchemy-2.0.40-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:915866fd50dd868fdcc18d61d8258db1bf9ed7fbd6dfec960ba43365952f3b01", size = 2107887, upload_time = "2025-03-27T18:40:05.461Z" }, - { url = "https://files.pythonhosted.org/packages/cb/60/9fa692b1d2ffc4cbd5f47753731fd332afed30137115d862d6e9a1e962c7/sqlalchemy-2.0.40-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a4c5a2905a9ccdc67a8963e24abd2f7afcd4348829412483695c59e0af9a705", size = 2098367, upload_time = "2025-03-27T18:40:07.182Z" }, - { url = "https://files.pythonhosted.org/packages/4c/9f/84b78357ca641714a439eb3fbbddb17297dacfa05d951dbf24f28d7b5c08/sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55028d7a3ebdf7ace492fab9895cbc5270153f75442a0472d8516e03159ab364", size = 3184806, upload_time = "2025-03-27T18:51:29.356Z" }, - { url = "https://files.pythonhosted.org/packages/4b/7d/e06164161b6bfce04c01bfa01518a20cccbd4100d5c951e5a7422189191a/sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cfedff6878b0e0d1d0a50666a817ecd85051d12d56b43d9d425455e608b5ba0", size = 3198131, upload_time = "2025-03-27T18:50:31.616Z" }, - { url = "https://files.pythonhosted.org/packages/6d/51/354af20da42d7ec7b5c9de99edafbb7663a1d75686d1999ceb2c15811302/sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb19e30fdae77d357ce92192a3504579abe48a66877f476880238a962e5b96db", size = 3131364, upload_time = "2025-03-27T18:51:31.336Z" }, - { url = "https://files.pythonhosted.org/packages/7a/2f/48a41ff4e6e10549d83fcc551ab85c268bde7c03cf77afb36303c6594d11/sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:16d325ea898f74b26ffcd1cf8c593b0beed8714f0317df2bed0d8d1de05a8f26", size = 3159482, upload_time = "2025-03-27T18:50:33.201Z" }, - { url = "https://files.pythonhosted.org/packages/33/ac/e5e0a807163652a35be878c0ad5cfd8b1d29605edcadfb5df3c512cdf9f3/sqlalchemy-2.0.40-cp313-cp313-win32.whl", hash = "sha256:a669cbe5be3c63f75bcbee0b266779706f1a54bcb1000f302685b87d1b8c1500", size = 2080704, upload_time = "2025-03-27T18:46:00.193Z" }, - { url = "https://files.pythonhosted.org/packages/1c/cb/f38c61f7f2fd4d10494c1c135ff6a6ddb63508d0b47bccccd93670637309/sqlalchemy-2.0.40-cp313-cp313-win_amd64.whl", hash = "sha256:641ee2e0834812d657862f3a7de95e0048bdcb6c55496f39c6fa3d435f6ac6ad", size = 2104564, upload_time = "2025-03-27T18:46:01.442Z" }, - { url = "https://files.pythonhosted.org/packages/d1/7c/5fc8e802e7506fe8b55a03a2e1dab156eae205c91bee46305755e086d2e2/sqlalchemy-2.0.40-py3-none-any.whl", hash = "sha256:32587e2e1e359276957e6fe5dad089758bc042a971a8a09ae8ecf7a8fe23d07a", size = 1903894, upload_time = "2025-03-27T18:40:43.796Z" }, + { url = "https://files.pythonhosted.org/packages/7f/18/e30c6fe1eca1bf34a39fbdd6066121cc9974c850faf6f349eac563697a26/sqlalchemy-2.0.52-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2eb3c6a64b1bfe6704777cfd504e7b8ad093a5f3e03ce67663a5e6742f294e43", size = 2167724, upload-time = "2026-08-11T20:58:12.679Z" }, + { url = "https://files.pythonhosted.org/packages/d0/56/2e17d161a4f7ecc1c2ffb93e607b4e1898bb551b451b283235acb8f6ce47/sqlalchemy-2.0.52-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:923bb183c1dc64fdf7b717965e3d59938ec4f8b8710b419a21ce403e5da9a9e1", size = 3321189, upload-time = "2026-08-11T21:02:41.932Z" }, + { url = "https://files.pythonhosted.org/packages/cf/b8/8490916e893f3f8d74dc9cc54c078619364999dee37047a188e73abbc852/sqlalchemy-2.0.52-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:651d6d8782e80679e6151707c7b490834d46ada526328895abf567f25e63d29c", size = 3338185, upload-time = "2026-08-11T21:17:02.597Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f7/752cc8ee453da222829b3f5c4613614bf750d97429363b70414fa10478e4/sqlalchemy-2.0.52-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b08cddb8989775e3c88799d86704bdfc3ee6e9846118201aa5997f16f27e3a15", size = 3271698, upload-time = "2026-08-11T21:02:43.963Z" }, + { url = "https://files.pythonhosted.org/packages/51/e6/074ade0c07b9e4c8e8bca46820320ed94df9702afdb6f2af06623068d2e6/sqlalchemy-2.0.52-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ab66fa9618269390d4dfa222f2f2f88f7bc4bf5da13905131b818217db7e8057", size = 3308936, upload-time = "2026-08-11T21:17:04.172Z" }, + { url = "https://files.pythonhosted.org/packages/66/07/557c0d04716705599227945ac14e0a17ad0338e899f37d8c2ddff4dcc663/sqlalchemy-2.0.52-cp313-cp313-win32.whl", hash = "sha256:c63bda077685c85ca513286547a531ba57e7a68cf0a7ed3bafcc2bbd18896f4d", size = 2127308, upload-time = "2026-08-11T21:14:53.879Z" }, + { url = "https://files.pythonhosted.org/packages/96/4e/226eda27654318ce525d043025221f689abef883da2c7126f9065121618c/sqlalchemy-2.0.52-cp313-cp313-win_amd64.whl", hash = "sha256:9876b09b9f1ce7398b0ffece585c0a911244c53191187341f6bcae640e133751", size = 2153876, upload-time = "2026-08-11T21:14:55.527Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f5/71cb30af58c9b80a4e1fac0b73bb48f86d497a774a6a2eb6d2f1e657bb73/sqlalchemy-2.0.52-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:410d52be41d17f1a236d19520fbe776257dc16516ed06bd16d433311842aefd9", size = 2169537, upload-time = "2026-08-11T20:58:13.855Z" }, + { url = "https://files.pythonhosted.org/packages/4c/93/d07ebd645d1b07b6b5ed63450a70f063a346a7e0f2c8810daf2e532400cb/sqlalchemy-2.0.52-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfe9ce533dbe4d0a2ae1486546619bd30b76bcd670539a44d910361376175f5e", size = 3319606, upload-time = "2026-08-11T21:02:45.829Z" }, + { url = "https://files.pythonhosted.org/packages/ae/5c/290c84c7c2566ecd3b65baaae0fddec9bc33b033b398a06123bb86fbfc6e/sqlalchemy-2.0.52-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:812bae5138bfc0aa46fb0686da0fc7f581f68e2bbb05bc24c3713bebaedd1437", size = 3323642, upload-time = "2026-08-11T21:17:05.675Z" }, + { url = "https://files.pythonhosted.org/packages/13/f5/2cc160590ca49173359557880b92a0572293ccb899e8f6cedf150c5a3ddf/sqlalchemy-2.0.52-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:50bff43b632a56fbf5ed9afdd76307e1512b62051bcd5afb341ae67205bbb6c8", size = 3268125, upload-time = "2026-08-11T21:02:47.649Z" }, + { url = "https://files.pythonhosted.org/packages/35/f3/ea8933fc9f7d1353e9c2ff9965eae687c4cef181120574591ed2fa0633e1/sqlalchemy-2.0.52-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:49565daf5af554f538e23aef1fc81a95a4e49658f152285e45c02f5fc44f04cd", size = 3289516, upload-time = "2026-08-11T21:17:07.267Z" }, + { url = "https://files.pythonhosted.org/packages/45/67/05cf86541c1e1716fca1e4a996954a439cd74501707cda607fb7cb02ef50/sqlalchemy-2.0.52-cp314-cp314-win32.whl", hash = "sha256:ab9da41e61b9979b910499d633b241df20c51ee5037e5405b11c2faac3cbe1a2", size = 2130249, upload-time = "2026-08-11T21:14:57.273Z" }, + { url = "https://files.pythonhosted.org/packages/96/d7/8ac6ffa1e36169e762ef65bd835046abb2251b1bc17f8f6708e14ed8d31f/sqlalchemy-2.0.52-cp314-cp314-win_amd64.whl", hash = "sha256:a593db51b3bae75db17a5738ad5f992244b3a03863f83c28117ee482c6a3f76d", size = 2156718, upload-time = "2026-08-11T21:14:58.667Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4b/e01a737eef378e734cc6394a82248a6ce13b167dfa36c731075ce9fc9c64/sqlalchemy-2.0.52-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1e61d08bdf4ee2f41024569e3400de7d6734ba498144766b11260936ccfa582", size = 2190344, upload-time = "2026-08-11T19:53:21.393Z" }, + { url = "https://files.pythonhosted.org/packages/b3/3f/3582293d1e185e71d19d7c731c3e2ee20ba21981c4a1115c0806c1f62120/sqlalchemy-2.0.52-py3-none-any.whl", hash = "sha256:3b81b8363a919ce53453591cdb93702e6bd54ade6c4fa2f468fc053baee5ed89", size = 1950700, upload-time = "2026-08-11T20:47:21.603Z" }, ] [[package]] @@ -966,9 +1058,9 @@ dependencies = [ { name = "pydantic" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/86/4b/c2ad0496f5bdc6073d9b4cef52be9c04f2b37a5773441cc6600b1857648b/sqlmodel-0.0.24.tar.gz", hash = "sha256:cc5c7613c1a5533c9c7867e1aab2fd489a76c9e8a061984da11b4e613c182423", size = 116780, upload_time = "2025-03-07T05:43:32.887Z" } +sdist = { url = "https://files.pythonhosted.org/packages/86/4b/c2ad0496f5bdc6073d9b4cef52be9c04f2b37a5773441cc6600b1857648b/sqlmodel-0.0.24.tar.gz", hash = "sha256:cc5c7613c1a5533c9c7867e1aab2fd489a76c9e8a061984da11b4e613c182423", size = 116780, upload-time = "2025-03-07T05:43:32.887Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/16/91/484cd2d05569892b7fef7f5ceab3bc89fb0f8a8c0cde1030d383dbc5449c/sqlmodel-0.0.24-py3-none-any.whl", hash = "sha256:6778852f09370908985b667d6a3ab92910d0d5ec88adcaf23dbc242715ff7193", size = 28622, upload_time = "2025-03-07T05:43:30.37Z" }, + { url = "https://files.pythonhosted.org/packages/16/91/484cd2d05569892b7fef7f5ceab3bc89fb0f8a8c0cde1030d383dbc5449c/sqlmodel-0.0.24-py3-none-any.whl", hash = "sha256:6778852f09370908985b667d6a3ab92910d0d5ec88adcaf23dbc242715ff7193", size = 28622, upload-time = "2025-03-07T05:43:30.37Z" }, ] [[package]] @@ -978,9 +1070,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846, upload_time = "2025-04-13T13:56:17.942Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846, upload-time = "2025-04-13T13:56:17.942Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037, upload_time = "2025-04-13T13:56:16.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037, upload-time = "2025-04-13T13:56:16.21Z" }, +] + +[[package]] +name = "tomli-w" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184, upload-time = "2025-01-15T12:07:24.262Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675, upload-time = "2025-01-15T12:07:22.074Z" }, ] [[package]] @@ -993,39 +1094,39 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8b/6f/3991f0f1c7fcb2df31aef28e0594d8d54b05393a0e4e34c65e475c2a5d41/typer-0.15.2.tar.gz", hash = "sha256:ab2fab47533a813c49fe1f16b1a370fd5819099c00b119e0633df65f22144ba5", size = 100711, upload_time = "2025-02-27T19:17:34.807Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/6f/3991f0f1c7fcb2df31aef28e0594d8d54b05393a0e4e34c65e475c2a5d41/typer-0.15.2.tar.gz", hash = "sha256:ab2fab47533a813c49fe1f16b1a370fd5819099c00b119e0633df65f22144ba5", size = 100711, upload-time = "2025-02-27T19:17:34.807Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/fc/5b29fea8cee020515ca82cc68e3b8e1e34bb19a3535ad854cac9257b414c/typer-0.15.2-py3-none-any.whl", hash = "sha256:46a499c6107d645a9c13f7ee46c5d5096cae6f5fc57dd11eccbbb9ae3e44ddfc", size = 45061, upload_time = "2025-02-27T19:17:32.111Z" }, + { url = "https://files.pythonhosted.org/packages/7f/fc/5b29fea8cee020515ca82cc68e3b8e1e34bb19a3535ad854cac9257b414c/typer-0.15.2-py3-none-any.whl", hash = "sha256:46a499c6107d645a9c13f7ee46c5d5096cae6f5fc57dd11eccbbb9ae3e44ddfc", size = 45061, upload-time = "2025-02-27T19:17:32.111Z" }, ] [[package]] name = "typing-extensions" -version = "4.13.2" +version = "4.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload_time = "2025-04-10T14:19:05.416Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload_time = "2025-04-10T14:19:03.967Z" }, + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, ] [[package]] name = "typing-inspection" -version = "0.4.0" +version = "0.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload_time = "2025-02-25T17:27:59.638Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c09092e6b34058f36a460eea2d4c3e8b910c695975a0/typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47", size = 76928, upload-time = "2026-08-12T12:37:25.997Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload_time = "2025-02-25T17:27:57.754Z" }, + { url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload-time = "2026-08-12T12:37:24.648Z" }, ] [[package]] name = "urllib3" version = "2.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload_time = "2025-04-10T15:23:39.232Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload_time = "2025-04-10T15:23:37.377Z" }, + { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, ] [[package]] @@ -1036,9 +1137,9 @@ dependencies = [ { name = "click" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a6/ae/9bbb19b9e1c450cf9ecaef06463e40234d98d95bf572fab11b4f19ae5ded/uvicorn-0.34.2.tar.gz", hash = "sha256:0e929828f6186353a80b58ea719861d2629d766293b6d19baf086ba31d4f3328", size = 76815, upload_time = "2025-04-19T06:02:50.101Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/ae/9bbb19b9e1c450cf9ecaef06463e40234d98d95bf572fab11b4f19ae5ded/uvicorn-0.34.2.tar.gz", hash = "sha256:0e929828f6186353a80b58ea719861d2629d766293b6d19baf086ba31d4f3328", size = 76815, upload-time = "2025-04-19T06:02:50.101Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/4b/4cef6ce21a2aaca9d852a6e84ef4f135d99fcd74fa75105e2fc0c8308acd/uvicorn-0.34.2-py3-none-any.whl", hash = "sha256:deb49af569084536d269fe0a6d67e3754f104cf03aba7c11c40f01aadf33c403", size = 62483, upload_time = "2025-04-19T06:02:48.42Z" }, + { url = "https://files.pythonhosted.org/packages/b1/4b/4cef6ce21a2aaca9d852a6e84ef4f135d99fcd74fa75105e2fc0c8308acd/uvicorn-0.34.2-py3-none-any.whl", hash = "sha256:deb49af569084536d269fe0a6d67e3754f104cf03aba7c11c40f01aadf33c403", size = 62483, upload-time = "2025-04-19T06:02:48.42Z" }, ] [package.optional-dependencies] @@ -1056,14 +1157,14 @@ standard = [ name = "uvloop" version = "0.21.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/c0/854216d09d33c543f12a44b393c402e89a920b1a0a7dc634c42de91b9cf6/uvloop-0.21.0.tar.gz", hash = "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", size = 2492741, upload_time = "2024-10-14T23:38:35.489Z" } +sdist = { url = "https://files.pythonhosted.org/packages/af/c0/854216d09d33c543f12a44b393c402e89a920b1a0a7dc634c42de91b9cf6/uvloop-0.21.0.tar.gz", hash = "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", size = 2492741, upload-time = "2024-10-14T23:38:35.489Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/8d/2cbef610ca21539f0f36e2b34da49302029e7c9f09acef0b1c3b5839412b/uvloop-0.21.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281", size = 1468123, upload_time = "2024-10-14T23:38:00.688Z" }, - { url = "https://files.pythonhosted.org/packages/93/0d/b0038d5a469f94ed8f2b2fce2434a18396d8fbfb5da85a0a9781ebbdec14/uvloop-0.21.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af", size = 819325, upload_time = "2024-10-14T23:38:02.309Z" }, - { url = "https://files.pythonhosted.org/packages/50/94/0a687f39e78c4c1e02e3272c6b2ccdb4e0085fda3b8352fecd0410ccf915/uvloop-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6", size = 4582806, upload_time = "2024-10-14T23:38:04.711Z" }, - { url = "https://files.pythonhosted.org/packages/d2/19/f5b78616566ea68edd42aacaf645adbf71fbd83fc52281fba555dc27e3f1/uvloop-0.21.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816", size = 4701068, upload_time = "2024-10-14T23:38:06.385Z" }, - { url = "https://files.pythonhosted.org/packages/47/57/66f061ee118f413cd22a656de622925097170b9380b30091b78ea0c6ea75/uvloop-0.21.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc", size = 4454428, upload_time = "2024-10-14T23:38:08.416Z" }, - { url = "https://files.pythonhosted.org/packages/63/9a/0962b05b308494e3202d3f794a6e85abe471fe3cafdbcf95c2e8c713aabd/uvloop-0.21.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553", size = 4660018, upload_time = "2024-10-14T23:38:10.888Z" }, + { url = "https://files.pythonhosted.org/packages/3f/8d/2cbef610ca21539f0f36e2b34da49302029e7c9f09acef0b1c3b5839412b/uvloop-0.21.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281", size = 1468123, upload-time = "2024-10-14T23:38:00.688Z" }, + { url = "https://files.pythonhosted.org/packages/93/0d/b0038d5a469f94ed8f2b2fce2434a18396d8fbfb5da85a0a9781ebbdec14/uvloop-0.21.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af", size = 819325, upload-time = "2024-10-14T23:38:02.309Z" }, + { url = "https://files.pythonhosted.org/packages/50/94/0a687f39e78c4c1e02e3272c6b2ccdb4e0085fda3b8352fecd0410ccf915/uvloop-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6", size = 4582806, upload-time = "2024-10-14T23:38:04.711Z" }, + { url = "https://files.pythonhosted.org/packages/d2/19/f5b78616566ea68edd42aacaf645adbf71fbd83fc52281fba555dc27e3f1/uvloop-0.21.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816", size = 4701068, upload-time = "2024-10-14T23:38:06.385Z" }, + { url = "https://files.pythonhosted.org/packages/47/57/66f061ee118f413cd22a656de622925097170b9380b30091b78ea0c6ea75/uvloop-0.21.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc", size = 4454428, upload-time = "2024-10-14T23:38:08.416Z" }, + { url = "https://files.pythonhosted.org/packages/63/9a/0962b05b308494e3202d3f794a6e85abe471fe3cafdbcf95c2e8c713aabd/uvloop-0.21.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553", size = 4660018, upload-time = "2024-10-14T23:38:10.888Z" }, ] [[package]] @@ -1073,38 +1174,38 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/03/e2/8ed598c42057de7aa5d97c472254af4906ff0a59a66699d426fc9ef795d7/watchfiles-1.0.5.tar.gz", hash = "sha256:b7529b5dcc114679d43827d8c35a07c493ad6f083633d573d81c660abc5979e9", size = 94537, upload_time = "2025-04-08T10:36:26.722Z" } +sdist = { url = "https://files.pythonhosted.org/packages/03/e2/8ed598c42057de7aa5d97c472254af4906ff0a59a66699d426fc9ef795d7/watchfiles-1.0.5.tar.gz", hash = "sha256:b7529b5dcc114679d43827d8c35a07c493ad6f083633d573d81c660abc5979e9", size = 94537, upload-time = "2025-04-08T10:36:26.722Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/62/435766874b704f39b2fecd8395a29042db2b5ec4005bd34523415e9bd2e0/watchfiles-1.0.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0b289572c33a0deae62daa57e44a25b99b783e5f7aed81b314232b3d3c81a11d", size = 401531, upload_time = "2025-04-08T10:35:35.792Z" }, - { url = "https://files.pythonhosted.org/packages/6e/a6/e52a02c05411b9cb02823e6797ef9bbba0bfaf1bb627da1634d44d8af833/watchfiles-1.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a056c2f692d65bf1e99c41045e3bdcaea3cb9e6b5a53dcaf60a5f3bd95fc9763", size = 392417, upload_time = "2025-04-08T10:35:37.048Z" }, - { url = "https://files.pythonhosted.org/packages/3f/53/c4af6819770455932144e0109d4854437769672d7ad897e76e8e1673435d/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9dca99744991fc9850d18015c4f0438865414e50069670f5f7eee08340d8b40", size = 453423, upload_time = "2025-04-08T10:35:38.357Z" }, - { url = "https://files.pythonhosted.org/packages/cb/d1/8e88df58bbbf819b8bc5cfbacd3c79e01b40261cad0fc84d1e1ebd778a07/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:894342d61d355446d02cd3988a7326af344143eb33a2fd5d38482a92072d9563", size = 458185, upload_time = "2025-04-08T10:35:39.708Z" }, - { url = "https://files.pythonhosted.org/packages/ff/70/fffaa11962dd5429e47e478a18736d4e42bec42404f5ee3b92ef1b87ad60/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab44e1580924d1ffd7b3938e02716d5ad190441965138b4aa1d1f31ea0877f04", size = 486696, upload_time = "2025-04-08T10:35:41.469Z" }, - { url = "https://files.pythonhosted.org/packages/39/db/723c0328e8b3692d53eb273797d9a08be6ffb1d16f1c0ba2bdbdc2a3852c/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6f9367b132078b2ceb8d066ff6c93a970a18c3029cea37bfd7b2d3dd2e5db8f", size = 522327, upload_time = "2025-04-08T10:35:43.289Z" }, - { url = "https://files.pythonhosted.org/packages/cd/05/9fccc43c50c39a76b68343484b9da7b12d42d0859c37c61aec018c967a32/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2e55a9b162e06e3f862fb61e399fe9f05d908d019d87bf5b496a04ef18a970a", size = 499741, upload_time = "2025-04-08T10:35:44.574Z" }, - { url = "https://files.pythonhosted.org/packages/23/14/499e90c37fa518976782b10a18b18db9f55ea73ca14641615056f8194bb3/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0125f91f70e0732a9f8ee01e49515c35d38ba48db507a50c5bdcad9503af5827", size = 453995, upload_time = "2025-04-08T10:35:46.336Z" }, - { url = "https://files.pythonhosted.org/packages/61/d9/f75d6840059320df5adecd2c687fbc18960a7f97b55c300d20f207d48aef/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:13bb21f8ba3248386337c9fa51c528868e6c34a707f729ab041c846d52a0c69a", size = 629693, upload_time = "2025-04-08T10:35:48.161Z" }, - { url = "https://files.pythonhosted.org/packages/fc/17/180ca383f5061b61406477218c55d66ec118e6c0c51f02d8142895fcf0a9/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:839ebd0df4a18c5b3c1b890145b5a3f5f64063c2a0d02b13c76d78fe5de34936", size = 624677, upload_time = "2025-04-08T10:35:49.65Z" }, - { url = "https://files.pythonhosted.org/packages/bf/15/714d6ef307f803f236d69ee9d421763707899d6298d9f3183e55e366d9af/watchfiles-1.0.5-cp313-cp313-win32.whl", hash = "sha256:4a8ec1e4e16e2d5bafc9ba82f7aaecfeec990ca7cd27e84fb6f191804ed2fcfc", size = 277804, upload_time = "2025-04-08T10:35:51.093Z" }, - { url = "https://files.pythonhosted.org/packages/a8/b4/c57b99518fadf431f3ef47a610839e46e5f8abf9814f969859d1c65c02c7/watchfiles-1.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:f436601594f15bf406518af922a89dcaab416568edb6f65c4e5bbbad1ea45c11", size = 291087, upload_time = "2025-04-08T10:35:52.458Z" }, + { url = "https://files.pythonhosted.org/packages/c7/62/435766874b704f39b2fecd8395a29042db2b5ec4005bd34523415e9bd2e0/watchfiles-1.0.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0b289572c33a0deae62daa57e44a25b99b783e5f7aed81b314232b3d3c81a11d", size = 401531, upload-time = "2025-04-08T10:35:35.792Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a6/e52a02c05411b9cb02823e6797ef9bbba0bfaf1bb627da1634d44d8af833/watchfiles-1.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a056c2f692d65bf1e99c41045e3bdcaea3cb9e6b5a53dcaf60a5f3bd95fc9763", size = 392417, upload-time = "2025-04-08T10:35:37.048Z" }, + { url = "https://files.pythonhosted.org/packages/3f/53/c4af6819770455932144e0109d4854437769672d7ad897e76e8e1673435d/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9dca99744991fc9850d18015c4f0438865414e50069670f5f7eee08340d8b40", size = 453423, upload-time = "2025-04-08T10:35:38.357Z" }, + { url = "https://files.pythonhosted.org/packages/cb/d1/8e88df58bbbf819b8bc5cfbacd3c79e01b40261cad0fc84d1e1ebd778a07/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:894342d61d355446d02cd3988a7326af344143eb33a2fd5d38482a92072d9563", size = 458185, upload-time = "2025-04-08T10:35:39.708Z" }, + { url = "https://files.pythonhosted.org/packages/ff/70/fffaa11962dd5429e47e478a18736d4e42bec42404f5ee3b92ef1b87ad60/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab44e1580924d1ffd7b3938e02716d5ad190441965138b4aa1d1f31ea0877f04", size = 486696, upload-time = "2025-04-08T10:35:41.469Z" }, + { url = "https://files.pythonhosted.org/packages/39/db/723c0328e8b3692d53eb273797d9a08be6ffb1d16f1c0ba2bdbdc2a3852c/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6f9367b132078b2ceb8d066ff6c93a970a18c3029cea37bfd7b2d3dd2e5db8f", size = 522327, upload-time = "2025-04-08T10:35:43.289Z" }, + { url = "https://files.pythonhosted.org/packages/cd/05/9fccc43c50c39a76b68343484b9da7b12d42d0859c37c61aec018c967a32/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2e55a9b162e06e3f862fb61e399fe9f05d908d019d87bf5b496a04ef18a970a", size = 499741, upload-time = "2025-04-08T10:35:44.574Z" }, + { url = "https://files.pythonhosted.org/packages/23/14/499e90c37fa518976782b10a18b18db9f55ea73ca14641615056f8194bb3/watchfiles-1.0.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0125f91f70e0732a9f8ee01e49515c35d38ba48db507a50c5bdcad9503af5827", size = 453995, upload-time = "2025-04-08T10:35:46.336Z" }, + { url = "https://files.pythonhosted.org/packages/61/d9/f75d6840059320df5adecd2c687fbc18960a7f97b55c300d20f207d48aef/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:13bb21f8ba3248386337c9fa51c528868e6c34a707f729ab041c846d52a0c69a", size = 629693, upload-time = "2025-04-08T10:35:48.161Z" }, + { url = "https://files.pythonhosted.org/packages/fc/17/180ca383f5061b61406477218c55d66ec118e6c0c51f02d8142895fcf0a9/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:839ebd0df4a18c5b3c1b890145b5a3f5f64063c2a0d02b13c76d78fe5de34936", size = 624677, upload-time = "2025-04-08T10:35:49.65Z" }, + { url = "https://files.pythonhosted.org/packages/bf/15/714d6ef307f803f236d69ee9d421763707899d6298d9f3183e55e366d9af/watchfiles-1.0.5-cp313-cp313-win32.whl", hash = "sha256:4a8ec1e4e16e2d5bafc9ba82f7aaecfeec990ca7cd27e84fb6f191804ed2fcfc", size = 277804, upload-time = "2025-04-08T10:35:51.093Z" }, + { url = "https://files.pythonhosted.org/packages/a8/b4/c57b99518fadf431f3ef47a610839e46e5f8abf9814f969859d1c65c02c7/watchfiles-1.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:f436601594f15bf406518af922a89dcaab416568edb6f65c4e5bbbad1ea45c11", size = 291087, upload-time = "2025-04-08T10:35:52.458Z" }, ] [[package]] name = "websockets" version = "15.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload_time = "2025-03-05T20:03:41.606Z" } +sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload_time = "2025-03-05T20:02:36.695Z" }, - { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload_time = "2025-03-05T20:02:37.985Z" }, - { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload_time = "2025-03-05T20:02:39.298Z" }, - { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload_time = "2025-03-05T20:02:40.595Z" }, - { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload_time = "2025-03-05T20:02:41.926Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload_time = "2025-03-05T20:02:43.304Z" }, - { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload_time = "2025-03-05T20:02:48.812Z" }, - { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload_time = "2025-03-05T20:02:50.14Z" }, - { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload_time = "2025-03-05T20:02:51.561Z" }, - { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload_time = "2025-03-05T20:02:53.814Z" }, - { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload_time = "2025-03-05T20:02:55.237Z" }, - { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload_time = "2025-03-05T20:03:39.41Z" }, + { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" }, + { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" }, + { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" }, + { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" }, + { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" }, + { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" }, + { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" }, + { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, + { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, ] diff --git a/kontor-doc/.gitattributes b/kontor-doc/.gitattributes new file mode 100644 index 0000000..f91f646 --- /dev/null +++ b/kontor-doc/.gitattributes @@ -0,0 +1,12 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# Linux start script should use lf +/gradlew text eol=lf + +# These are Windows script files and should use crlf +*.bat text eol=crlf + +# Binary files should be left untouched +*.jar binary + diff --git a/kontor-doc/.gitignore b/kontor-doc/.gitignore new file mode 100644 index 0000000..5c4ac6d --- /dev/null +++ b/kontor-doc/.gitignore @@ -0,0 +1,8 @@ +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build + +# Ignore Kotlin plugin data +.kotlin diff --git a/kontor-doc/build.gradle.kts b/kontor-doc/build.gradle.kts new file mode 100644 index 0000000..7d85b00 --- /dev/null +++ b/kontor-doc/build.gradle.kts @@ -0,0 +1,49 @@ +plugins { + id("base") + id("maven-publish") + id("de.infolektuell.typst") version "0.8.0" +} + +typst.version = "v0.14.2" + +typst.sourceSets { + // Sources in src/main + val main by registering { + // The files to compile (without .typ extension) in src/main/typst + documents = listOf("kontor") // src/main/typst/document.typst + inputs.put("version", version.toString()) + } +} + +tasks.withType().configureEach { + dependsOn(tasks.named("compileTypst")) +} + +publishing { + publications { + create("maven") { + artifactId = "kontor" + artifact(file("build/typst/main/pdf/kontor.pdf")) { + classifier = "docs" + extension = "pdf" + } + } + } + repositories { + maven { + // Determine URL based on version + url = uri( + if (version.toString().endsWith("SNAPSHOT")) { + "https://nexus.thpeetz.de/repository/maven-snapshots/" + } else { + "https://nexus.thpeetz.de/repository/maven-releases/" + } + ) + // Credentials + credentials { + username = project.findProperty("nexusUsername") as String? ?: System.getenv("NEXUS_USERNAME") + password = project.findProperty("nexusPassword") as String? ?: System.getenv("NEXUS_PASSWORD") + } + } + } +} diff --git a/kontor-doc/gradle.properties b/kontor-doc/gradle.properties new file mode 100644 index 0000000..aae9744 --- /dev/null +++ b/kontor-doc/gradle.properties @@ -0,0 +1,7 @@ +# This file was generated by the Gradle 'init' task. +# https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties +description='Kontor Documentation' +version=0.3.0-SNAPSHOT +group=de.thpeetz +org.gradle.configuration-cache=true + diff --git a/kontor-doc/gradle/libs.versions.toml b/kontor-doc/gradle/libs.versions.toml new file mode 100644 index 0000000..a1a7386 --- /dev/null +++ b/kontor-doc/gradle/libs.versions.toml @@ -0,0 +1,2 @@ +# This file was generated by the Gradle 'init' task. +# https://docs.gradle.org/current/userguide/version_catalogs.html#sec::toml-dependencies-format diff --git a/kontor-doc/gradle/wrapper/gradle-wrapper.jar b/kontor-doc/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..d997cfc Binary files /dev/null and b/kontor-doc/gradle/wrapper/gradle-wrapper.jar differ diff --git a/kontor-doc/gradle/wrapper/gradle-wrapper.properties b/kontor-doc/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..c61a118 --- /dev/null +++ b/kontor-doc/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/kontor-doc/gradlew b/kontor-doc/gradlew new file mode 100755 index 0000000..739907d --- /dev/null +++ b/kontor-doc/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed 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. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +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 + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/kontor-doc/gradlew.bat b/kontor-doc/gradlew.bat new file mode 100644 index 0000000..c4bdd3a --- /dev/null +++ b/kontor-doc/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem 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, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/kontor-doc/settings.gradle.kts b/kontor-doc/settings.gradle.kts new file mode 100644 index 0000000..11bd2ea --- /dev/null +++ b/kontor-doc/settings.gradle.kts @@ -0,0 +1,8 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * For more detailed information on multi-project builds, please refer to https://docs.gradle.org/9.4.1/userguide/multi_project_builds.html in the Gradle documentation. + */ + +rootProject.name = "kontor-doc" diff --git a/kontor-doc/src/main/typst/domain.typ b/kontor-doc/src/main/typst/domain.typ new file mode 100644 index 0000000..6883013 --- /dev/null +++ b/kontor-doc/src/main/typst/domain.typ @@ -0,0 +1,25 @@ += Anforderungen der Domäne + +== Systemfunktionen + +=== Anwendungsfälle + +=== Akteure + +=== Zielgruppen + +== Anforderungen + +=== Anforderungen an externe Schnittstellen + +=== Funktionale Anforderungen + +=== Qualitätsanforderungen + +=== Randbedingungen + +=== Weitere Anforderungen + +=== Wartungs- und Supportinformationen + +== Verifikation diff --git a/kontor-doc/src/main/typst/kontor.typ b/kontor-doc/src/main/typst/kontor.typ new file mode 100644 index 0000000..d9e05cb --- /dev/null +++ b/kontor-doc/src/main/typst/kontor.typ @@ -0,0 +1,98 @@ +#let version = sys.inputs.at("version", default: "0.0.1") +//#set page("a4") +#import "@preview/basic-report:0.5.0": * +#import "@preview/in-dexter:0.7.2": * +#import "@preview/pintorita:0.1.4" + +#set text(fill: white) +#show raw.where(lang: "pintora"): it => pintorita.render(it.text) + +#show: it => basic-report( + doc-category: "Entwicklungs- und Projekthandbuch", + doc-title: "Projekt kontor\nVersion " + version, + author: "Thomas Peetz", + language: "de", + compact-mode: false, + show-outline: true, + it, +) + += Allgemeines + +#figure( + table( + columns: 4, + [Version], [Datum], [Autor], [Änderungsgrund / Bemerkungen], + [1.0.0], [16.05.2022], [Thomas Peetz], [Ersterstellung], + ), + caption: [Dokumenthistorie], +) + +== Zweck des Dokumentes + +Das Entwicklungshandbuch beschreibt die Werkzeuge und die Vorgehensweise bei der Entwicklung +im Projekt kontor-spring und der Erstellung der Dokumentation. + +== Verwendete Tools + +=== Gitea + +Für die Verwaltung des Sourcecode kommt Gitea #index[Gitea]@gitea zum Einsatz. +Mit Gitea werden auch die Projektaufgaben verwaltet. + +Das Projekt und das dazugehörige Git Repository sind unter der Adresse @gitea-kontor zu finden. + += Erstellung der Dokumentation + +Die Dokumentation des Projektes wird mit Asciidoctor #index[Asciidoctor]@asciidoctor geschrieben. +Die Dokumente erhalten ihre Namen nach dem jeweiligen Hauptdokument. + +== Quellcode Verwaltung + +Die Asciidoctor-Dateien haben die Endung `.adoc`. + +== Buildsystem + +Zur Erstellung der PDF-Dateien aus den Asciidoctor-Dateien wird das Buildsystem Gradle #index[Gradle]@gradle verwendet. +Die Dateien für die Dokumente liegen im Verzeichnis `src/docs/asciidoc`. + +Der Gradle Build wird über die Datei `build.gradle` definiert. + +#pagebreak() += Einführung + +== Zweck + +== Stakeholder des Systems + +== Systemumfang + +=== Zielsetzung des Systems + +#pagebreak() +#include "system.typ" + +#include "domain.typ" + +#include "projekt.typ" + += Verschiedenes + +== Erreichbarkeiten + += Referenzen + +#bibliography("reference.yaml", title: none, full: true) + += Glossar + += Index +#make-index(title: none, outlined: true, use-page-counter: true) + += Verzeichnisse + +== Abbildungsverzeichnis +#outline(title: none, target: figure.where(kind: image)) + +== Tabellenverzeichnis +#outline(title: none, target: figure.where(kind: table)) diff --git a/kontor-doc/src/main/typst/projekt.typ b/kontor-doc/src/main/typst/projekt.typ new file mode 100644 index 0000000..a8122f7 --- /dev/null +++ b/kontor-doc/src/main/typst/projekt.typ @@ -0,0 +1,46 @@ += Projektbeschreibung + +== Ausgangslage + +//==== Rechtliche Vorgaben und Rahmenbedingungen +//=== Rahmenbedingungen + +//==== Vorhandene Regelungen + +== Projektziele + +== Projektabgrenzung + +//=== Voraussichtliche Kosten + +//=== Projektrisiken + +//==== Produktivität + +//==== Finanzielle Risiken + +//==== Akzeptanz + += Projektorganisation + +== Projekt-Aufbauorganisation + +== Rollendefinition + +//==== Projektauftraggeber + +//==== Projektausschuss + +//==== Beratung / Qualitätssicherung + +=== Projekteiter + +=== Projektteam + +=== Liste der Stakeholder + +== Projektablauforganisation + +=== Projekt-Phasen + +== Erstellung der Projektdokumentation diff --git a/kontor-doc/src/main/typst/reference.yaml b/kontor-doc/src/main/typst/reference.yaml new file mode 100644 index 0000000..10eaf8a --- /dev/null +++ b/kontor-doc/src/main/typst/reference.yaml @@ -0,0 +1,15 @@ +asciidoctor: + type: web + url: http://asciidoctor.org +gitea: + type: web + url: http://www.gitea.org +gradle: + type: web + url: http://www.gradle.org +jenkins: + type: web + url: http://jenkins-ci.org +gitea-kontor: + type: web + url: https://gitea.thpeetz.de/kontor/kontor-spring diff --git a/kontor-doc/src/main/typst/system.typ b/kontor-doc/src/main/typst/system.typ new file mode 100644 index 0000000..f6b797e --- /dev/null +++ b/kontor-doc/src/main/typst/system.typ @@ -0,0 +1,336 @@ += Systemübersicht + +== Systemkontext + +== Systemarchitektur + +== Systemschnittstellen + +=== Realisierte Schnittstellen + +=== Verwendete Schnittstellen + +== Logisches Datenmodell + +#figure( + kind: image, + ```pintora + erDiagram + USER { + string id PK + datetime created_date + datetime last_modified_date + int version + string email + boolean enabled + string firstName + string lastName + string password + string token + boolean tokenExpired + string userName UNIQUE + } + USER ||--o{ AUTHORIZATION_MATRIX : "matrix" + ROLE { + string id PK + datetime created_date + datetime last_modified_date + int version + string name + } + ROLE ||--o{ AUTHORIZATION_MATRIX : "matrix" + AUTHORIZATION_MATRIX { + string id PK + datetime created_date + datetime last_modified_date + int version + string user_id FK + string role_id FK + } + ```, + caption: [Benutzer ER-Diagramm] +) + +#figure( + kind: image, + ```pintora + erDiagram + comic { + string id PK + datetime created_date + datetime last_modified_date + int version + boolean completed + boolean currentOrder + string title + string publisher_id FK + } + comic ||--o{ comic_work : "1" + comic ||--o{ issue : "1" + comic ||--o{ volume : "1" + comic ||--o{ story_arc : "1" + comic ||--o{ trade_paperback : "1" + volume { + string id PK + datetime created_date + datetime last_modified_date + int version + string name + string comic_id FK + } + volume ||--o{ issue : "1" + issue { + string id PK + datetime created_date + datetime last_modified_date + int version + boolean in_stock + boolean is_read + string issue_number + string comic_id FK + string volume_id FK + } + publisher { + string id PK + datetime created_date + datetime last_modified_date + int version + string name + } + publisher ||--o{ comic : "1" + artist { + string id PK + datetime created_date + datetime last_modified_date + int version + string name + } + artist ||--o{ comic_work : "1" + story_arc { + string id PK + datetime created_date + datetime last_modified_date + int version + string name + string comic_id FK + } + trade_paperback { + string id PK + datetime created_date + datetime last_modified_date + int version + int issueStart + int issueEnd + string name + string comic_id FK + } + worktype { + string id PK + datetime created_date + datetime last_modified_date + int version + string name + } + worktype ||--o{ comic-work : "1" + comic_work { + string id PK + datetime created_date + datetime last_modified_date + int version + string artist_id FK + string comic_id FK + string worktype_id FK + } + ```, + caption: [Comics ER-Diagramm] +) + +#figure( + kind: image, + ```pintora + erDiagram + sport { + string id PK + datetime created_date + datetime last_modified_date + int version + string name + } + team { + string id PK + datetime created_date + datetime last_modified_date + int version + string name + string short_name + string sport_id FK + } + field_position { + string id PK + datetime created_date + datetime last_modified_date + int version + string name + string short_name + string sport_id FK + } + rooster { + string id PK + datetime created_date + datetime last_modified_date + int version + int year + string player_id FK + string position_id FK + string team_id FK + } + player { + string id PK + datetime created_date + datetime last_modified_date + int version + string first_name + string last_name + } + vendor { + string id PK + datetime created_date + datetime last_modified_date + int version + string name + } + card_set { + string id PK + datetime created_date + datetime last_modified_date + int version + boolean insert_set + string name + boolean parallel_set + string vendor_id FK + } + card { + string id PK + datetime created_date + datetime last_modified_date + int version + int cardNumber + int year + string card_set FK + string rooster_id FK + string vendor_id FK + } + sport ||--o{ team : "1" + sport ||--o{ field_position : "1" + field_position ||--o{ rooster : "1" + player ||--o{ rooster : "1" + team ||--o{ rooster : "1" + vendor ||--o{ card : "1" + card_set ||--o{ card : "1" + rooster ||--o{ card : "1" + ```, + caption: [TYSC ER-Diagramm] +) + +#figure( + kind: image, + ```pintora + erDiagram + book { + string id PK + datetime created_date + datetime last_modified_date + int version + string isbn UNIQUE + string title + int year + string publisher_id FK + } + bookshelf_publisher { + string id PK + datetime created_date + datetime last_modified_date + int version + string name UNIQUE + } + author { + string id PK + datetime created_date + datetime last_modified_date + int version + string first_name + string last_name + } + article { + string id PK + datetime created_date + datetime last_modified_date + int version + string title + } + article_author { + string id PK + datetime created_date + datetime last_modified_date + int version + string article_id FK + string author_id FK + } + book_author { + string id PK + datetime created_date + datetime last_modified_date + int version + string book_id FK + string author_id FK + } + bookshelf_publisher ||--o{ book : "1" + article ||--o{ article_author : "1" + author ||--o{ article_author : "1" + book ||--o{ book_author : "1" + author ||--o{ book_author : "1" + ```, + caption: [Bookshelf ER-Diagramm] +) + +#figure( + kind: image, + ```pintora + erDiagram + mail { + string id PK + datetime created_date + datetime last_modified_date + int version + string subject + string content + datetime received_date + datetime sent_date + } + mail_account { + string id PK + datetime created_date + datetime last_modified_date + int version + string host + string password + int port + string protocol + boolean start_tls + string user_name + } + mail_address { + string id PK + datetime created_date + datetime last_modified_date + int version + string internet_address UNIQUE + string personal + string user_id FK + } + user ||--o{ mail_address : "1" + ```, + caption: [Mail ER-Diagramm] +) + +=== Einschränkungen diff --git a/kontor-echo/Containerfile b/kontor-echo/Containerfile new file mode 100644 index 0000000..bbb66d7 --- /dev/null +++ b/kontor-echo/Containerfile @@ -0,0 +1,24 @@ +# ---------- Stage 1: Build ---------- +FROM docker.io/library/golang:1.25-alpine AS builder +# Set the working directory +WORKDIR /app +# Ensure a portable, static-ish binary +ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64 +# Copy and download dependencies +COPY go.mod go.sum ./ +RUN go mod download +# Copy the source code +COPY . . +# Build the Go application (strip debug info for smaller size) +RUN go build -trimpath -ldflags="-s -w" -o kontor cmd/kontor/main.go + +# ---------- Stage 2: Final ---------- +FROM alpine:latest +# Set the working directory +WORKDIR /app +# Install runtime dependencies you actually need +RUN apk add --no-cache ca-certificates tzdata curl +# Copy the binary and set ownership +COPY --from=builder /app/kontor /app/kontor +# Set the entrypoint command +ENTRYPOINT ["/app/kontor"] diff --git a/kontor-echo/Dockerfile b/kontor-echo/Dockerfile deleted file mode 100644 index 08b639f..0000000 --- a/kontor-echo/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -# ---------- Stage 1: Build ---------- -FROM golang:1.25-alpine AS builder -# Set the working directory -WORKDIR /app -# Ensure a portable, static-ish binary -ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64 -# Copy and download dependencies -COPY go.mod go.sum ./ -RUN go mod download -# Copy the source code -COPY . . -# Build the Go application (strip debug info for smaller size) -RUN go build -trimpath -ldflags="-s -w" -o kontor cmd/kontor/main.go - -# ---------- Stage 2: Final ---------- -FROM alpine:latest -# Set the working directory -WORKDIR /app -# Install runtime dependencies you actually need -RUN apk add --no-cache ca-certificates tzdata curl -# Create non-root user for security -RUN addgroup -S kontor && adduser -S -G kontor -H -s /sbin/nologin kontor -# Copy the binary and set ownership -COPY --from=builder --chown=kontor:kontor /app/kontor /app/kontor -# Run as non-root user -USER kontor -# Set the entrypoint command -ENTRYPOINT ["/app/kontor"] diff --git a/kontor-echo/cmd/kontor/main.go b/kontor-echo/cmd/kontor/main.go index 1d9ef14..aef6b85 100644 --- a/kontor-echo/cmd/kontor/main.go +++ b/kontor-echo/cmd/kontor/main.go @@ -49,6 +49,6 @@ func main() { handler.SetupComicRoutes(group) handler.SetupMediaRoutes(group) - e.Logger.Fatal(e.Start(":8700")) + e.Logger.Fatal(e.Start(":8400")) log.Println("Kontor finished") } diff --git a/kontor-echo/pkg/schema/media.go b/kontor-echo/pkg/schema/media.go index d8977e0..f2b5a4f 100644 --- a/kontor-echo/pkg/schema/media.go +++ b/kontor-echo/pkg/schema/media.go @@ -31,7 +31,7 @@ type MediaActor struct { CreatedAt time.Time `bun:"created_date,nullzero,notnull,default:current_timestamp"` UpdatedAt time.Time `bun:"last_modified_date,nullzero,notnull,default:current_timestamp"` Version int `bun:"version,default:0"` - Name string `bun:"name,unique:name"` + Name string `bun:"name"` WebLink string `bun:"url,unique:url"` MediaActorFiles []MediaActorFile `bun:"rel:has-many,join:id=media_actor_id"` diff --git a/kontor-fiber/Containerfile b/kontor-fiber/Containerfile new file mode 100644 index 0000000..bbb66d7 --- /dev/null +++ b/kontor-fiber/Containerfile @@ -0,0 +1,24 @@ +# ---------- Stage 1: Build ---------- +FROM docker.io/library/golang:1.25-alpine AS builder +# Set the working directory +WORKDIR /app +# Ensure a portable, static-ish binary +ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64 +# Copy and download dependencies +COPY go.mod go.sum ./ +RUN go mod download +# Copy the source code +COPY . . +# Build the Go application (strip debug info for smaller size) +RUN go build -trimpath -ldflags="-s -w" -o kontor cmd/kontor/main.go + +# ---------- Stage 2: Final ---------- +FROM alpine:latest +# Set the working directory +WORKDIR /app +# Install runtime dependencies you actually need +RUN apk add --no-cache ca-certificates tzdata curl +# Copy the binary and set ownership +COPY --from=builder /app/kontor /app/kontor +# Set the entrypoint command +ENTRYPOINT ["/app/kontor"] diff --git a/kontor-fiber/Dockerfile b/kontor-fiber/Dockerfile deleted file mode 100644 index 08b639f..0000000 --- a/kontor-fiber/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -# ---------- Stage 1: Build ---------- -FROM golang:1.25-alpine AS builder -# Set the working directory -WORKDIR /app -# Ensure a portable, static-ish binary -ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64 -# Copy and download dependencies -COPY go.mod go.sum ./ -RUN go mod download -# Copy the source code -COPY . . -# Build the Go application (strip debug info for smaller size) -RUN go build -trimpath -ldflags="-s -w" -o kontor cmd/kontor/main.go - -# ---------- Stage 2: Final ---------- -FROM alpine:latest -# Set the working directory -WORKDIR /app -# Install runtime dependencies you actually need -RUN apk add --no-cache ca-certificates tzdata curl -# Create non-root user for security -RUN addgroup -S kontor && adduser -S -G kontor -H -s /sbin/nologin kontor -# Copy the binary and set ownership -COPY --from=builder --chown=kontor:kontor /app/kontor /app/kontor -# Run as non-root user -USER kontor -# Set the entrypoint command -ENTRYPOINT ["/app/kontor"] diff --git a/kontor-fiber/cmd/kontor/main.go b/kontor-fiber/cmd/kontor/main.go index 28ba3ea..efe67d2 100644 --- a/kontor-fiber/cmd/kontor/main.go +++ b/kontor-fiber/cmd/kontor/main.go @@ -35,7 +35,7 @@ func main() { handler.SetupComicRoutes(api) handler.SetupMediaRoutes(api) // Listen on port 8900 - app.Listen(":8600") + app.Listen(":8500") log.Println("Kontor finished") } diff --git a/kontor-fiber/pkg/schema/media.go b/kontor-fiber/pkg/schema/media.go index d8977e0..f2b5a4f 100644 --- a/kontor-fiber/pkg/schema/media.go +++ b/kontor-fiber/pkg/schema/media.go @@ -31,7 +31,7 @@ type MediaActor struct { CreatedAt time.Time `bun:"created_date,nullzero,notnull,default:current_timestamp"` UpdatedAt time.Time `bun:"last_modified_date,nullzero,notnull,default:current_timestamp"` Version int `bun:"version,default:0"` - Name string `bun:"name,unique:name"` + Name string `bun:"name"` WebLink string `bun:"url,unique:url"` MediaActorFiles []MediaActorFile `bun:"rel:has-many,join:id=media_actor_id"` diff --git a/kontor-gui/.gitignore b/kontor-gui/.gitignore deleted file mode 100644 index e877d19..0000000 --- a/kontor-gui/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -deployment/ -venv/ -kontor.bin -bin/ -include/ -lib/ -lib64/ -lib64 -env/ diff --git a/kontor-gui/Makefile b/kontor-gui/Makefile deleted file mode 100644 index 5bb3fcd..0000000 --- a/kontor-gui/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -.PHONY: clean virtualenv test docker dist dist-upload - -clean: - find . -name '*.py[co]' -delete - -virtualenv: - virtualenv --prompt '|> kontor <| ' env - env/bin/pip install -r requirements.txt - env/bin/python setup.py develop - @echo - @echo "VirtualENV Setup Complete. Now run: source env/bin/activate" - @echo - -test: - python -m pytest \ - -v \ - --cov=kontor \ - --cov-report=term \ - --cov-report=html:coverage-report \ - tests/ - -docker: clean - docker build -t kontor-api:latest . - -dist: clean - rm -rf dist/* - python setup.py sdist - python setup.py bdist_wheel - -dist-upload: - twine upload dist/* diff --git a/kontor-gui/README.md b/kontor-gui/README.md deleted file mode 100644 index c2c7bec..0000000 --- a/kontor-gui/README.md +++ /dev/null @@ -1 +0,0 @@ -# kontor-gui diff --git a/kontor-gui/gui/comic_window.py b/kontor-gui/gui/comic_window.py deleted file mode 100644 index d032998..0000000 --- a/kontor-gui/gui/comic_window.py +++ /dev/null @@ -1,66 +0,0 @@ -from PySide6.QtCore import Signal, QSortFilterProxyModel -from PySide6.QtWidgets import QWidget, QVBoxLayout, QTabWidget, QTableView, QMdiSubWindow, \ - QHeaderView - -from gui.model_config import KontorModelConfig -from gui.table_model import KontorTableModel - - -class ComicWindow(QMdiSubWindow): - closed = Signal() - - def __init__(self, main_window): - super().__init__() - self.data_views = list() - self._main_window = main_window - self.log = main_window.log - self._init_gui() - self.tick = main_window.tick - self.cross = main_window.cross - - def _init_gui(self): - self.setWindowTitle("Comics") - self.setWidget(QWidget()) - layout = QVBoxLayout() - self.tabs = QTabWidget() - self.tabs.addTab(self.generate_data_tab("comic"), "Comics") - self.tabs.addTab(self.generate_data_tab("publisher"), "Publisher") - self.tabs.currentChanged.connect(self._tab_changed) - layout.addWidget(self.tabs) - self.setLayout(layout) - self.setWidget(self.tabs) - - def closeEvent(self, event): - self.closed.emit() - super().closeEvent(event) - self._main_window.remove_sub_window('comic') - - def refresh(self): - # self.log.info("refresh") - self.data_views[self.tabs.currentIndex()].refresh() - - def _tab_changed(self, tab_index): - self.data_views[tab_index].refresh() - - def update_status(self, message): - self._main_window.update_status(message) - - def generate_data_tab(self, table_name): - data_tab = QWidget() - - table_config = KontorModelConfig(self._main_window.kontor_db, self, table_name) - model = KontorTableModel(table_config) - layout = QVBoxLayout() - self.data_views.append(model) - data_tab.setLayout(layout) - table_view = QTableView() - header = table_view.horizontalHeader() - header.setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents) - proxy_model = QSortFilterProxyModel() - proxy_model.setSourceModel(model) - table_view.setSortingEnabled(True) - table_view.setModel(proxy_model) - layout.addLayout(table_config.get_filter_layout()) - layout.addWidget(table_view) - model.refresh() - return data_tab diff --git a/kontor-gui/gui/data_view.py b/kontor-gui/gui/data_view.py deleted file mode 100644 index 91c66d2..0000000 --- a/kontor-gui/gui/data_view.py +++ /dev/null @@ -1,12 +0,0 @@ -from abc import ABC, abstractmethod - - -class DataViewMeta(ABC): - @abstractmethod - def get_header(self): - pass - - -class ComicView(DataViewMeta): - def get_header(self): - pass diff --git a/kontor-gui/gui/data_view_model.py b/kontor-gui/gui/data_view_model.py deleted file mode 100644 index 4ffdc8c..0000000 --- a/kontor-gui/gui/data_view_model.py +++ /dev/null @@ -1,32 +0,0 @@ -from typing import List - -from PySide6.QtCore import QModelIndex, QAbstractTableModel -from PySide6.QtGui import Qt - -from gui.data_view import DataViewMeta - - -class DataViewModel(QAbstractTableModel): - def __init__(self): - super().__init__() - self.main_window = None - self._config = None - self._data = List[DataViewMeta] - - def rowCount(self, parent=QModelIndex()): - return len(self._data) - - def columnCount(self, parent=QModelIndex()): - return 0 - - def headerData(self, section, orientation, role=Qt.ItemDataRole.DisplayRole): - return None - - def data(self, index, role=Qt.ItemDataRole.DisplayRole): - return None - - def setData(self, index, value, role=Qt.ItemDataRole.EditRole): - return False - - def flags(self, index): - return None diff --git a/kontor-gui/gui/dialogs.py b/kontor-gui/gui/dialogs.py deleted file mode 100644 index 21dbe92..0000000 --- a/kontor-gui/gui/dialogs.py +++ /dev/null @@ -1,106 +0,0 @@ -from pathlib import Path - -from PySide6.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QHBoxLayout, QPushButton, QFileDialog, \ - QCheckBox, QComboBox - - -class ExportKontorDialog(QDialog): - def __init__(self, parent=None, kontor_db=None): - super().__init__(parent) - - self.parent = parent - self.kontor_db = kontor_db - self.file_name = "data.json" - self.tables = [] - self._table_options = {} - - self.export_options = {"JSON": {"ext": ".json"}, "YAML": {"ext": ".yaml"}, "SQLite": {"ext": ".db"}} - self.current_export_type = "JSON" - - buttons = (QDialogButtonBox.Ok | QDialogButtonBox.Cancel) - - self.buttonBox = QDialogButtonBox(buttons) - self.buttonBox.accepted.connect(self.accept) - self.buttonBox.rejected.connect(self.reject) - - layout = QVBoxLayout() - - self.label = QLabel() - self.label.setText("Export DB to data.json") - - self.combo_box = QComboBox() - self.combo_box.addItems(["JSON", "YAML", "SQLite"]) - self.combo_box.currentTextChanged.connect(self.change_export_type) - file_layout = QHBoxLayout() - file_layout.addWidget(self.label) - file_layout.addWidget(self.combo_box) - file_button = QPushButton("Select file") - file_button.clicked.connect(self.select_file) - file_layout.addWidget(file_button) - layout.addLayout(file_layout) - - for table_name in self.kontor_db.get_table_names(): - check_box = QCheckBox(table_name) - check_box.setChecked(True) - self.tables.append(table_name) - self._table_options[table_name] = check_box - check_box.stateChanged.connect(self.change_selection) - layout.addWidget(check_box) - layout.addWidget(self.buttonBox) - self.setLayout(layout) - - def change_selection(self): - self.tables.clear() - for (name, box) in self._table_options.items(): - if box.isChecked(): - self.tables.append(name) - - def change_export_type(self, text): - self.current_export_type = text - self.label.setText(f'Export DB to data.{self.export_options[text]["ext"]}') - - def select_file(self): - file_dialog = QFileDialog() - file_dialog.setFileMode(QFileDialog.FileMode.AnyFile) - file_dialog.setDefaultSuffix(self.export_options[self.current_export_type]["ext"]) - file_dialog.setNameFilter(f'*{self.export_options[self.current_export_type]["ext"]}') - if file_dialog.exec(): - self.file_name = file_dialog.selectedFiles()[0] - export_file = Path(self.file_name) - self.file_name = export_file.with_suffix(self.export_options[self.current_export_type]["ext"]) - self.label.setText(f"Export DB to {self.file_name}") - - def get_tables_to_export(self) -> list: - return self.tables - - -class ImportKontorDialog(QDialog): - def __init__(self, parent=None): - super().__init__(parent) - - self.file_name = None - - QBtn = (QDialogButtonBox.Ok | QDialogButtonBox.Cancel) - - self.buttonBox = QDialogButtonBox(QBtn) - self.buttonBox.accepted.connect(self.accept) - self.buttonBox.rejected.connect(self.reject) - - self.label = QLabel() - self.label.setText("Import DB from data.json") - layout = QVBoxLayout() - file_layout = QHBoxLayout() - file_layout.addWidget(self.label) - file_button = QPushButton("Select file") - file_button.clicked.connect(self.select_file) - file_layout.addWidget(file_button) - layout.addLayout(file_layout) - layout.addWidget(self.buttonBox) - self.setLayout(layout) - - def select_file(self): - file_dialog = QFileDialog() - file_dialog.setFileMode(QFileDialog.FileMode.ExistingFile) - if file_dialog.exec(): - self.file_name = file_dialog.selectedFiles()[0] - self.label.setText(f"Import DB from {self.file_name}") diff --git a/kontor-gui/gui/main_window.py b/kontor-gui/gui/main_window.py deleted file mode 100644 index 336e2be..0000000 --- a/kontor-gui/gui/main_window.py +++ /dev/null @@ -1,237 +0,0 @@ -from PySide6.QtCore import Qt -from PySide6.QtGui import QAction, QIcon, QGuiApplication -from PySide6.QtWidgets import QMenu, QMessageBox, QProgressBar, QMdiArea -from PySide6.QtWidgets import QLabel, QMainWindow -from sqlalchemy import Engine -from kontor_schema import KontorDB - -from .comic_window import ComicWindow -from .media_window import MediaWindow -from .meta_data_window import MetaDataWindow -from .progress import ProgressUpdate -from .dialogs import ExportKontorDialog, ImportKontorDialog -from .worker import VideoDownloader - - -class MainWindow(QMainWindow): - - def __init__(self, engine: Engine, log): - super().__init__() - - self.downloader = None - self.tick = QIcon('res/tick.png') - self.cross = QIcon('res/cross.png') - self.import_icon = QIcon("res/application-import.png") - self.export_icon = QIcon("res/application-export.png") - self.circle_icon = QIcon("res/arrow-circle-double.png") - - self.data = [] - self.filter = {} - self.kontor_db = KontorDB(engine, log) - self.log = log - self._subwindows = {} - self.media_dir = "/data/media" - self.dl_tool = "yt-dlp" - - self._setup_ui() - - def _setup_ui(self): - self.setWindowTitle("Kontor") - self.setMinimumSize(1200, 800) - self._create_actions() - self.mdi_area = QMdiArea() - self.setCentralWidget(self.mdi_area) - self.mdi_area.setObjectName('mdi_area') - self.mdi_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded) - self.mdi_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded) - self._create_menubar() - self._create_toolbars() - self.status_progress = QProgressBar() - self.progress_update = ProgressUpdate(self.status_progress) - self._create_statusbar() - center_point = QGuiApplication.screens()[0].geometry().center() - self.move(center_point - self.frameGeometry().center()) - - def _create_actions(self): - self.newAction = QAction("&New", self) - self.aboutAction = QAction("&Über...", self) - self.aboutAction.triggered.connect(self.about) - self.showComicWindow = QAction("&Comic Window", self) - self.showComicWindow.triggered.connect(self.show_comic_window) - self.showTyscWindow = QAction("TYSC Window", self) - self.showMediaWindow = QAction("&Media Window", self) - self.showMediaWindow.triggered.connect(self.show_media_window) - self.showMetaDataWindow = QAction("Meta Data Window", self) - self.showMetaDataWindow.triggered.connect(self.show_meta_data_window) - self.importAction = QAction(self.import_icon, "&Import", self) - self.importAction.triggered.connect(self.import_from_file) - self.exportAction = QAction(self.export_icon, "&Export", self) - self.exportAction.triggered.connect(self.export_to_file) - self.refreshAction = QAction(self.circle_icon, "&Refresh", self) - self.refreshAction.triggered.connect(self.refresh) - self.updateTitleAction = QAction("&Update Titles", self) - self.updateTitleAction.triggered.connect(self.update_title) - self.downloadAction = QAction("&Download Videos", self) - self.downloadAction.triggered.connect(self.start_download) - self.checkFileAction = QAction("&Check files", self) - self.checkFileAction.triggered.connect(self.check_files) - self.exitAction = QAction("&Beenden", self) - self.exitAction.setShortcut("Alt+F4") - self.exitAction.triggered.connect(self.close) - - def _create_menubar(self): - menu_bar = self.menuBar() - # File menu - file_menu = QMenu("&Datei") - menu_bar.addMenu(file_menu) - file_menu.addAction(self.exitAction) - # Kontor menu - kontor_menu = QMenu("&Kontor") - menu_bar.addMenu(kontor_menu) - kontor_menu.addAction(self.importAction) - kontor_menu.addAction(self.exportAction) - comic_menu = QMenu("&Comic") - comic_menu.addAction(self.showComicWindow) - tysc_menu = QMenu("&TradeYourSportCards") - media_file_menu = QMenu("&MediaFile") - media_file_menu.addAction(self.updateTitleAction) - media_file_menu.addAction(self.downloadAction) - media_file_menu.addAction(self.checkFileAction) - kontor_menu.addMenu(comic_menu) - kontor_menu.addMenu(tysc_menu) - kontor_menu.addMenu(media_file_menu) - window_menu = QMenu("&Window") - layouts_menu = QMenu("&Layouts") - window_menu.addMenu(layouts_menu) - window_menu.addAction(self.showComicWindow) - window_menu.addAction(self.showMediaWindow) - window_menu.addAction(self.showMetaDataWindow) - menu_bar.addMenu(window_menu) - # Help menu - help_menu = QMenu("&Hilfe") - menu_bar.addMenu(help_menu) - help_menu.addAction(self.aboutAction) - - def _create_toolbars(self): - # Kontor toolbar - kontor_tool_bar = self.addToolBar("Kontor") - kontor_tool_bar.addAction(self.importAction) - kontor_tool_bar.addAction(self.exportAction) - kontor_tool_bar.addAction(self.refreshAction) - - def _create_statusbar(self): - self.statusBar = self.statusBar() - self.statusBar.showMessage("Kontor ready", 6000) - self.status_label = QLabel("") - self.status_progress.setEnabled(False) - self.statusBar.addPermanentWidget(self.status_progress) - - def about(self): - QMessageBox.about(self, "Über Kontor", "Python: 3.11\nKontor: 0.1.0") - - def show_comic_window(self): - if 'comic' not in self._subwindows: - comic = ComicWindow(self) - comic.closed.connect(self.sub_window_closed) - self._subwindows['comic'] = comic - self.mdi_area.addSubWindow(comic) - comic.show() - else: - comic = self._subwindows.pop('comic') - comic.close() - self.mdi_area.removeSubWindow(comic) - - def show_media_window(self): - if 'media' not in self._subwindows: - media = MediaWindow(self) - media.closed.connect(self.sub_window_closed) - self._subwindows['media'] = media - self.mdi_area.addSubWindow(media) - media.show() - else: - media = self._subwindows.pop('media') - media.close() - self.mdi_area.removeSubWindow(media) - - def show_meta_data_window(self): - if 'meta_data' not in self._subwindows: - meta_data = MetaDataWindow(self) - meta_data.closed.connect(self.sub_window_closed) - self._subwindows['meta_data'] = meta_data - self.mdi_area.addSubWindow(meta_data) - meta_data.show() - else: - meta_data = self._subwindows.pop('meta_data') - meta_data.close() - self.mdi_area.removeSubWindow(meta_data) - - def remove_sub_window(self, name: str): - self.log.info("remove subwindow %s", name) - if name in self._subwindows: - window = self._subwindows.pop(name) - window.close() - self.mdi_area.removeSubWindow(window) - - def sub_window_closed(self): - self.log.info("close subwindow") - - def import_from_file(self): - import_dlg = ImportKontorDialog(self) - if import_dlg.exec(): - print(f"import DB from file {import_dlg.file_name}") - self.kontor_db.import_db(import_dlg.file_name) - else: - print("do nothing for import") - - def export_to_file(self): - export_dlg = ExportKontorDialog(self, self.kontor_db) - if export_dlg.exec(): - self.log.info(export_dlg.get_tables_to_export()) - self.log.info(f"export DB to {export_dlg.file_name}") - self.statusBar.showMessage(f"export DB to {export_dlg.file_name}", 3000) - self.kontor_db.export_db(export_dlg.current_export_type, export_dlg.file_name) - else: - self.statusBar.showMessage("Export cancelled", 3000) - - def update_title(self): - self.log.info("update title for table MediaFile") - self.statusBar.showMessage("update title for table MediaFile", 3000) - self.status_progress.setEnabled(True) - self.kontor_db.update_titles() - self.status_progress.setEnabled(False) - self.refresh() - - def start_download(self): - self.status_progress.setEnabled(True) - self.statusBar.showMessage("download videos for table MediaFile", 3000) - self.downloader = VideoDownloader(self.kontor_db, self.log) - self.downloader.setTotalProgress.connect(self.status_progress.setMaximum) - self.downloader.setCurrentProgress.connect(self.downloadProgress) - self.downloader.succeeded.connect(self.downloadSucceeded) - self.downloader.finished.connect(self.downloadFinished) - self.downloader.start() - - def downloadProgress(self, value: int): - self.status_progress.setValue(value) - self.refresh() - - def downloadSucceeded(self): - self.status_progress.setValue(self.status_progress.maximum()) - self.statusBar.showMessage("Download succeeded", 3000) - - def downloadFinished(self): - self.status_progress.setEnabled(False) - del self.downloader - - def check_files(self): - self.log.info("check files") - self.statusBar.showMessage("check files for table MediaFile", 3000) - self.kontor_db.check_files() - - def refresh(self): - self.log.info("refresh") - for (_, window) in self._subwindows.items(): - window.refresh() - - def update_status(self, message, timeout=3000): - self.statusBar.showMessage(message, timeout=timeout) diff --git a/kontor-gui/gui/media_window.py b/kontor-gui/gui/media_window.py deleted file mode 100644 index f084c76..0000000 --- a/kontor-gui/gui/media_window.py +++ /dev/null @@ -1,77 +0,0 @@ -from PySide6.QtCore import Signal, QSortFilterProxyModel -from PySide6.QtWidgets import QMdiSubWindow, QWidget, QVBoxLayout, QTabWidget, QTableView - -from .model_config import KontorModelConfig -from .table_details import KontorTableDetailsView -from .table_model import KontorTableModel - - -class MediaWindow(QMdiSubWindow): - closed = Signal() - - def __init__(self, main_window): - super().__init__() - self.data_views = list() - self._main_window = main_window - self.log = main_window.log - self._init_gui() - self.tick = main_window.tick - self.cross = main_window.cross - - def _init_gui(self): - self.setWindowTitle("Media") - self.setWidget(QWidget()) - layout = QVBoxLayout() - self.tabs = QTabWidget() - self.tabs.addTab(self.generate_data_tab("media_file"), "Media File") - self.tabs.addTab(self.generate_data_tab("media_video"), "Media Video") - self.tabs.addTab(self.generate_data_tab("media_article"), "Media Article") - self.tabs.addTab(self.generate_data_tab_with_details("media_actor"), "Media Actor") - self.tabs.currentChanged.connect(self._tab_changed) - layout.addWidget(self.tabs) - self.setLayout(layout) - self.setWidget(self.tabs) - - def closeEvent(self, event): - self.closed.emit() - super().closeEvent(event) - self._main_window.remove_sub_window('media') - - def refresh(self): - self.log.info("MediaWindow.refresh") - self.data_views[self.tabs.currentIndex()].refresh() - - def _tab_changed(self, tab_index): - self.data_views[tab_index].refresh() - - def update_status(self, message): - self._main_window.update_status(message) - - def generate_data_tab(self, table_name): - data_tab = QWidget() - - table_config = KontorModelConfig(self._main_window.kontor_db, self, table_name) - model = KontorTableModel(table_config) - layout = QVBoxLayout() - self.data_views.append(model) - data_tab.setLayout(layout) - table_view = QTableView() - proxy_model = QSortFilterProxyModel() - proxy_model.setSourceModel(model) - table_view.setSortingEnabled(True) - table_view.setModel(proxy_model) - layout.addLayout(table_config.get_filter_layout()) - layout.addWidget(table_view) - model.refresh() - table_view.resizeColumnToContents(0) - return data_tab - - def generate_data_tab_with_details(self, table_name): - table_config = KontorModelConfig(self._main_window.kontor_db, self, table_name) - model = KontorTableModel(table_config) - self.data_views.append(model) - details_view = KontorTableDetailsView(model) - return details_view.data_view - - def cell_selected(self, item): - self.log.info(f"Cell {item.row()}:{item.column()} clicked") diff --git a/kontor-gui/gui/meta_data_window.py b/kontor-gui/gui/meta_data_window.py deleted file mode 100644 index 567abeb..0000000 --- a/kontor-gui/gui/meta_data_window.py +++ /dev/null @@ -1,66 +0,0 @@ -from PySide6.QtCore import Signal, QSortFilterProxyModel -from PySide6.QtWidgets import QWidget, QVBoxLayout, QTabWidget, QTableView, QMdiSubWindow - -from gui.model_config import KontorModelConfig -from gui.table_model import KontorTableModel - - -class MetaDataWindow(QMdiSubWindow): - closed = Signal() - - def __init__(self, main_window): - super().__init__() - self.data_views = list() - self._main_window = main_window - self.log = main_window.log - self._init_gui() - self.tick = main_window.tick - self.cross = main_window.cross - - def _init_gui(self): - self.setWindowTitle("Meta Data") - self.setWidget(QWidget()) - layout = QVBoxLayout() - self.tabs = QTabWidget() - self.tabs.addTab(self.generate_data_tab("module_data"), "Module") - self.tabs.addTab(self.generate_data_tab("meta_data_table"), "Tables") - self.tabs.addTab(self.generate_data_tab("meta_data_column"), "Columns") - self.tabs.currentChanged.connect(self._tab_changed) - layout.addWidget(self.tabs) - self.setLayout(layout) - self.setWidget(self.tabs) - - def closeEvent(self, event): - self.closed.emit() - super().closeEvent(event) - self._main_window.remove_sub_window('meta_data') - - def refresh(self): - # self.log.info("refresh") - self.data_views[self.tabs.currentIndex()].refresh() - - def _tab_changed(self, tab_index): - self.data_views[tab_index].refresh() - - def update_status(self, message): - self._main_window.update_status(message) - - def generate_data_tab(self, table_name): - data_tab = QWidget() - table_config = KontorModelConfig(self._main_window.kontor_db, self, table_name) - model = KontorTableModel(table_config) - layout = QVBoxLayout() - self.data_views.append(model) - data_tab.setLayout(layout) - table_view = QTableView() - # header = table_view.horizontalHeader() - # header.setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents) - proxy_model = QSortFilterProxyModel() - proxy_model.setSourceModel(model) - table_view.setSortingEnabled(True) - table_view.setModel(proxy_model) - layout.addLayout(table_config.get_filter_layout()) - layout.addWidget(table_view) - model.refresh() - table_view.resizeColumnToContents(0) - return data_tab diff --git a/kontor-gui/gui/model_config.py b/kontor-gui/gui/model_config.py deleted file mode 100644 index 6a4e00b..0000000 --- a/kontor-gui/gui/model_config.py +++ /dev/null @@ -1,55 +0,0 @@ -from PySide6.QtWidgets import QHBoxLayout, QCheckBox -from kontor_schema import KontorDB, ColumnEntry - - -class KontorModelConfig: - - def __init__(self, kontor_db: KontorDB, main_window, table_name: str): - self.header = {} - self.filter = {} - self.main_window = main_window - self.log = main_window.log - self._table_name = table_name - self.kontor_db = kontor_db - self.get_table_config() - - def __str__(self): - return f"KontorModelConfig({self._table_name})" - - def get_table_config(self): - # self.log.info("get_table_config %s", self) - self.header = self.kontor_db.get_column_meta_data(self._table_name) - self.filter = self.kontor_db.get_filters(self._table_name) - # self.log.info("headers: %s", self.header) - # self.log.info("%s filters: %s", self, self.filter) - - def filters(self) -> dict: - # self.log.info("%s filters: %s", self, self.filter) - _filters = {} - # print(self.filter["download"].isChecked()) - for column, filter_info in self.filter.items(): - # print(column, filter_info) - if filter_info[ColumnEntry.COLUMN_WIDGET].isChecked(): - _filters[column] = True - # print(f"{filter_rule=}") - # self.log.info("filters -> %s", _filters) - return _filters - - def get_data(self) -> list: - # self.log.info("get_data") - data = self.kontor_db.data(self._table_name, self.header, self.filters()) - # self.log.info("get_data: %d %s", len(data), data) - return data - - def get_filter_layout(self) -> QHBoxLayout: - # self.log.info("get_filter_layout: %s", self.filter) - filter_layout = QHBoxLayout() - for column, filter_info in self.filter.items(): - filter_checkbox = QCheckBox() - filter_checkbox.setText(filter_info[ColumnEntry.COLUMN_LABEL]) - filter_checkbox.checkStateChanged.connect(self.main_window.refresh) - self.filter[column][ColumnEntry.COLUMN_WIDGET] = filter_checkbox - filter_layout.addWidget(filter_checkbox) - filter_layout.addStretch() - # self.log.info("get_filter_layout: %s", self.filter) - return filter_layout diff --git a/kontor-gui/gui/progress.py b/kontor-gui/gui/progress.py deleted file mode 100644 index 1b44c26..0000000 --- a/kontor-gui/gui/progress.py +++ /dev/null @@ -1,18 +0,0 @@ -from PySide6.QtWidgets import QProgressBar - - -class ProgressUpdate: - def __init__(self, progress: QProgressBar): - self.start = 0 - self.end = 0 - self.current = 0 - self.progress = progress - - def start(self, start_value, end_value): - self.start = start_value - self.end = end_value - self.current = start_value - self.progress.update() - - def update(self, current): - self.progress.update() diff --git a/kontor-gui/gui/table_details.py b/kontor-gui/gui/table_details.py deleted file mode 100644 index 07760f0..0000000 --- a/kontor-gui/gui/table_details.py +++ /dev/null @@ -1,60 +0,0 @@ -from PySide6.QtCore import QSortFilterProxyModel -from PySide6.QtWidgets import QHBoxLayout, QWidget, QTableView, QVBoxLayout, QFormLayout, QLineEdit, QLabel - -from .table_model import KontorTableModel - - -class KontorTableDetailsView: - def __init__(self, table_model: KontorTableModel): - self._data_view: QWidget = QWidget() - self._model = table_model - self.log = table_model.log - self._table_view = QTableView() - self._label = QLabel() - self.init_gui() - - def init_gui(self): - self.log.info("KontorTableDetailsView.init_gui()") - layout = QVBoxLayout() - self._data_view.setLayout(layout) - details_layout = QHBoxLayout() - table_with_details = QWidget() - table_with_details.setLayout(details_layout) - - self._table_view.setSelectionBehavior(QTableView.SelectionBehavior.SelectRows) - proxy_model = QSortFilterProxyModel() - proxy_model.setSourceModel(self._model) - self._table_view.setSortingEnabled(True) - self._table_view.setModel(proxy_model) - self._table_view.clicked.connect(self.update_details) - self._table_view.activated.connect(self.refresh_details) - - layout.addLayout(self._model.config.get_filter_layout()) - details_layout.addWidget(self._table_view) - - form = QWidget() - form_layout = QFormLayout(form) - form.setLayout(form_layout) - - title = QLineEdit(form) - form_layout.addRow("ID", self._label) - form_layout.addRow("Title", title) - # layout.addWidget(table_view) - details_layout.addWidget(form) - layout.addWidget(table_with_details) - self._model.refresh() - self._table_view.resizeColumnToContents(0) - - @property - def data_view(self): - return self._data_view - - def update_details(self, item): - print(f"Cell {item.row()}-{item.column()} selected") - self.log.info(f"Cell {item.row()}-{item.column()} selected") - self._label.setText(self._model.raw_data()[item.row()][0]) - - def refresh_details(self): - indexes = self._table_view.selectedIndexes() - for index in indexes: - self.log.info(f"refresh_details: Cell {index.row()}-{index.column()} selected") diff --git a/kontor-gui/gui/table_model.py b/kontor-gui/gui/table_model.py deleted file mode 100644 index fb32802..0000000 --- a/kontor-gui/gui/table_model.py +++ /dev/null @@ -1,128 +0,0 @@ -from datetime import datetime -from typing import Any - -from PySide6.QtCore import QAbstractTableModel, QModelIndex -from PySide6.QtGui import Qt, QColor -from kontor_schema.database import ColumnEntry - -from .model_config import KontorModelConfig - - -def get_display_value(value: Any, column_config: dict, window) -> str: - if isinstance(value, datetime): - return value.strftime("%Y-%m-%d %M:%M:%S") - if column_config[ColumnEntry.COLUMN_TYPE] == 'BOOLEAN': - if value == 1: - return window.tick - else: - return window.cross - if value is None: - return "" - # window.log.info(f"unknown type: {column_config[ColumnEntry.COLUMN_TYPE]} - {type(value)}") - return str(value) - - -def get_edit_value(value, column_config, window): - # window.log.info(f"edit value {value}") - return str(value) - - -def get_decoration_value(value: Any, column_config: dict, window): - if column_config[ColumnEntry.COLUMN_TYPE] == 'BOOLEAN': - if value == 1: - return window.tick - else: - return window.cross - - -def get_background_value(value: Any, column_config: dict, window): - if value is None: - return QColor('lightgrey') - - -class KontorTableModel(QAbstractTableModel): - - def __init__(self, model_config: KontorModelConfig): - super().__init__() - self._main_window = model_config.main_window - self._config = model_config - self._data = [] - self.log = model_config.log - - def __str__(self): - return f"KontorTableModel({self._config})" - - @property - def config(self): - return self._config - - @property - def raw_data(self): - return self._data - - def refresh(self): - # self.log.info("refresh") - data = self._config.get_data() - count = 0 - # print(data) - if data is not None: - self.beginResetModel() - self._data.clear() - self._data = data - self.endResetModel() - count = len(data) - # print(data) - # print(self._data) - self.layoutChanged.emit() - self._main_window.update_status(f"{count} Einträge geladen") - - def rowCount(self, parent=QModelIndex()): - # self.log.info("rowCount %s: %d", self, len(self._data)) - # The length of the outer list. - if self._data is None: - return 0 - return len(self._data) - - def headerData(self, col, orientation, role=Qt.ItemDataRole.DisplayRole): - # self.log.info(f"{self._config.header[col]}") - if orientation == Qt.Orientation.Horizontal and role == Qt.ItemDataRole.DisplayRole: - return self._config.header[col][ColumnEntry.COLUMN_LABEL] - if orientation == Qt.Orientation.Vertical and role == Qt.ItemDataRole.DisplayRole: - return str(col + 1) - - def data(self, index, role=Qt.ItemDataRole.DisplayRole): - if self._data is None: - return None - value = self._data[index.row()][index.column()] - # print('{}:: {}:: {}:: {}: {}'.format(index, role, self._config.header[index.column()][ColumnEntry.COLUMN_TYPE], value, type(value))) - match role: - case Qt.ItemDataRole.DisplayRole: - return get_display_value(value, self._config.header[index.column()], self._config.main_window) - case Qt.ItemDataRole.EditRole: - return get_edit_value(value, self._config.header[index.column()], self._config.main_window) - case Qt.ItemDataRole.DecorationRole: - return get_decoration_value(value, self._config.header[index.column()], self._config.main_window) - case Qt.ItemDataRole.BackgroundRole: - return get_background_value(value, self._config.header[index.column()], self._config.main_window) - - def columnCount(self, index=QModelIndex()): - # self.log.info("rowCount %s: %d", self, len(self._config.header)) - return len(self._config.header) - - def setData(self, index, value, role=Qt.ItemDataRole.EditRole) -> bool: - # self._config.log.info(f"{index}: {role}") - if role == Qt.ItemDataRole.EditRole: - self._data[index.row()][index.column()] = value - # self._config.log.info(f"{index.row()}-{index.column()}: {self._data[index.row()][index.column()]}") - self.dataChanged.emit(index, index) - return True - if role == Qt.ItemDataRole.CheckStateRole: - print("role == Qt.ItemDataRole.CheckStateRole") - checked = value == Qt.CheckState.Checked - self._data[index.row()][index.column()] = checked - return False - - def flags(self, index): - if self._config.header[index.column()][ColumnEntry.COLUMN_NAME] == 'id': - return Qt.ItemFlag.ItemIsEnabled - return Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsEditable | Qt.ItemFlag.ItemIsUserTristate diff --git a/kontor-gui/gui/worker.py b/kontor-gui/gui/worker.py deleted file mode 100644 index 5f0d4d6..0000000 --- a/kontor-gui/gui/worker.py +++ /dev/null @@ -1,27 +0,0 @@ - -from PySide6.QtCore import Signal, QThread - - -class VideoDownloader(QThread): - # Signal for the window to establish the maximum value - # of the progress bar. - setTotalProgress = Signal(int) - # Signal to increase the progress. - setCurrentProgress = Signal(int) - # Signal to be emitted when the file has been downloaded successfully. - succeeded = Signal() - - def __init__(self, kontor_db, log): - super().__init__() - self.kontor_db = kontor_db - self.log = log - - def run(self): - self.log.info("download videos for table MediaFile") - download_entries = self.kontor_db.get_download_list() - self.setTotalProgress.emit(len(download_entries)) - for index, entry in enumerate(download_entries): - self.kontor_db.download_file(entry) - self.setCurrentProgress.emit(index) - self.succeeded.emit() - diff --git a/kontor-gui/main.py b/kontor-gui/main.py deleted file mode 100644 index 9ec73f1..0000000 --- a/kontor-gui/main.py +++ /dev/null @@ -1,48 +0,0 @@ -""" -PySide6 GUI for Kontor -""" -import sys -import logging.config -from pathlib import Path -from platformdirs import PlatformDirs -from PySide6.QtWidgets import QApplication -import yaml -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker -from kontor_schema.base import Base - -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter -from gui.main_window import MainWindow - -parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('--verbose', '-v', action='count', default=0) -parser.add_argument('--config', '-c', default='kontor-docker') -args = parser.parse_args() - - -if __name__ == '__main__': - app = QApplication(sys.argv) - dirs = PlatformDirs(args.config) - database_config = Path(dirs.user_config_dir, 'database-config.yaml') - with open(database_config, 'rt') as f: - db_config = yaml.safe_load(f.read()) - connect_string = ('mariadb+mariadbconnector://{}:{}@{}:{}/{}'.format( - db_config['mariadb']['user'], - db_config['mariadb']['password'], - db_config['mariadb']['host'], - db_config['mariadb']['port'], - db_config['mariadb']['database'] - )) - logging_config = Path(dirs.user_config_dir, 'logging-config.yaml') - with open(logging_config, 'rt') as f: - config = yaml.safe_load(f.read()) - logging.config.dictConfig(config) - logger = logging.getLogger('development') - # engine = create_engine(connect_string, echo=True) - engine = create_engine(connect_string) - Base.metadata.create_all(bind=engine, checkfirst=True) - __session__ = sessionmaker(bind=engine) - - window = MainWindow(engine, logger) - window.show() - app.exec() diff --git a/kontor-gui/pyproject.toml b/kontor-gui/pyproject.toml deleted file mode 100644 index db3be97..0000000 --- a/kontor-gui/pyproject.toml +++ /dev/null @@ -1,26 +0,0 @@ -[project] -name = "kontor-gui" -version = "0.1.0" -description = "Kontor GUI" -authors = [ - {name = "Thomas Peetz", email = "thomas.peetz@thpeetz.de"}, -] -dependencies = [ - "platformdirs", - "pyyaml", - "PySide6", -] -requires-python = ">=3.11" -readme = "README.md" -license = {text = "MIT"} - -[build-system] -requires = ["pdm-backend"] -build-backend = "pdm.backend" - - -[tool.pdm] -distribution = true - -[dependency-groups] -dev = ["-e file:///${PROJECT_ROOT}/../kontor-schema#egg=kontor-schema"] diff --git a/kontor-gui/pysidedeploy.spec b/kontor-gui/pysidedeploy.spec deleted file mode 100644 index 6fb865d..0000000 --- a/kontor-gui/pysidedeploy.spec +++ /dev/null @@ -1,98 +0,0 @@ -[app] - -# title of your application -title = kontor - -# project directory. the general assumption is that project_dir is the parent directory -# of input_file -project_dir = /home/tpeetz/projects/kontor/python/kontor-gui - -# source file path -input_file = /home/tpeetz/projects/kontor/python/kontor-gui/main.py - -# directory where exec is stored -exec_directory = . - -# path to .pyproject project file -project_file = - -# application icon -icon = /usr/local/lib/python3.11/dist-packages/PySide6/scripts/deploy_lib/pyside_icon.jpg - -[python] - -# python path -python_path = /home/tpeetz/projects/kontor/python/kontor-gui/env/bin/python - -# python packages to install -packages = Nuitka==2.4.8 - -# buildozer = for deploying Android application -android_packages = buildozer==1.5.0,cython==0.29.33 - -[qt] - -# comma separated path to qml files required -# normally all the qml files required by the project are added automatically -qml_files = - -# excluded qml plugin binaries -excluded_qml_plugins = - -# qt modules used. comma separated -modules = Widgets,DBus,Core,Gui - -# qt plugins used by the application -plugins = platformthemes,imageformats,platforms,generic,iconengines,egldeviceintegrations,styles,xcbglintegrations,platforms/darwin,platforminputcontexts,accessiblebridge - -[android] - -# path to pyside wheel -wheel_pyside = - -# path to shiboken wheel -wheel_shiboken = - -# plugins to be copied to libs folder of the packaged application. comma separated -plugins = - -[nuitka] - -# usage description for permissions requested by the app as found in the info.plist file -# of the app bundle -# eg = extra_args = --show-modules --follow-stdlib -macos.permissions = - -# mode of using nuitka. accepts standalone or onefile. default is onefile. -mode = onefile - -# (str) specify any extra nuitka arguments -extra_args = --quiet --noinclude-qt-translations - -[buildozer] - -# build mode -# possible options = [release, debug] -# release creates an aab, while debug creates an apk -mode = debug - -# contrains path to pyside6 and shiboken6 recipe dir -recipe_dir = - -# path to extra qt android jars to be loaded by the application -jars_dir = - -# if empty uses default ndk path downloaded by buildozer -ndk_path = - -# if empty uses default sdk path downloaded by buildozer -sdk_path = - -# other libraries to be loaded. comma separated. -# loaded at app startup -local_libs = - -# architecture of deployed platform -# possible values = ["aarch64", "armv7a", "i686", "x86_64"] -arch = - diff --git a/kontor-gui/pyvenv.cfg b/kontor-gui/pyvenv.cfg deleted file mode 100644 index e6324f5..0000000 --- a/kontor-gui/pyvenv.cfg +++ /dev/null @@ -1,5 +0,0 @@ -home = /usr/bin -include-system-site-packages = false -version = 3.11.2 -executable = /usr/bin/python3.11 -command = /usr/bin/python -m venv /home/tpeetz/projects/kontor/python/kontor-gui diff --git a/kontor-gui/requirements.txt b/kontor-gui/requirements.txt deleted file mode 100644 index a6e9a93..0000000 --- a/kontor-gui/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ --e ../kontor-schema - -platformdirs -pyyaml -PySide6 - diff --git a/kontor-gui/res/application-export.png b/kontor-gui/res/application-export.png deleted file mode 100644 index 555887a..0000000 Binary files a/kontor-gui/res/application-export.png and /dev/null differ diff --git a/kontor-gui/res/application-import.png b/kontor-gui/res/application-import.png deleted file mode 100644 index 922cb07..0000000 Binary files a/kontor-gui/res/application-import.png and /dev/null differ diff --git a/kontor-gui/res/arrow-circle-double.png b/kontor-gui/res/arrow-circle-double.png deleted file mode 100644 index ba5ebd1..0000000 Binary files a/kontor-gui/res/arrow-circle-double.png and /dev/null differ diff --git a/kontor-gui/res/cross.png b/kontor-gui/res/cross.png deleted file mode 100644 index 6b9fa6d..0000000 Binary files a/kontor-gui/res/cross.png and /dev/null differ diff --git a/kontor-gui/res/tick.png b/kontor-gui/res/tick.png deleted file mode 100644 index 2414885..0000000 Binary files a/kontor-gui/res/tick.png and /dev/null differ diff --git a/kontor-javalin/Containerfile b/kontor-javalin/Containerfile new file mode 100644 index 0000000..1ba141b --- /dev/null +++ b/kontor-javalin/Containerfile @@ -0,0 +1,21 @@ +# ----------------------------------------------------------------------- # +FROM docker.io/library/gradle:9.2.1-jdk21 AS builder +WORKDIR / +COPY ./src/main/ ./src/main/ +COPY ./build.gradle ./ +COPY ./gradle.properties ./ +COPY ./settings.gradle ./ +COPY ./gradle/libs.versions.toml ./gradle/ +RUN gradle build --no-daemon + +# ----------------------------------------------------------------------- # +FROM docker.io/alpine/java:21-jre AS run + +RUN apk --no-cache add curl + +COPY --from=builder /build/libs/kontor-javalin-0.2.0-SNAPSHOT.jar app.jar + +EXPOSE 8600 + +CMD ["java", "-jar", "app.jar"] + diff --git a/kontor-javalin/Dockerfile b/kontor-javalin/Dockerfile deleted file mode 100644 index 9e50434..0000000 --- a/kontor-javalin/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -# ----------------------------------------------------------------------- # -FROM gradle:9.2.1-jdk21 AS builder -WORKDIR / -COPY ./src/main/ ./src/main/ -COPY ./build.gradle ./ -COPY ./gradle.properties ./ -COPY ./settings.gradle ./ -COPY ./gradle/libs.versions.toml ./gradle/ -RUN gradle build --no-daemon - -# ----------------------------------------------------------------------- # -FROM alpine/java:21-jre AS run - -RUN apk --no-cache add curl - -RUN adduser --system appuser -USER appuser - -COPY --from=builder --chown=appuser:appuser /build/libs/kontor-javalin-0.2.0-SNAPSHOT.jar app.jar - -EXPOSE 8400 -USER appuser - -CMD ["java", "-jar", "app.jar"] - diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/Main.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/Main.java index f6ffa6e..3081245 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/Main.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/Main.java @@ -16,7 +16,7 @@ import io.javalin.config.Key; public class Main { private static Logger logger = LoggerFactory.getLogger(Main.class); - private static short port = 8400; + private static short port = 8600; // private static Key emf = new // Key("entityManagerFactory"); private static Key sf = new Key<>("SessionFactory"); diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/media/MediaActor.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/media/MediaActor.java index 77f8f40..54e570f 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/media/MediaActor.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/media/MediaActor.java @@ -39,10 +39,9 @@ public class MediaActor { private Date lastModifiedDate; @NotEmpty - @Column(unique = true) private String name; - @Column(nullable = true) + @Column(nullable = true,unique = true) private String url; @Column(nullable = true) diff --git a/kontor-schema/.python-version b/kontor-model/.python-version similarity index 100% rename from kontor-schema/.python-version rename to kontor-model/.python-version diff --git a/kontor-schema/README.md b/kontor-model/README.md similarity index 100% rename from kontor-schema/README.md rename to kontor-model/README.md diff --git a/kontor-model/pyproject.toml b/kontor-model/pyproject.toml new file mode 100644 index 0000000..22eedda --- /dev/null +++ b/kontor-model/pyproject.toml @@ -0,0 +1,18 @@ +[project] +name = "kontor_model" +version = "0.3.0" +description = "Kontor Model" +readme = "README.md" +authors = [ + { name = "Thomas Peetz", email = "thomas.peetz@cimt-ag.de" } +] +requires-python = ">=3.13" +dependencies = [ + "sqlalchemy>=2.0.52", + "msgspec[toml,yaml]>=0.21.1", + "pydantic[email]>=2.13.4", +] + +[build-system] +requires = ["uv_build>=0.9.27,<0.10.0"] +build-backend = "uv_build" diff --git a/kontor-model/src/kontor_model/__init__.py b/kontor-model/src/kontor_model/__init__.py new file mode 100644 index 0000000..253334d --- /dev/null +++ b/kontor-model/src/kontor_model/__init__.py @@ -0,0 +1,2 @@ +def hello() -> str: + return "Hello from kontor-model!" diff --git a/kontor-api/src/db/models/__init__.py b/kontor-model/src/kontor_model/db/__init__.py similarity index 100% rename from kontor-api/src/db/models/__init__.py rename to kontor-model/src/kontor_model/db/__init__.py diff --git a/kontor-model/src/kontor_model/db/models/__init__.py b/kontor-model/src/kontor_model/db/models/__init__.py new file mode 100644 index 0000000..88d05c8 --- /dev/null +++ b/kontor-model/src/kontor_model/db/models/__init__.py @@ -0,0 +1,86 @@ +from typing import Any, Dict +from kontor_model.db.models.admin import ( + Assignment, + Token, + Profile, + Permission, + MailAccount, + Mail, +) +from kontor_model.db.models.bookshelf import ( + ArticleAuthor, + BookAuthor, + BookshelfPublisher, + Article, + Book, + Author, +) +from kontor_model.db.models.comic import ( + Issue, + StoryArc, + TradePaperback, + Volume, + ComicWork, + IssueWork, + Artist, + Comic, + Publisher, + WorkType, +) +from kontor_model.db.models.media import ( + MediaFile, + MediaActor, + MediaActorFile, + MediaArticle, + MediaVideo, + MediaLofi, +) +from kontor_model.db.models.tysc import ( + Card, + CardSet, + Rooster, + Team, + FieldPosition, + Player, + Vendor, + Sport, +) + +registry: Dict[str, Any] = { + Sport.__tablename__: Sport, + Player.__tablename__: Player, + Team.__tablename__: Team, + FieldPosition.__tablename__: FieldPosition, + Rooster.__tablename__: Rooster, + Vendor.__tablename__: Vendor, + CardSet.__tablename__: CardSet, + Card.__tablename__: Card, + Artist.__tablename__: Artist, + Publisher.__tablename__: Publisher, + WorkType.__tablename__: WorkType, + Comic.__tablename__: Comic, + Volume.__tablename__: Volume, + StoryArc.__tablename__: StoryArc, + Issue.__tablename__: Issue, + TradePaperback.__tablename__: TradePaperback, + ComicWork.__tablename__: ComicWork, + IssueWork.__tablename__: IssueWork, + Article.__tablename__: Article, + BookshelfPublisher.__tablename__: BookshelfPublisher, + Book.__tablename__: Book, + Author.__tablename__: Author, + ArticleAuthor.__tablename__: ArticleAuthor, + BookAuthor.__tablename__: BookAuthor, + MediaArticle.__tablename__: MediaArticle, + MediaVideo.__tablename__: MediaVideo, + MediaLofi.__tablename__: MediaLofi, + MediaFile.__tablename__: MediaFile, + MediaActor.__tablename__: MediaActor, + MediaActorFile.__tablename__: MediaActorFile, + Profile.__tablename__: Profile, + Permission.__tablename__: Permission, + Assignment.__tablename__: Assignment, + Token.__tablename__: Token, + MailAccount.__tablename__: MailAccount, + Mail.__tablename__: Mail +} diff --git a/kontor-model/src/kontor_model/db/models/admin.py b/kontor-model/src/kontor_model/db/models/admin.py new file mode 100644 index 0000000..78dbddb --- /dev/null +++ b/kontor-model/src/kontor_model/db/models/admin.py @@ -0,0 +1,205 @@ +from datetime import datetime +from typing import Any, Dict + +from sqlalchemy import Column, ForeignKey, Integer, String, Boolean +from sqlalchemy.orm import relationship, mapped_column, Mapped + +from kontor_model.db.models.base import Base, BaseMixin + + +class Profile(Base, BaseMixin): + __tablename__ = 'profile' + first_name = Column(String) + last_name = Column(String) + user_name = Column(String, nullable=False) + email = Column(String) + password = Column(String) + enabled = Column(Boolean) + assignments = relationship("Assignment") + tokens = relationship("Token") + + def get_full_name(self) -> str: + full_name: str = "" + if self.first_name is not None: + full_name += str(self.first_name) + if self.last_name is not None: + if len(full_name) > 0: + full_name += " " + full_name += str(self.last_name) + return full_name + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.first_name = import_data['first_name'] + self.last_name = import_data['last_name'] + self.user_name = import_data['user_name'] + self.email = import_data['email'] + self.password = import_data['password'] + self.enabled = import_data['enabled'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['first_name'] = self.first_name + item['last_name'] = self.last_name + item['user_name'] = self.user_name + item['email'] = self.email + item['password'] = self.password + item['enabled'] = self.enabled + return item + + +class Token(Base, BaseMixin): + __tablename__ = "token" + token = Column(String, nullable=False, unique=True) + name = Column(String) + last_used_date: Mapped[datetime] = mapped_column() + enabled = Column(Boolean) + profile_id = Column(String, ForeignKey("profile.id"), nullable=False) + profile = relationship("Profile", back_populates="tokens") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.token = import_data['token'] + self.name = import_data['name'] + self.last_used_date = import_data['last_used_date'] + self.enabled = import_data['enabled'] + self.profile_id = import_data['profile_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['token'] = self.token + item['name'] = self.name + item['last_used_date'] = self.last_used_date + item['enabled'] = self.enabled + item['profile_id'] = self.profile_id + return item + + +class Permission(Base, BaseMixin): + __tablename__ = "permission" + name = Column(String, nullable=False) + assignments = relationship("Assignment") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['name'] = self.name + return item + +class Assignment(Base, BaseMixin): + __tablename__ = "assignment" + profile_id = Column(String, ForeignKey("profile.id"), nullable=False) + profile = relationship("Profile", back_populates="assignments") + permission_id = Column(String, ForeignKey("permission.id"), nullable=False) + permission = relationship("Permission", back_populates="assignments") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.profile_id = import_data['profile_id'] + self.permission_id = import_data['permission_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['profile_id'] = self.profile_id + item['permission_id'] = self.permission_id + return item + + +class MailAccount(Base, BaseMixin): + __tablename__ = "mail_account" + host = Column(String) + port = Column(Integer) + protocol = Column(String) + user_name = Column(String) + password = Column(String) + start_tls = Column(Boolean) + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.host = import_data['host'] + self.port = import_data['port'] + self.protocol = import_data['protocol'] + self.user_name = import_data['user_name'] + self.password = import_data['password'] + self.start_tls = import_data['start_tls'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['host'] = self.host + item['port'] = self.port + item['protocol'] = self.protocol + item['user_name'] = self.user_name + item['password'] = self.password + item['start_tls'] = self.start_tls + return item + + +class Mail(Base, BaseMixin): + __tablename__ = "mail" + folder: Mapped[str] = mapped_column() + subject: Mapped[str] = mapped_column() + body: Mapped[str] = mapped_column() + sent_date: Mapped[datetime] = mapped_column() + received_date: Mapped[datetime] = mapped_column() + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.folder = import_data['folder'] + self.subject = import_data['subject'] + self.body = import_data['body'] + self.sent_date = import_data['sent_date'] + self.received_date = import_data['received_date'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['folder'] = self.folder + item['subject'] = self.subject + item['body'] = self.body + item['sent_date'] = str(self.sent_date) + item['received_date'] = str(self.received_date) + return item diff --git a/kontor-scripts/db/models/base.py b/kontor-model/src/kontor_model/db/models/base.py similarity index 100% rename from kontor-scripts/db/models/base.py rename to kontor-model/src/kontor_model/db/models/base.py diff --git a/kontor-model/src/kontor_model/db/models/bookshelf.py b/kontor-model/src/kontor_model/db/models/bookshelf.py new file mode 100644 index 0000000..b55f429 --- /dev/null +++ b/kontor-model/src/kontor_model/db/models/bookshelf.py @@ -0,0 +1,159 @@ +from typing import Any, Dict +from sqlalchemy import Column, ForeignKey, Integer, String +from sqlalchemy.orm import relationship + +from kontor_model.db.models.base import Base, BaseMixin + + +class Article(Base, BaseMixin): + __tablename__ = 'article' + title = Column(String, unique=True) + article_authors = relationship("ArticleAuthor") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.title = import_data['title'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['title'] = self.title + return item + + +class Author(Base, BaseMixin): + __tablename__ = 'author' + first_name = Column(String) + last_name = Column(String) + article_authors = relationship("ArticleAuthor") + book_authors = relationship("BookAuthor") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.first_name = import_data['first_name'] + self.last_name = import_data['last_name'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['first_name'] = self.first_name + item['last_name'] = self.last_name + return item + + +class BookshelfPublisher(Base, BaseMixin): + __tablename__ = 'bookshelf_publisher' + name = Column(String, unique=True) + books = relationship("Book", back_populates="publisher") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['name'] = self.name + return item + + +class Book(Base, BaseMixin): + __tablename__ = 'book' + isbn = Column(String, unique=True) + title = Column(String) + year = Column(Integer, nullable=False) + publisher_id = Column(String, ForeignKey('bookshelf_publisher.id'), nullable=False) + publisher = relationship('BookshelfPublisher', back_populates="books") + book_authors = relationship("BookAuthor") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.isbn = import_data['isbn'] + self.title = import_data['title'] + self.year = import_data['year'] + self.publisher_id = import_data['publisher_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['isbn'] = self.isbn + item['title'] = self.title + item['year'] = self.year + item['publisher_id'] = self.publisher_id + return item + + +class ArticleAuthor(Base, BaseMixin): + __tablename__ = 'article_author' + article_id = Column(String, ForeignKey('article.id'), nullable=False) + article = relationship('Article', back_populates="article_authors") + author_id = Column(String, ForeignKey('author.id'), nullable=False) + author = relationship('Author', back_populates="article_authors") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.article_id = import_data['article_id'] + self.author_id = import_data['author_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['article_id'] = self.article_id + item['author_id'] = self.author_id + return item + + +class BookAuthor(Base, BaseMixin): + __tablename__ = 'book_author' + author_id = Column(String, ForeignKey('author.id'), nullable=False) + author = relationship('Author', back_populates="book_authors") + book_id = Column(String, ForeignKey('book.id'), nullable=False) + book = relationship('Book', back_populates="book_authors") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.author_id = import_data['author_id'] + self.book_id = import_data['book_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['author_id'] = self.author_id + item['book_id'] = self.book_id + return item diff --git a/kontor-model/src/kontor_model/db/models/comic.py b/kontor-model/src/kontor_model/db/models/comic.py new file mode 100644 index 0000000..136a5c0 --- /dev/null +++ b/kontor-model/src/kontor_model/db/models/comic.py @@ -0,0 +1,352 @@ +import uuid +from datetime import datetime +from typing import Dict, List, Optional, Any +from sqlalchemy import Column, ForeignKey, Integer, String, Boolean, func +from sqlalchemy.orm import relationship, Mapped, mapped_column + +from kontor_model.db.models.base import Base, BaseMixin + + +class Publisher(Base): + __tablename__ = "publisher" + id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4) + created_date: Mapped[datetime] = mapped_column(default=func.now()) + last_modified_date: Mapped[datetime] = mapped_column(default=func.now()) + version: Mapped[int] = mapped_column(default=0) + name = Column(String, unique=True) + weblink = Column(String, nullable=True) + parent_publisher_id: Mapped[Optional[str]] = mapped_column(ForeignKey('publisher.id')) + parent_publisher: Mapped[Optional['Publisher']] = relationship("Publisher", back_populates="imprints", remote_side=[id]) + imprints: Mapped[List['Publisher']] = relationship('Publisher', back_populates="parent_publisher") + comics = relationship("Comic") + + def __repr__(self): + return f'Publisher({self.id} {self.name})' + + def __str__(self): + return self.__repr__() + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + self.parent_publisher_id = import_data['parent_publisher_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = { + 'id': self.id, + 'created_date': str(self.created_date), + 'last_modified_date': str(self.last_modified_date), + 'version': self.version, + 'name': self.name, + 'weblink': self.weblink, + 'parent_publisher_id': self.parent_publisher_id + } + return item + + +class Comic(Base, BaseMixin): + __tablename__ = 'comic' + title = Column(String, unique=True) + publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False) + publisher = relationship("Publisher", back_populates="comics") + current_order = Column(Boolean) + completed = Column(Boolean) + weblink = Column(String, nullable=True) + issues = relationship("Issue") + story_arcs = relationship("StoryArc") + trade_paperbacks = relationship("TradePaperback") + volumes = relationship("Volume") + comic_works = relationship("ComicWork") + + def __repr__(self): + return f'Comic({self.id} {self.version} {self.title} {self.publisher.name})' + + def __str__(self): + return f'{self.title}({self.id})' + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.title = import_data['title'] + self.publisher_id = import_data['publisher_id'] + self.current_order = import_data['current_order'] + self.completed = import_data['completed'] + if 'weblink' in import_data: + self.weblink = import_data['weblink'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = { + 'id': self.id, + 'created_date': str(self.created_date), + 'last_modified_date': str(self.last_modified_date), + 'version': self.version, + 'title': self.title, + 'publisher_id': self.publisher_id, + 'current_order': self.current_order, + 'completed': self.completed, + 'weblink': self.weblink + } + return item + + +class Volume(Base, BaseMixin): + __tablename__ = "volume" + name = Column(String, nullable=False) + comic_id = Column(String, ForeignKey("comic.id"), nullable=False) + comic = relationship("Comic", back_populates="volumes") + story_arcs = relationship("StoryArc") + issues = relationship("Issue") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + self.comic_id = import_data['comic_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['name'] = self.name + item['comic_id'] = self.comic_id + return item + +class TradePaperback(Base, BaseMixin): + __tablename__ = "trade_paperback" + name = Column(String, nullable=False) + issue_start = Column(Integer) + issue_end = Column(Integer) + comic_id = Column(String, ForeignKey("comic.id"), nullable=False) + comic = relationship("Comic", back_populates="trade_paperbacks") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + self.issue_start = import_data['issue_start'] + self.issue_end = import_data['issue_end'] + self.comic_id = import_data['comic_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['name'] = self.name + item['issue_start'] = self.issue_start + item['issue_end'] = self.issue_end + item['comic_id'] = self.comic_id + return item + + +class StoryArc(Base, BaseMixin): + __tablename__ = "story_arc" + name = Column(String, nullable=False) + comic_id = Column(String, ForeignKey("comic.id"), nullable=False) + comic = relationship("Comic", back_populates="story_arcs") + volume_id = Column(String, ForeignKey("volume.id"), nullable=True) + volume = relationship("Volume", back_populates="story_arcs") + issues = relationship("Issue") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + self.comic_id = import_data['comic_id'] + self.volume_id = import_data['volume_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = { + 'id': self.id, + 'created_date': str(self.created_date), + 'last_modified_date': str(self.last_modified_date), + 'version': self.version, + 'name': self.name, + 'comic_id': self.comic_id, + 'volume_id': self.volume_id + } + return item + + +class Issue(Base, BaseMixin): + __tablename__ = "issue" + issue_number = Column(String) + title = Column(String, nullable=True) + published_on: Mapped[datetime] = mapped_column(nullable=True) + in_stock = Column(Boolean) + is_read = Column(Boolean) + comic_id = Column(String, ForeignKey("comic.id"), nullable=False) + comic = relationship("Comic", back_populates="issues") + volume_id = Column(String, ForeignKey("volume.id"), nullable=True) + volume = relationship("Volume", back_populates="issues") + story_arc_id = Column(String, ForeignKey("story_arc.id"), nullable=True) + story_arc = relationship("StoryArc", back_populates="issues") + issue_works = relationship("IssueWork") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.issue_number = import_data['issue_number'] + self.title = import_data['title'] + if import_data['published_on'] == 'None': + self.published_on = None # type: ignore + else: + self.published_on = import_data['published_on'] + self.in_stock = import_data['in_stock'] + self.is_read = import_data['is_read'] + self.comic_id = import_data['comic_id'] + self.volume_id = import_data['volume_id'] + self.story_arc_id = import_data['story_arc_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = { + 'id': self.id, + 'created_date': str(self.created_date), + 'last_modified_date': str(self.last_modified_date), + 'version': self.version, + 'issue_number': self.issue_number, + 'title': self.title, + 'published_on': str(self.published_on), + 'in_stock': self.in_stock, + 'is_read': self.is_read, + 'comic_id': self.comic_id, + 'volume_id': self.volume_id, + 'story_arc_id': self.story_arc_id + } + return item + + +class Artist(Base, BaseMixin): + __tablename__ = "artist" + name = Column(String, nullable=False) + weblink = Column(String, nullable=True) + comic_works = relationship("ComicWork") + issue_works = relationship("IssueWork") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + if 'weblink' in import_data: + self.weblink = import_data['weblink'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = { + 'id': self.id, + 'created_date': str(self.created_date), + 'last_modified_date': str(self.last_modified_date), + 'version': self.version, + 'name': self.name, + 'weblink': self.weblink + } + return item + + +class WorkType(Base, BaseMixin): + __tablename__ = "worktype" + name = Column(String, nullable=False, unique=True) + comic_works = relationship("ComicWork") + issue_works = relationship("IssueWork") + + def __repr__(self): + return f'Worktype({self.id} {self.version} {self.name} {len(self.comic_works)})' + + def __str__(self): + return f'{self.name}({self.id})' + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = { + 'id': self.id, + 'created_date': str(self.created_date), + 'last_modified_date': str(self.last_modified_date), + 'version': self.version, + 'name': self.name + } + return item + + +class ComicWork(Base, BaseMixin): + __tablename__ = "comic_work" + comic_id = Column(String, ForeignKey("comic.id"), nullable=False) + comic = relationship("Comic", back_populates="comic_works") + artist_id = Column(String, ForeignKey("artist.id"), nullable=False) + artist = relationship("Artist", back_populates="comic_works") + work_type_id = Column(String, ForeignKey("worktype.id"), nullable=False) + work_type = relationship("WorkType", back_populates="comic_works") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.comic_id = import_data['comic_id'] + self.artist_id = import_data['artist_id'] + self.work_type_id = import_data['work_type_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = { + 'id': self.id, + 'created_date': str(self.created_date), + 'last_modified_date': str(self.last_modified_date), + 'version': self.version, + 'comic_id': self.comic_id, + 'artist_id': self.artist_id, + 'work_type_id': self.work_type_id + } + return item + + +class IssueWork(Base, BaseMixin): + __tablename__ = "issue_work" + issue_id = Column(String, ForeignKey("issue.id"), nullable=False) + issue = relationship("Issue", back_populates="issue_works") + artist_id = Column(String, ForeignKey("artist.id"), nullable=False) + artist = relationship("Artist", back_populates="issue_works") + work_type_id = Column(String, ForeignKey("worktype.id"), nullable=False) + work_type = relationship("WorkType", back_populates="issue_works") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.issue_id = import_data['issue_id'] + self.artist_id = import_data['artist_id'] + self.work_type_id = import_data['work_type_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = { + 'id': self.id, + 'created_date': str(self.created_date), + 'last_modified_date': str(self.last_modified_date), + 'version': self.version, + 'issue_id': self.issue_id, + 'artist_id': self.artist_id, + 'work_type_id': self.work_type_id + } + return item diff --git a/kontor-model/src/kontor_model/db/models/media.py b/kontor-model/src/kontor_model/db/models/media.py new file mode 100644 index 0000000..a7678db --- /dev/null +++ b/kontor-model/src/kontor_model/db/models/media.py @@ -0,0 +1,207 @@ +from typing import Any, Dict +from sqlalchemy import Boolean, Column, String, ForeignKey +from sqlalchemy.orm import relationship + +from kontor_model.db.models.base import Base, BaseMixin, BaseVideoMixin + + +class MediaFile(Base, BaseMixin, BaseVideoMixin): + __tablename__ = 'media_file' + media_actor_files = relationship("MediaActorFile") + + def __repr__(self): + return f'MediaFile(\n\tID: {self.id}\n\tTitle: {self.title}\n\tURL: {self.url}\n\tReview: {self.review}\n\tDownload: {self.should_download}\n\tPath: {self.path}\n\tCloudlink: {self.cloud_link})' + + def __str__(self): + return f'{self.title}({self.id})' + + def update_title(self): + pass + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.cloud_link = import_data['cloud_link'] + self.file_name = import_data['file_name'] + self.path = import_data['path'] + self.review = import_data['review'] + self.title = import_data['title'] + self.url = import_data['url'] + self.should_download = import_data['should_download'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['cloud_link'] = self.cloud_link + item['file_name'] = self.file_name + item['path'] = self.path + item['review'] = self.review + item['title'] = self.title + item['url'] = self.url + item['should_download'] = self.should_download + return item + + +class MediaActor(Base, BaseMixin): + __tablename__ = 'media_actor' + name = Column(String) + url = Column(String, unique=True) + media_actor_files = relationship("MediaActorFile") + + def __repr__(self): + return f'MediaActor(\n\tID: {self.id}\n\tName: {self.name}\n\tURL: {self.url})' + + def __str__(self): + return f'{self.name}({self.id})' + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + self.url = import_data['url'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['name'] = self.name + item['url'] = self.url + return item + + +class MediaActorFile(Base, BaseMixin): + __tablename__ = 'media_actor_file' + media_actor_id = Column(String, ForeignKey("media_actor.id"), nullable=False) + media_actor = relationship("MediaActor", back_populates="media_actor_files") + media_file_id = Column(String, ForeignKey("media_file.id"), nullable=True) + media_file = relationship("MediaFile", back_populates="media_actor_files") + + def __repr__(self): + return f'MediaActorFile(\n\tID: {self.id}\n\tMediaActor: {self.media_actor_id}\n\tMediaFile: {self.media_file_id})' + + def __str__(self): + return f'{self.id}: MediaActor: {self.media_actor_id} - MediaFile: {self.media_file_id}' + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.media_actor_id = import_data['media_actor_id'] + self.media_file_id = import_data['media_file_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['media_actor_id'] = self.media_actor_id + item['media_file_id'] = self.media_file_id + return item + +class MediaArticle(Base, BaseMixin): + __tablename__ = 'media_article' + review = Column(Boolean) + title = Column(String) + url = Column(String, unique=True) + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.review = import_data['review'] + self.title = import_data['title'] + self.url = import_data['url'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['review'] = self.review + item['title'] = self.title + item['url'] = self.url + return item + + +class MediaVideo(Base, BaseMixin): + __tablename__ = 'media_video' + cloud_link = Column(String) + file_name = Column(String) + path = Column(String) + review = Column(Boolean) + title = Column(String) + url = Column(String, unique=True) + should_download = Column(Boolean) + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.cloud_link = import_data['cloud_link'] + self.file_name = import_data['file_name'] + self.path = import_data['path'] + self.review = import_data['review'] + self.title = import_data['title'] + self.url = import_data['url'] + self.should_download = import_data['should_download'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['cloud_link'] = self.cloud_link + item['file_name'] = self.file_name + item['path'] = self.path + item['review'] = self.review + item['title'] = self.title + item['url'] = self.url + item['should_download'] = self.should_download + return item + +class MediaLofi(Base, BaseMixin): + __tablename__ = 'media_lofi' + file_name = Column(String) + review = Column(Boolean) + should_download = Column(Boolean) + title = Column(String) + url = Column(String, unique=True) + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.file_name = import_data['file_name'] + self.review = import_data['review'] + self.should_download = import_data['should_download'] + self.title = import_data['title'] + self.url = import_data['url'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['file_name'] = self.file_name + item['review'] = self.review + item['should_download'] = self.should_download + item['title'] = self.title + item['url'] = self.url + return item diff --git a/kontor-model/src/kontor_model/db/models/tysc.py b/kontor-model/src/kontor_model/db/models/tysc.py new file mode 100644 index 0000000..221df0c --- /dev/null +++ b/kontor-model/src/kontor_model/db/models/tysc.py @@ -0,0 +1,259 @@ +from typing import Dict, Any +from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Boolean +from sqlalchemy.orm import relationship + +from kontor_model.db.models.base import Base, BaseMixin + + +class Sport(Base, BaseMixin): + __tablename__ = "sport" + __table_args__ = ( + UniqueConstraint("name"), + ) + name = Column(String, nullable=False, index=True, unique=True) + teams = relationship("Team") + positions = relationship("FieldPosition") + + def __repr__(self): + return f"Sport(id={self.id}, name={self.name}, created_date={self.created_date})" + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['name'] = self.name + return item + +class Team(Base, BaseMixin): + __tablename__ = "team" + name = Column(String, nullable=False, index=True, unique=True) + short_name = Column(String, nullable=False, ) + sport_id = Column(String, ForeignKey("sport.id"), nullable=False) + sport = relationship("Sport", back_populates="teams") + roosters = relationship("Rooster") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + self.short_name = import_data['short_name'] + self.sport_id = import_data['sport_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['name'] = self.name + item['short_name'] = self.short_name + item['sport_id'] = self.sport_id + return item + +class FieldPosition(Base, BaseMixin): + __tablename__ = "field_position" + __table_args__ = ( + UniqueConstraint("name", "sport_id"), + UniqueConstraint("short_name", "sport_id"), + ) + name = Column(String, nullable=False, index=True) + short_name = Column(String, nullable=False) + sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True) + sport = relationship("Sport", back_populates="positions") + roosters = relationship("Rooster") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + self.short_name = import_data['short_name'] + self.sport_id = import_data['sport_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['name'] = self.name + item['short_name'] = self.short_name + item['sport_id'] = self.sport_id + return item + + +class Player(Base, BaseMixin): + __tablename__ = "player" + __table_args__ = ( + UniqueConstraint("first_name", "last_name"), + ) + first_name = Column(String, nullable=False, index=True) + last_name = Column(String, nullable=False, index=True) + roosters = relationship("Rooster") + + def get_full_name(self) -> str: + return f"{self.last_name}, {self.first_name}" + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.first_name = import_data['first_name'] + self.last_name = import_data['last_name'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['first_name'] = self.first_name + item['last_name'] = self.last_name + return item + + +class Rooster(Base, BaseMixin): + __tablename__ = "rooster" + __table_args__ = ( + UniqueConstraint("year", "team_id", "player_id", "position_id"), + ) + year = Column(Integer) + team_id = Column(String, ForeignKey("team.id"), nullable=False, index=True) + team = relationship("Team", back_populates="roosters") + player_id = Column(String, ForeignKey("player.id"), nullable=False, index=True) + player = relationship("Player", back_populates="roosters") + position_id = Column(String, ForeignKey("field_position.id"), nullable=False, index=True) + position = relationship("FieldPosition", back_populates="roosters") + cards = relationship("Card") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.year = import_data['year'] + self.team_id = import_data['team_id'] + self.player_id = import_data['player_id'] + self.position_id = import_data['position_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['year'] = self.year + item['team_id'] = self.team_id + item['player_id'] = self.player_id + item['position_id'] = self.position_id + return item + + +class Vendor(Base, BaseMixin): + __tablename__ = "vendor" + name = Column(String, nullable=False, unique=True, index=True) + card_sets = relationship("CardSet") + cards = relationship("Card") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['name'] = self.name + return item + + +class CardSet(Base, BaseMixin): + __tablename__ = "card_set" + __table_args__ = ( + UniqueConstraint("name", "vendor_id"), + ) + name = Column(String, index=True) + parallel_set = Column(Boolean) + insert_set = Column(Boolean) + vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False, index=True) + vendor = relationship("Vendor", back_populates="card_sets") + cards = relationship("Card") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.name = import_data['name'] + self.parallel_set = import_data['parallel_set'] + self.insert_set = import_data['insert_set'] + self.vendor_id = import_data['vendor_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['name'] = self.name + item['parallel_set'] = self.parallel_set + item['insert_set'] = self.insert_set + item['vendor_id'] = self.vendor_id + return item + + +class Card(Base, BaseMixin): + __tablename__ = "card" + __table_args__ = ( + UniqueConstraint("card_number", "year", "vendor_id", "card_set_id"), + ) + card_number = Column(Integer, index=True) + year = Column(Integer, index=True) + card_set_id = Column(String, ForeignKey("card_set.id"), nullable=False) + card_set = relationship("CardSet", back_populates="cards") + rooster_id = Column(String, ForeignKey("rooster.id"), nullable=False) + rooster = relationship("Rooster", back_populates="cards") + vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False) + vendor = relationship("Vendor", back_populates="cards") + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.card_number = import_data['card_number'] + self.year = import_data['year'] + self.card_set_id = import_data['card_set_id'] + self.rooster_id = import_data['rooster_id'] + self.vendor_id = import_data['vendor_id'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['card_number'] = self.card_number + item['year'] = self.year + item['card_set_id'] = self.card_set_id + item['rooster_id'] = self.rooster_id + item['vendor_id'] = self.vendor_id + return item diff --git a/kontor-api/src/db/repository/__init__.py b/kontor-model/src/kontor_model/db/repository/__init__.py similarity index 100% rename from kontor-api/src/db/repository/__init__.py rename to kontor-model/src/kontor_model/db/repository/__init__.py diff --git a/kontor-model/src/kontor_model/db/repository/admin.py b/kontor-model/src/kontor_model/db/repository/admin.py new file mode 100644 index 0000000..bca48c7 --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/admin.py @@ -0,0 +1,18 @@ +from typing import Optional + +from sqlalchemy.orm import Session + +from kontor_model.db.models.admin import Profile + + +def get_profile_by_username(username: str, db: Session) -> Optional[Profile]: + profile = db.query(Profile).filter(Profile.user_name == username).first() + return profile + +def get_profile_by_email(email: str, db: Session) -> Optional[Profile]: + profile = db.query(Profile).filter(Profile.email == email).first() + return profile + +def is_database_empty(db: Session) -> bool: + profiles = db.query(Profile).all() + return len(profiles) == 0 diff --git a/kontor-api/src/db/repository/comics/__init__.py b/kontor-model/src/kontor_model/db/repository/comics/__init__.py similarity index 100% rename from kontor-api/src/db/repository/comics/__init__.py rename to kontor-model/src/kontor_model/db/repository/comics/__init__.py diff --git a/kontor-model/src/kontor_model/db/repository/comics/artist.py b/kontor-model/src/kontor_model/db/repository/comics/artist.py new file mode 100644 index 0000000..a2bd1f0 --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/comics/artist.py @@ -0,0 +1,54 @@ +from typing import List, Optional + +from sqlalchemy.orm import Session + +from kontor_model.db.models.comic import Artist +from kontor_model.schema.comics.artist import AddArtist +from kontor_model.schema.comics.artist_details import ArtistDetailResponse, ArtistWorktypeComicResponse, ArtistWorktypeIssueResponse +from kontor_model.schema.comics.comic import ComicResponse +from kontor_model.schema.comics.worktype import WorktypeResponse + + +def get_artist_details(artist: Artist) -> ArtistDetailResponse: + comic_works: List[ArtistWorktypeComicResponse] = [] + comic_works_map = {} + for work in artist.comic_works: + worktype_id = work.work_type.id + if worktype_id in comic_works_map: + comic = ComicResponse( + id=work.comic.id, + created_date=work.comic.created_date, + last_modified_date=work.comic.last_modified_date, + version=work.comic.version, + publisher_id=work.comic.publisher_id, + current_order=work.comic.current_order, + weblink=work.comic.weblink, + title=work.comic.title, + completed=work.comic.completed + ) + comic_works_map[worktype_id].comics.append(comic) + else: + comic_works_map[worktype_id] = ArtistWorktypeComicResponse( + worktype=WorktypeResponse(id=worktype_id, name=work.work_type.name), + comics=[ComicResponse(id=work.comic.id, title=work.comic.title, completed=work.comic.completed)] + ) + for value in comic_works_map.values(): + comic_works.append(value) + issue_works: List[ArtistWorktypeIssueResponse] = [] + response = ArtistDetailResponse( + id=artist.id, + name=str(artist.name), + weblink=str(artist.weblink), + comic_works=comic_works, + issue_works=issue_works, + ) + return response + +def update_artist(add_artist: AddArtist, artist_id: str, db: Session) -> Optional[Artist]: + artist: Optional[Artist] = db.get(Artist, artist_id) + if artist is not None: + artist.name = add_artist.name + db.add(artist) + db.commit() + db.refresh(artist) + return artist diff --git a/kontor-model/src/kontor_model/db/repository/comics/comic.py b/kontor-model/src/kontor_model/db/repository/comics/comic.py new file mode 100644 index 0000000..785f9ad --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/comics/comic.py @@ -0,0 +1,69 @@ +from typing import Dict, List, Optional + +from sqlalchemy.orm import Session + +from kontor_model.db.models.comic import Comic, Issue +from kontor_model.schema.comics.artist import artist_to_response +from kontor_model.schema.comics.comic import ComicSchema, comic_to_response +from kontor_model.schema.comics.comic_details import ComicDetailsResponse, ComicWorktypeArtistResponse +from kontor_model.schema.comics.issue import IssueResponse, issue_to_response +from kontor_model.schema.comics.issue_details import IssueDetailsResponse +from kontor_model.schema.comics.publisher import publisher_to_response +from kontor_model.schema.comics.volume import VolumeResponse, volume_to_response +from kontor_model.schema.comics.worktype import worktype_to_response + + +def get_issue_details(issue: Issue) -> IssueDetailsResponse: + volume = None + if issue.volume: + volume = volume_to_response(issue.volume) + response = IssueDetailsResponse( + id=issue.id, + issue_number=str(issue.issue_number), + in_stock=bool(issue.in_stock), + is_read=bool(issue.is_read), + comic=comic_to_response(issue.comic), + volume=volume + ) + return response + + +def update_comic(new_comic: ComicSchema, comic_id: str, db: Session) -> Optional[Comic]: + comic: Optional[Comic] = db.get(Comic, comic_id) + return comic + +def get_comic_details(comic: Comic) -> ComicDetailsResponse: + volumes: List[VolumeResponse] = [] + for volume in comic.volumes: + volumes.append(volume_to_response(volume)) + issues: List[IssueResponse] = [] + for issue in comic.issues: + issues.append(issue_to_response(issue)) + works: List[ComicWorktypeArtistResponse] = [] + works_map: Dict[str, ComicWorktypeArtistResponse] = {} + for work in comic.comic_works: + worktype_id = work.work_type.id + if worktype_id in works_map: + artist = artist_to_response(work.artist) + works_map[worktype_id].artists.append(artist) + print(f"add artist to response map: {artist} -> {works_map}") + else: + works_map[worktype_id] = ComicWorktypeArtistResponse( + worktype=worktype_to_response(work.work_type), + artists=[artist_to_response(work.artist)] + ) + for value in works_map.values(): + works.append(value) + response = ComicDetailsResponse( + id=str(comic.id), + created=str(comic.created_date), + title=str(comic.title), + completed=bool(comic.completed), + current_order=bool(comic.current_order), + weblink=str(comic.weblink), + publisher=publisher_to_response(comic.publisher), + issues=issues, + volumes=volumes, + works=works + ) + return response diff --git a/kontor-model/src/kontor_model/db/repository/comics/publisher.py b/kontor-model/src/kontor_model/db/repository/comics/publisher.py new file mode 100644 index 0000000..e0edcfb --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/comics/publisher.py @@ -0,0 +1,52 @@ +from typing import List + +from kontor_model.db.models.comic import Publisher +from kontor_model.schema.comics.comic import ComicResponse +from kontor_model.schema.comics.publisher import PublisherResponse +from kontor_model.schema.comics.publisher_details import PublisherDetailsResponse + + +def get_publisher_details(publisher: Publisher) -> PublisherDetailsResponse: + imprints: List[PublisherResponse] = [] + for imprint in publisher.imprints: + imprints.append( + PublisherResponse( + id=imprint.id, + created_date=imprint.created_date, + last_modified_date=imprint.last_modified_date, + version=imprint.version, + weblink=str(imprint.weblink), + parent_publisher_id=imprint.parent_publisher_id, + name=str(imprint.name) + ) + ) + comics: List[ComicResponse] = [] + for comic in publisher.comics: + comics.append( + ComicResponse( + id=comic.id, + created_date=comic.created_date, + last_modified_date=comic.last_modified_date, + version=comic.version, + publisher_id=comic.publisher_id, + current_order=comic.current_order, + weblink=comic.weblink, + title=comic.title, + completed=comic.completed + ) + ) + parent_publisher: PublisherResponse | None = None + if publisher.parent_publisher: + parent_publisher = PublisherResponse( + id=publisher.parent_publisher.id, + created_date=publisher.parent_publisher.created_date, + last_modified_date=publisher.parent_publisher.last_modified_date, + version=publisher.parent_publisher.version,# + weblink=str(publisher.parent_publisher.weblink), + parent_publisher_id=publisher.parent_publisher.parent_publisher_id, + name=str(publisher.parent_publisher.name) + ) + response: PublisherDetailsResponse = PublisherDetailsResponse( + id=publisher.id, name=str(publisher.name), parent_publisher=parent_publisher, imprints=imprints, comics=comics + ) + return response diff --git a/kontor-model/src/kontor_model/db/repository/comics/worktype.py b/kontor-model/src/kontor_model/db/repository/comics/worktype.py new file mode 100644 index 0000000..2d2a13f --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/comics/worktype.py @@ -0,0 +1,30 @@ +import uuid +from datetime import datetime +from typing import AnyStr, Optional + +from sqlalchemy.orm import Session + +from kontor_model.db.models.comic import WorkType +from kontor_model.schema.comics.worktype import AddWorkType + + +def create_new_worktype(work: AddWorkType, db: Session) -> WorkType: + worktype = WorkType() + worktype.id = str(uuid.uuid4()) + worktype.created_date = datetime.now() + worktype.last_modified_date = datetime.now() + worktype.name = work.worktype + db.add(worktype) + db.commit() + db.refresh(worktype) + return worktype + + +def update_worktype(work: AddWorkType, worktype_id: AnyStr, db: Session) -> Optional[WorkType]: + worktype: Optional[WorkType] = db.get(WorkType, worktype_id) + if worktype is not None: + worktype.name = work.worktype + db.add(worktype) + db.commit() + db.refresh(worktype) + return worktype diff --git a/kontor-model/src/kontor_model/db/repository/media/actor.py b/kontor-model/src/kontor_model/db/repository/media/actor.py new file mode 100644 index 0000000..9bf58b5 --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/media/actor.py @@ -0,0 +1,65 @@ +from datetime import datetime +import uuid + +from sqlalchemy.orm import Session + +from kontor_model.db.models.media import MediaActor +from kontor_model.db.repository.media.actorfile import delete_mediaactorfile +from kontor_model.schema.media.actor import MediaActorModel + + +def create_new_mediaactor(new_actor: MediaActorModel, db: Session) -> MediaActor: + print(f"create MediaActor with url {new_actor.url}") + media_actor: MediaActor = MediaActor() + media_actor.id = str(uuid.uuid4()) + if new_actor.name is not None: + media_actor.name = new_actor.name + media_actor.url = new_actor.url + media_actor.created_date = datetime.now() + media_actor.last_modified_date = datetime.now() + media_actor.version = 0 + db.add(media_actor) + db.commit() + db.refresh(media_actor) + print(f"created {media_actor}") + return media_actor + +def delete_mediaactor(db: Session, actor_id: str): + print(f"delete MediaActor with id {actor_id}") + media_actor = db.get(MediaActor, actor_id) + if media_actor is not None: + actor_files = media_actor.media_actor_files + for actor_file in actor_files: + delete_mediaactorfile(db, actorfile_id=actor_file.id) + db.refresh(media_actor) + db.delete(media_actor) + db.commit() + +def import_mediaactor(db: Session, new_actor: MediaActorModel) -> MediaActor: + """ + import MediaFile and set missing values with default ones. + """ + print("import MediaActor with %s", new_actor) + media_actor: MediaActor = MediaActor() + media_actor.id = new_actor.id + if new_actor.created_date: + media_actor.created_date = new_actor.created_date + else: + media_actor.created_date = datetime.now() + if new_actor.last_modified_date: + media_actor.last_modified_date = new_actor.last_modified_date + else: + media_actor.last_modified_date = datetime.now() + media_actor.version = new_actor.version + if new_actor.name: + media_actor.name = new_actor.name + else: + media_actor.name = "" + if new_actor.url: + media_actor.url = new_actor.url + else: + media_actor.url = "" + db.add(media_actor) + db.commit() + db.refresh(media_actor) + return media_actor diff --git a/kontor-model/src/kontor_model/db/repository/media/actorfile.py b/kontor-model/src/kontor_model/db/repository/media/actorfile.py new file mode 100644 index 0000000..04ab50c --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/media/actorfile.py @@ -0,0 +1,63 @@ +from datetime import datetime +import uuid + +from sqlalchemy.orm import Session + +from kontor_model.db.models.media import MediaActorFile +from kontor_model.schema.media.actorfile import MediaActorFileModel + + +def create_new_mediaactorfile( + db: Session, actor_id: str, file_id: str +) -> MediaActorFile: + """ + Create relation for MediaFile and MediaActor + """ + print("create MediaActorFile with actor %s and file %s", actor_id, file_id) + media_actor_file: MediaActorFile = MediaActorFile() + media_actor_file.id = str(uuid.uuid4()) + media_actor_file.created_date = datetime.now() + media_actor_file.last_modified_date = datetime.now() + media_actor_file.version = 0 + media_actor_file.media_actor_id = actor_id + media_actor_file.media_file_id = file_id + db.add(media_actor_file) + db.commit() + db.refresh(media_actor_file) + return media_actor_file + + +def delete_mediaactorfile(db: Session, actorfile_id: str): + """ + Delete relation between MediaFile and MediaActor. + """ + print("delete MediaActorFile with id %s", actorfile_id) + media_actorfile = db.get(MediaActorFile, actorfile_id) + db.delete(media_actorfile) + db.commit() + + +def import_mediaactorfile( + db: Session, new_actorfile: MediaActorFileModel +) -> MediaActorFile: + """ + Import MediaFile and set missing values with default ones. + """ + print("import MediaActorFile with %s", new_actorfile) + media_actor_file: MediaActorFile = MediaActorFile() + media_actor_file.id = new_actorfile.id + if new_actorfile.created_date: + media_actor_file.created_date = new_actorfile.created_date + else: + media_actor_file.created_date = datetime.now() + if new_actorfile.last_modified_date: + media_actor_file.last_modified_date = new_actorfile.last_modified_date + else: + media_actor_file.last_modified_date = datetime.now() + media_actor_file.version = new_actorfile.version + media_actor_file.media_actor_id = new_actorfile.media_actor_id + media_actor_file.media_file_id = new_actorfile.media_file_id + db.add(media_actor_file) + db.commit() + db.refresh(media_actor_file) + return media_actor_file diff --git a/kontor-model/src/kontor_model/db/repository/media/file.py b/kontor-model/src/kontor_model/db/repository/media/file.py new file mode 100644 index 0000000..ca99a6c --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/media/file.py @@ -0,0 +1,77 @@ +from datetime import datetime +import uuid + +from sqlalchemy.orm import Session + +from kontor_model.db.models.media import MediaFile +from kontor_model.schema.media.file import MediaFileModel + + +def create_new_mediafile(link: str, db: Session) -> MediaFile: + """ + Create MediaFile with gievne URL. + """ + print("create MediaFile with url {link}") + media_file: MediaFile = MediaFile() + media_file.id = str(uuid.uuid4()) + media_file.url = link + media_file.created_date = datetime.now() + media_file.last_modified_date = datetime.now() + media_file.version = 0 + media_file.review = True + media_file.should_download = True + db.add(media_file) + db.commit() + db.refresh(media_file) + print("created %s", media_file) + return media_file + + +def delete_mediafile(db: Session, media_file_id: str): + """ + Delete MediaFile with given ID from db. + """ + print("delete MediaFile with id %s", media_file_id) + media_file = db.get(MediaFile, media_file_id) + db.delete(media_file) + db.commit() + + +def import_mediafile(db: Session, new_file: MediaFileModel) -> MediaFile: + """ + import MediaActor and set missing values with defautl ones. + """ + print("import MediaFile with %s", new_file) + media_file: MediaFile = MediaFile() + media_file.id = new_file.id + if new_file.created_date: + media_file.created_date = new_file.created_date + else: + media_file.created_date = datetime.now() + if new_file.last_modified_date: + media_file.last_modified_date = new_file.last_modified_date + else: + media_file.last_modified_date = datetime.now() + media_file.version = new_file.version + if new_file.title: + media_file.title = new_file.title + else: + media_file.title = "" + if new_file.file_name: + media_file.file_name = new_file.file_name + else: + media_file.file_name = "" + if new_file.cloud_link: + media_file.cloud_link = new_file.cloud_link + else: + media_file.cloud_link = "" + if new_file.url: + media_file.url = new_file.url + else: + media_file.url = "" + media_file.review = new_file.review + media_file.should_download = new_file.should_download + db.add(media_file) + db.commit() + db.refresh(media_file) + return media_file diff --git a/kontor-model/src/kontor_model/db/repository/media/lofi.py b/kontor-model/src/kontor_model/db/repository/media/lofi.py new file mode 100644 index 0000000..3cdc2e3 --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/media/lofi.py @@ -0,0 +1,22 @@ +from datetime import datetime +import uuid + +from sqlalchemy.orm import Session + +from kontor_model.db.models.media import MediaLofi + + +def create_new_lofi(url: str, db: Session) -> MediaLofi: + print(url) + media_lofi = MediaLofi() + media_lofi.id = str(uuid.uuid4()) + media_lofi.url = url + media_lofi.created_date = datetime.now() + media_lofi.last_modified_date = datetime.now() + media_lofi.review = True + media_lofi.should_download = False + db.add(media_lofi) + db.commit() + db.refresh(media_lofi) + print(media_lofi) + return media_lofi diff --git a/kontor-model/src/kontor_model/db/repository/media/video.py b/kontor-model/src/kontor_model/db/repository/media/video.py new file mode 100644 index 0000000..b1196dc --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/media/video.py @@ -0,0 +1,22 @@ +from datetime import datetime +import uuid + +from sqlalchemy.orm import Session + +from kontor_model.db.models.media import MediaVideo + + +def create_new_video(url: str, db: Session) -> MediaVideo: + print(url) + media_video = MediaVideo() + media_video.id = str(uuid.uuid4()) + media_video.url = url + media_video.created_date = datetime.now() + media_video.last_modified_date = datetime.now() + media_video.review = True + media_video.should_download = True + db.add(media_video) + db.commit() + db.refresh(media_video) + print(media_video) + return media_video diff --git a/kontor-model/src/kontor_model/db/repository/user.py b/kontor-model/src/kontor_model/db/repository/user.py new file mode 100644 index 0000000..2511845 --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/user.py @@ -0,0 +1,41 @@ +from datetime import datetime +from typing import Optional +import uuid +from kontor_model.db.models.admin import Assignment, Profile +from sqlalchemy.orm import Session + +from kontor_model.schema.user.profile import ProfileModel + + +def create_new_profile(new_profile: ProfileModel, db: Session) -> Profile: + print(f"create Profile with username {new_profile.username}") + profile: Profile = Profile() + profile.id = str(uuid.uuid4()) + profile.user_name = new_profile.username + profile.first_name = new_profile.first_name + profile.last_name = new_profile.last_name + profile.created_date = datetime.now() + profile.last_modified_date = datetime.now() + profile.version = 0 + db.add(profile) + db.commit() + db.refresh(profile) + print(f"created {profile}") + return profile + +def delete_profile(db: Session, profile_id: str): + print(f"delete Profile with id {profile_id}") + profile: Optional[Profile] = db.get(Profile, profile_id) + if profile is not None: + assignments = profile.assignments + for assignment in assignments: + delete_assignment(db, assignment.id) + db.delete(profile) + db.commit() + +def delete_assignment(db: Session, assignment_id: str) -> None: + print(f"delete Assignment with id {assignment_id}") + assignment: Optional[Assignment] = db.get(Assignment, assignment_id) + if assignment is not None: + db.delete(assignment) + db.commit() diff --git a/kontor-api/src/schema/__init__.py b/kontor-model/src/kontor_model/py.typed similarity index 100% rename from kontor-api/src/schema/__init__.py rename to kontor-model/src/kontor_model/py.typed diff --git a/kontor-api/src/schema/comics/__init__.py b/kontor-model/src/kontor_model/schema/__init__.py similarity index 100% rename from kontor-api/src/schema/comics/__init__.py rename to kontor-model/src/kontor_model/schema/__init__.py diff --git a/kontor-model/src/kontor_model/schema/admin/healthcheck.py b/kontor-model/src/kontor_model/schema/admin/healthcheck.py new file mode 100644 index 0000000..1ee4e6f --- /dev/null +++ b/kontor-model/src/kontor_model/schema/admin/healthcheck.py @@ -0,0 +1,9 @@ +from pydantic import BaseModel + + +class HealthCheck(BaseModel): + """ + Health check model + """ + + status: str = "ok" diff --git a/kontor-model/src/kontor_model/schema/admin/login.py b/kontor-model/src/kontor_model/schema/admin/login.py new file mode 100644 index 0000000..f9eef3e --- /dev/null +++ b/kontor-model/src/kontor_model/schema/admin/login.py @@ -0,0 +1,8 @@ +from typing import Optional + +from pydantic import BaseModel + + +class LoginRequest(BaseModel): + email: Optional[str] = None + password: Optional[str] = None diff --git a/kontor-model/src/kontor_model/schema/admin/mailaccount.py b/kontor-model/src/kontor_model/schema/admin/mailaccount.py new file mode 100644 index 0000000..a61f914 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/admin/mailaccount.py @@ -0,0 +1,34 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.admin import MailAccount + + +class MailAccountResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + host: str + port: int + protocol: str + user_name: str + password: str + start_tls: bool + + +def to_response(account: MailAccount) -> MailAccountResponse: + response: MailAccountResponse = MailAccountResponse( + id=account.id, + created_date=account.created_date, + last_modified_date=account.last_modified_date, + version=account.version, + host=str(account.host), + port=account.port, + protocol=str(account.protocol), + user_name=str(account.user_name), + password=str(account.password), + start_tls=bool(account.start_tls), + ) + return response diff --git a/kontor-model/src/kontor_model/schema/admin/token.py b/kontor-model/src/kontor_model/schema/admin/token.py new file mode 100644 index 0000000..47b21b6 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/admin/token.py @@ -0,0 +1,13 @@ +from typing import List, Optional + +from pydantic import BaseModel + + +class Token(BaseModel): + access_token: str + token_type: str + + +class TokenData(BaseModel): + username: Optional[str] = None + scopes: List[str] = [] diff --git a/kontor-model/src/kontor_model/schema/bookshelf/article.py b/kontor-model/src/kontor_model/schema/bookshelf/article.py new file mode 100644 index 0000000..4c0bf79 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/bookshelf/article.py @@ -0,0 +1,23 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.bookshelf import Article + + +class ArticleResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + title: str + +def to_response(article: Article) -> ArticleResponse: + response: ArticleResponse = ArticleResponse( + id=article.id, + created_date=article.created_date, + last_modified_date=article.last_modified_date, + version=article.version, + title=str(article.title) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/bookshelf/articleauthor.py b/kontor-model/src/kontor_model/schema/bookshelf/articleauthor.py new file mode 100644 index 0000000..d8b6b37 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/bookshelf/articleauthor.py @@ -0,0 +1,25 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.bookshelf import ArticleAuthor + + +class ArticleAuthorResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + article_id: str + author_id: str + +def to_response(articleauthor: ArticleAuthor) -> ArticleAuthorResponse: + response: ArticleAuthorResponse = ArticleAuthorResponse( + id=articleauthor.id, + created_date=articleauthor.created_date, + last_modified_date=articleauthor.last_modified_date, + version=articleauthor.version, + article_id=str(articleauthor.article_id), + author_id=str(articleauthor.author_id) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/bookshelf/author.py b/kontor-model/src/kontor_model/schema/bookshelf/author.py new file mode 100644 index 0000000..955c805 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/bookshelf/author.py @@ -0,0 +1,25 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.bookshelf import Author + + +class AuthorResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + first_name: str + last_name: str + +def to_response(author: Author) -> AuthorResponse: + response: AuthorResponse = AuthorResponse( + id=author.id, + created_date=author.created_date, + last_modified_date=author.last_modified_date, + version=author.version, + first_name=str(author.first_name), + last_name=str(author.last_name) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/bookshelf/book.py b/kontor-model/src/kontor_model/schema/bookshelf/book.py new file mode 100644 index 0000000..26000ff --- /dev/null +++ b/kontor-model/src/kontor_model/schema/bookshelf/book.py @@ -0,0 +1,29 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.bookshelf import Book + + +class BookResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + isbn: str + title: str + year: int + publisher_id: str + +def to_response(book: Book) -> BookResponse: + response: BookResponse = BookResponse( + id=book.id, + created_date=book.created_date, + last_modified_date=book.last_modified_date, + version=book.version, + isbn=str(book.isbn), + title=str(book.title), + year=book.year, + publisher_id=str(book.publisher_id) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/bookshelf/bookauthor.py b/kontor-model/src/kontor_model/schema/bookshelf/bookauthor.py new file mode 100644 index 0000000..4ef95fe --- /dev/null +++ b/kontor-model/src/kontor_model/schema/bookshelf/bookauthor.py @@ -0,0 +1,25 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.bookshelf import BookAuthor + + +class BookAuthorResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + author_id: str + book_id: str + +def to_response(bookauthor: BookAuthor) -> BookAuthorResponse: + response: BookAuthorResponse = BookAuthorResponse( + id=bookauthor.id, + created_date=bookauthor.created_date, + last_modified_date=bookauthor.last_modified_date, + version=bookauthor.version, + author_id=str(bookauthor.author_id), + book_id=str(bookauthor.book_id) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/bookshelf/publisher.py b/kontor-model/src/kontor_model/schema/bookshelf/publisher.py new file mode 100644 index 0000000..28b0b9e --- /dev/null +++ b/kontor-model/src/kontor_model/schema/bookshelf/publisher.py @@ -0,0 +1,23 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.bookshelf import BookshelfPublisher + + +class PublisherResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: str + +def to_response(publisher: BookshelfPublisher) -> PublisherResponse: + response: PublisherResponse = PublisherResponse( + id=publisher.id, + created_date=publisher.created_date, + last_modified_date=publisher.last_modified_date, + version=publisher.version, + name=str(publisher.name) + ) + return response diff --git a/kontor-api/src/schema/media/__init__.py b/kontor-model/src/kontor_model/schema/comics/__init__.py similarity index 100% rename from kontor-api/src/schema/media/__init__.py rename to kontor-model/src/kontor_model/schema/comics/__init__.py diff --git a/kontor-model/src/kontor_model/schema/comics/artist.py b/kontor-model/src/kontor_model/schema/comics/artist.py new file mode 100644 index 0000000..58c68e6 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/artist.py @@ -0,0 +1,35 @@ +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel + +from kontor_model.db.models.comic import Artist + + +class ArtistCreation(BaseModel): + id: str + name: str + +class ArtistResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: str + weblink: Optional[str] + +def artist_to_response(artist: Artist) -> ArtistResponse: + response: ArtistResponse = ArtistResponse( + id=artist.id, + created_date=artist.created_date, + last_modified_date=artist.last_modified_date, + version=artist.version, + name=artist.name, + weblink=artist.weblink + ) + return response + + +class AddArtist(BaseModel): + id: str + name: str diff --git a/kontor-model/src/kontor_model/schema/comics/artist_details.py b/kontor-model/src/kontor_model/schema/comics/artist_details.py new file mode 100644 index 0000000..0686c75 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/artist_details.py @@ -0,0 +1,22 @@ +from typing import List +from pydantic import BaseModel + +from kontor_model.schema.comics.comic import ComicResponse +from kontor_model.schema.comics.issue_details import IssueDetailsResponse +from kontor_model.schema.comics.worktype import WorktypeResponse + + +class ArtistWorktypeComicResponse(BaseModel): + worktype: WorktypeResponse + comics: List[ComicResponse] + +class ArtistWorktypeIssueResponse(BaseModel): + worktype: WorktypeResponse + issues: List[IssueDetailsResponse] + +class ArtistDetailResponse(BaseModel): + id: str + name: str + weblink: str + comic_works: List[ArtistWorktypeComicResponse] + issue_works: List[ArtistWorktypeIssueResponse] diff --git a/kontor-model/src/kontor_model/schema/comics/comic.py b/kontor-model/src/kontor_model/schema/comics/comic.py new file mode 100644 index 0000000..35d7119 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/comic.py @@ -0,0 +1,48 @@ +""" +Schema definitions for Comics. +""" +from datetime import datetime +from typing import Optional +from pydantic import BaseModel, AnyUrl + +from kontor_model.db.models.comic import Comic + + +class ComicResponse(BaseModel): + """ + Pydantic model for returning Comic objects. + """ + id: str + created_date: datetime + last_modified_date: datetime + version: int + title: str + publisher_id: str + current_order: bool + completed: bool + weblink: Optional[str] + +def comic_to_response(comic: Comic) -> ComicResponse: + response: ComicResponse = ComicResponse( + id=comic.id, + created_date=comic.created_date, + last_modified_date=comic.last_modified_date, + version=comic.version, + title=str(comic.title), + publisher_id=str(comic.publisher_id), + current_order=bool(comic.current_order), + completed=bool(comic.completed), + weblink=str(comic.weblink) + ) + return response + + +class ComicSchema(BaseModel): + """ + Pydantic model for uploading Comic object. + """ + id: str + title: str + weblink: Optional[AnyUrl] + completed: Optional[bool] + current_order: Optional[bool] diff --git a/kontor-model/src/kontor_model/schema/comics/comic_details.py b/kontor-model/src/kontor_model/schema/comics/comic_details.py new file mode 100644 index 0000000..0108ccb --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/comic_details.py @@ -0,0 +1,26 @@ +from typing import List +from pydantic import BaseModel + +from kontor_model.schema.comics.artist import ArtistResponse +from kontor_model.schema.comics.issue import IssueResponse +from kontor_model.schema.comics.publisher import PublisherResponse +from kontor_model.schema.comics.volume import VolumeResponse +from kontor_model.schema.comics.worktype import WorktypeResponse + + +class ComicWorktypeArtistResponse(BaseModel): + worktype: WorktypeResponse + artists: List[ArtistResponse] + + +class ComicDetailsResponse(BaseModel): + id: str + created: str + title: str + completed : bool + current_order : bool + weblink: str + publisher: PublisherResponse + issues: List[IssueResponse] + volumes: List[VolumeResponse] + works: List[ComicWorktypeArtistResponse] diff --git a/kontor-model/src/kontor_model/schema/comics/comicwork.py b/kontor-model/src/kontor_model/schema/comics/comicwork.py new file mode 100644 index 0000000..996bb2b --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/comicwork.py @@ -0,0 +1,32 @@ +""" +Model definitions for ComicWork. +""" + +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.comic import ComicWork + + +class ComicWorkResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + comic_id: str + artist_id: str + work_type_id: str + + +def comicwork_to_response(comicwork: ComicWork) -> ComicWorkResponse: + response: ComicWorkResponse = ComicWorkResponse( + id=comicwork.id, + created_date=comicwork.created_date, + last_modified_date=comicwork.last_modified_date, + version=comicwork.version, + comic_id=str(comicwork.comic_id), + artist_id=str(comicwork.artist_id), + work_type_id=str(comicwork.work_type_id), + ) + return response diff --git a/kontor-model/src/kontor_model/schema/comics/issue.py b/kontor-model/src/kontor_model/schema/comics/issue.py new file mode 100644 index 0000000..1a1bec9 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/issue.py @@ -0,0 +1,38 @@ +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel + +from kontor_model.db.models.comic import Issue + + +class IssueResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + issue_number: str + title: Optional[str] + published_on: Optional[datetime] + in_stock: bool + is_read: bool + comic_id: str + volume_id: Optional[str] + story_arc_id: Optional[str] + +def issue_to_response(issue: Issue) -> IssueResponse: + response: IssueResponse = IssueResponse( + id=issue.id, + created_date=issue.created_date, + last_modified_date=issue.last_modified_date, + version=issue.version, + issue_number=str(issue.issue_number), + title=str(issue.title), + published_on=issue.published_on, + in_stock=bool(issue.in_stock), + is_read=bool(issue.is_read), + comic_id=str(issue.comic_id), + volume_id=str(issue.volume_id), + story_arc_id=str(issue.story_arc_id) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/comics/issue_details.py b/kontor-model/src/kontor_model/schema/comics/issue_details.py new file mode 100644 index 0000000..01aca40 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/issue_details.py @@ -0,0 +1,14 @@ +from pydantic import BaseModel + +from kontor_model.schema.comics.comic import ComicResponse +from kontor_model.schema.comics.volume import VolumeResponse + + +class IssueDetailsResponse(BaseModel): + id: str + issue_number: str + in_stock: bool + is_read: bool + comic: ComicResponse + volume: VolumeResponse | None + diff --git a/kontor-model/src/kontor_model/schema/comics/issuework.py b/kontor-model/src/kontor_model/schema/comics/issuework.py new file mode 100644 index 0000000..4403e11 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/issuework.py @@ -0,0 +1,32 @@ +""" +Model definitions for IssueWork. +""" + +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.comic import IssueWork + + +class IssueWorkResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + issue_id: str + artist_id: str + work_type_id: str + + +def issuework_to_response(issuework: IssueWork) -> IssueWorkResponse: + response: IssueWorkResponse = IssueWorkResponse( + id=issuework.id, + created_date=issuework.created_date, + last_modified_date=issuework.last_modified_date, + version=issuework.version, + issue_id=str(issuework.issue_id), + artist_id=str(issuework.artist_id), + work_type_id=str(issuework.work_type_id), + ) + return response diff --git a/kontor-model/src/kontor_model/schema/comics/publisher.py b/kontor-model/src/kontor_model/schema/comics/publisher.py new file mode 100644 index 0000000..2a6a275 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/publisher.py @@ -0,0 +1,30 @@ +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel + +from kontor_model.db.models.comic import Publisher + + +class PublisherResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: str + weblink: Optional[str] + parent_publisher_id: Optional[str] + + +def publisher_to_response(publisher: Publisher) -> PublisherResponse: + response: PublisherResponse = PublisherResponse( + id=publisher.id, + created_date=publisher.created_date, + last_modified_date=publisher.last_modified_date, + version=publisher.version, + name=str(publisher.name), + weblink=str(publisher.weblink), + parent_publisher_id=publisher.parent_publisher_id + ) + return response + diff --git a/kontor-model/src/kontor_model/schema/comics/publisher_details.py b/kontor-model/src/kontor_model/schema/comics/publisher_details.py new file mode 100644 index 0000000..ebb1fc7 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/publisher_details.py @@ -0,0 +1,14 @@ +from typing import List + +from pydantic import BaseModel + +from kontor_model.schema.comics.comic import ComicResponse +from kontor_model.schema.comics.publisher import PublisherResponse + + +class PublisherDetailsResponse(BaseModel): + id: str + name: str + parent_publisher: PublisherResponse | None + imprints: List[PublisherResponse] + comics: List[ComicResponse] diff --git a/kontor-model/src/kontor_model/schema/comics/storyarc.py b/kontor-model/src/kontor_model/schema/comics/storyarc.py new file mode 100644 index 0000000..033daa8 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/storyarc.py @@ -0,0 +1,30 @@ +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel + +from kontor_model.db.models.comic import StoryArc + +class StoryArcResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: str + comic_id: str + volume_id: Optional[str] + +class AddLink(BaseModel): + url: str + +def storyarc_to_response(storyarc: StoryArc) -> StoryArcResponse: + response: StoryArcResponse = StoryArcResponse( + id=storyarc.id, + created_date=storyarc.created_date, + last_modified_date=storyarc.last_modified_date, + version=storyarc.version, + name=str(storyarc.name), + comic_id=str(storyarc.comic_id), + volume_id=str(storyarc.volume_id) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/comics/volume.py b/kontor-model/src/kontor_model/schema/comics/volume.py new file mode 100644 index 0000000..260d79f --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/volume.py @@ -0,0 +1,25 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.comic import Volume + + +class VolumeResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: str + comic_id: str + +def volume_to_response(volume: Volume) -> VolumeResponse: + response: VolumeResponse = VolumeResponse( + id=volume.id, + created_date=volume.created_date, + last_modified_date=volume.last_modified_date, + version=volume.version, + name=str(volume.name), + comic_id=str(volume.comic_id) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/comics/worktype.py b/kontor-model/src/kontor_model/schema/comics/worktype.py new file mode 100644 index 0000000..174bd34 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/comics/worktype.py @@ -0,0 +1,26 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.comic import WorkType + +class AddWorkType(BaseModel): + worktype: str + +class WorktypeResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: str + + +def worktype_to_response(worktype: WorkType) -> WorktypeResponse: + response: WorktypeResponse = WorktypeResponse( + id=worktype.id, + created_date=worktype.created_date, + last_modified_date=worktype.last_modified_date, + version=worktype.version, + name=str(worktype.name) + ) + return response diff --git a/kontor-api/src/schema/tysc/__init__.py b/kontor-model/src/kontor_model/schema/media/__init__.py similarity index 100% rename from kontor-api/src/schema/tysc/__init__.py rename to kontor-model/src/kontor_model/schema/media/__init__.py diff --git a/kontor-model/src/kontor_model/schema/media/actor.py b/kontor-model/src/kontor_model/schema/media/actor.py new file mode 100644 index 0000000..98d4151 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/media/actor.py @@ -0,0 +1,34 @@ +from datetime import datetime +from typing import Optional +from pydantic import BaseModel + +from kontor_model.db.models.media import MediaActor + + +class MediaActorResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: Optional[str] + url: Optional[str] + +def actor_to_response(actor: MediaActor) -> MediaActorResponse: + response: MediaActorResponse = MediaActorResponse( + id=actor.id, + created_date=actor.created_date, + last_modified_date=actor.last_modified_date, + version=actor.version, + name=str(actor.name), + url=str(actor.url) + ) + return response + + +class MediaActorModel(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: Optional[str] + url: Optional[str] diff --git a/kontor-model/src/kontor_model/schema/media/actorfile.py b/kontor-model/src/kontor_model/schema/media/actorfile.py new file mode 100644 index 0000000..968b875 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/media/actorfile.py @@ -0,0 +1,35 @@ +from datetime import datetime +from typing import Optional + +from kontor_model.db.models.media import MediaActorFile +from pydantic import BaseModel + + +class MediaActorFileResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + media_actor_id: str + media_file_id: Optional[str] + +def actorfile_to_response(actorfile: MediaActorFile) -> MediaActorFileResponse: + response: MediaActorFileResponse = MediaActorFileResponse( + id=actorfile.id, + created_date=actorfile.created_date, + last_modified_date=actorfile.last_modified_date, + version=actorfile.version, + media_actor_id=str(actorfile.media_actor_id), + media_file_id=str(actorfile.media_file_id) + ) + return response + + +class MediaActorFileModel(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + media_actor_id: str + media_file_id: Optional[str] + \ No newline at end of file diff --git a/kontor-model/src/kontor_model/schema/media/article.py b/kontor-model/src/kontor_model/schema/media/article.py new file mode 100644 index 0000000..5705cbf --- /dev/null +++ b/kontor-model/src/kontor_model/schema/media/article.py @@ -0,0 +1,30 @@ +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel + +from kontor_model.db.models.media import MediaArticle + +class MediaArticleResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + review: bool = False + title: Optional[str] = None + url: Optional[str] = None + +class AddLink(BaseModel): + url: str + +def to_response(video: MediaArticle) -> MediaArticleResponse: + response: MediaArticleResponse = MediaArticleResponse( + id=video.id, + created_date=video.created_date, + last_modified_date=video.last_modified_date, + version=video.version, + review=bool(video.review), + title=str(video.title), + url=str(video.url), + ) + return response diff --git a/kontor-model/src/kontor_model/schema/media/file.py b/kontor-model/src/kontor_model/schema/media/file.py new file mode 100644 index 0000000..c687afb --- /dev/null +++ b/kontor-model/src/kontor_model/schema/media/file.py @@ -0,0 +1,81 @@ +from datetime import datetime +from typing import Optional + +from kontor_model.db.models.media import MediaFile +from pydantic import BaseModel + + +class MediaFileResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + title: Optional[str] + file_name: Optional[str] + cloud_link: Optional[str] + url: Optional[str] + review: bool = False + should_download: bool = False + + +def file_to_response(mediafile: MediaFile) -> MediaFileResponse: + """ + Create MediaFileResponse from model. + """ + response: MediaFileResponse = MediaFileResponse( + id=mediafile.id, + created_date=mediafile.created_date, + last_modified_date=mediafile.last_modified_date, + version=mediafile.version, + title=mediafile.title, + file_name=mediafile.file_name, + cloud_link=mediafile.cloud_link, + url=mediafile.url, + review=mediafile.review, + should_download=mediafile.should_download, + ) + return response + + +def file_to_model(model: MediaFileResponse, mediafile: MediaFile) -> MediaFile: + """ + Set data of response to model. + """ + mediafile.file_name = model.file_name + mediafile.cloud_link = model.cloud_link + if model.url is not None: + mediafile.url = model.url + else: + mediafile.url = "" + if model.title is not None: + mediafile.title = model.title + else: + mediafile.title = "" + mediafile.last_modified_date = datetime.now() + mediafile.review = model.review + mediafile.should_download = model.should_download + return mediafile + + +class MediaFileModel(BaseModel): + """ + Pydantic model to import MediaFile. + """ + id: str + created_date: Optional[datetime] + last_modified_date: Optional[datetime] + version: int = 0 + title: Optional[str] + file_name: Optional[str] + cloud_link: Optional[str] + url: Optional[str] + review: bool = True + should_download: bool = True + + +class Link(BaseModel): + """ + PYdantic model for uploading url. + """ + + url: str diff --git a/kontor-model/src/kontor_model/schema/media/lofi.py b/kontor-model/src/kontor_model/schema/media/lofi.py new file mode 100644 index 0000000..831b805 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/media/lofi.py @@ -0,0 +1,33 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.media import MediaLofi + +class MediaLofiResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + file_name: str = "" + review: bool = False + should_download: bool = False + title: str = "" + url: str = "" + +class AddLofi(BaseModel): + url: str + +def lofi_to_response(lofi: MediaLofi) -> MediaLofiResponse: + response: MediaLofiResponse = MediaLofiResponse( + id=lofi.id, + created_date=lofi.created_date, + last_modified_date=lofi.last_modified_date, + version=lofi.version, + file_name=str(lofi.file_name), + review=bool(lofi.review), + should_download=bool(lofi.should_download), + title=str(lofi.title), + url=str(lofi.url), + ) + return response diff --git a/kontor-model/src/kontor_model/schema/media/video.py b/kontor-model/src/kontor_model/schema/media/video.py new file mode 100644 index 0000000..5f23152 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/media/video.py @@ -0,0 +1,38 @@ +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel + +from kontor_model.db.models.media import MediaVideo + +class MediaVideoResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + cloud_link: Optional[str] = None + file_name: Optional[str] = None + path: Optional[str] = None + review: bool = False + title: Optional[str] = None + url: Optional[str] = None + should_download: bool = False + +class AddLink(BaseModel): + url: str + +def video_to_response(video: MediaVideo) -> MediaVideoResponse: + response: MediaVideoResponse = MediaVideoResponse( + id=video.id, + created_date=video.created_date, + last_modified_date=video.last_modified_date, + version=video.version, + cloud_link=str(video.cloud_link), + file_name=str(video.file_name), + path=str(video.path), + review=bool(video.review), + title=str(video.title), + url=str(video.url), + should_download=bool(video.should_download) + ) + return response diff --git a/kontor-gui/gui/__init__.py b/kontor-model/src/kontor_model/schema/tysc/__init__.py similarity index 100% rename from kontor-gui/gui/__init__.py rename to kontor-model/src/kontor_model/schema/tysc/__init__.py diff --git a/kontor-model/src/kontor_model/schema/tysc/card.py b/kontor-model/src/kontor_model/schema/tysc/card.py new file mode 100644 index 0000000..9dc592c --- /dev/null +++ b/kontor-model/src/kontor_model/schema/tysc/card.py @@ -0,0 +1,31 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.tysc import Card + + +class CardResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + card_number: int + year: int + card_set_id: str + rooster_id: str + vendor_id: str + +def to_response(card: Card) -> CardResponse: + response: CardResponse = CardResponse( + id=card.id, + created_date=card.created_date, + last_modified_date=card.last_modified_date, + version=card.version, + card_number=card.card_number, + year=card.year, + card_set_id=str(card.card_set_id), + rooster_id=str(card.rooster_id), + vendor_id=str(card.vendor_id) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/tysc/cardset.py b/kontor-model/src/kontor_model/schema/tysc/cardset.py new file mode 100644 index 0000000..131ed68 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/tysc/cardset.py @@ -0,0 +1,30 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.tysc import CardSet + + +class CardSetResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: str + parallel_set: bool + insert_set: bool + vendor_id: str + + +def to_response(cardset: CardSet) -> CardSetResponse: + response: CardSetResponse = CardSetResponse( + id=cardset.id, + created_date=cardset.created_date, + last_modified_date=cardset.last_modified_date, + version=cardset.version, + name=str(cardset.name), + parallel_set=bool(cardset.parallel_set), + insert_set=bool(cardset.insert_set), + vendor_id=str(cardset.vendor_id) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/tysc/fieldposition.py b/kontor-model/src/kontor_model/schema/tysc/fieldposition.py new file mode 100644 index 0000000..9fc06e2 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/tysc/fieldposition.py @@ -0,0 +1,28 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.tysc import FieldPosition + + +class FieldPositionResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: str + short_name: str + sport_id: str + + +def to_response(fieldposition: FieldPosition) -> FieldPositionResponse: + response: FieldPositionResponse = FieldPositionResponse( + id=fieldposition.id, + created_date=fieldposition.created_date, + last_modified_date=fieldposition.last_modified_date, + version=fieldposition.version, + name=str(fieldposition.name), + short_name=str(fieldposition.short_name), + sport_id=str(fieldposition.sport_id) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/tysc/player.py b/kontor-model/src/kontor_model/schema/tysc/player.py new file mode 100644 index 0000000..dc7842a --- /dev/null +++ b/kontor-model/src/kontor_model/schema/tysc/player.py @@ -0,0 +1,25 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.tysc import Player + + +class PlayerResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + first_name: str + last_name: str + +def to_response(player: Player) -> PlayerResponse: + response: PlayerResponse = PlayerResponse( + id=player.id, + created_date=player.created_date, + last_modified_date=player.last_modified_date, + version=player.version, + first_name=str(player.first_name), + last_name=str(player.last_name) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/tysc/rooster.py b/kontor-model/src/kontor_model/schema/tysc/rooster.py new file mode 100644 index 0000000..b2df4b8 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/tysc/rooster.py @@ -0,0 +1,36 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.tysc import Rooster + + +class RoosterResponse(BaseModel): + """ + Pydantic model for returning Rooster objects. + """ + id: str + created_date: datetime + last_modified_date: datetime + version: int + year: int + team_id: str + player_id: str + position_id: str + + +def to_response(rooster: Rooster) -> RoosterResponse: + """ + convert database object to response object (Pydantic). + """ + response: RoosterResponse = RoosterResponse( + id=rooster.id, + created_date=rooster.created_date, + last_modified_date=rooster.last_modified_date, + version=rooster.version, + year=rooster.year, + team_id=str(rooster.team_id), + player_id=str(rooster.player_id), + position_id=str(rooster.position_id) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/tysc/sport.py b/kontor-model/src/kontor_model/schema/tysc/sport.py new file mode 100644 index 0000000..6d018df --- /dev/null +++ b/kontor-model/src/kontor_model/schema/tysc/sport.py @@ -0,0 +1,24 @@ + +from datetime import datetime +from pydantic import BaseModel + +from kontor_model.db.models.tysc import Sport + + +class SportResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: str + + +def to_response(sport: Sport) -> SportResponse: + response: SportResponse = SportResponse( + id=sport.id, + created_date=sport.created_date, + last_modified_date=sport.last_modified_date, + version=sport.version, + name=str(sport.name) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/tysc/team.py b/kontor-model/src/kontor_model/schema/tysc/team.py new file mode 100644 index 0000000..cc69b59 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/tysc/team.py @@ -0,0 +1,28 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.tysc import Team + + +class TeamResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: str + short_name: str + sport_id: str + + +def to_response(team: Team) -> TeamResponse: + response: TeamResponse = TeamResponse( + id=team.id, + created_date=team.created_date, + last_modified_date=team.last_modified_date, + version=team.version, + name=str(team.name), + short_name=str(team.short_name), + sport_id=str(team.sport_id) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/tysc/vendor.py b/kontor-model/src/kontor_model/schema/tysc/vendor.py new file mode 100644 index 0000000..a5e8954 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/tysc/vendor.py @@ -0,0 +1,32 @@ +""" +class and function for json response objects for Vendor. +""" +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.tysc import Vendor + + +class VendorResponse(BaseModel): + """ + Pydantic model for Vendor reponse object. + """ + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: str + +def to_response(vendor: Vendor) -> VendorResponse: + """ + convert database object Vendor to response object VendorResponse. + """ + reponse: VendorResponse = VendorResponse( + id=vendor.id, + created_date=vendor.created_date, + last_modified_date=vendor.last_modified_date, + version=vendor.version, + name=str(vendor.name) + ) + return reponse diff --git a/kontor-model/src/kontor_model/schema/user/assignment.py b/kontor-model/src/kontor_model/schema/user/assignment.py new file mode 100644 index 0000000..5a61b05 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/user/assignment.py @@ -0,0 +1,26 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.admin import Assignment + + +class AssignmentResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + profile_id: str + permission_id: str + + +def to_response(assignment: Assignment) -> AssignmentResponse: + response: AssignmentResponse = AssignmentResponse( + id=assignment.id, + created_date=assignment.created_date, + last_modified_date=assignment.last_modified_date, + version=assignment.version, + profile_id=str(assignment.profile_id), + permission_id=str(assignment.permission_id) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/user/permission.py b/kontor-model/src/kontor_model/schema/user/permission.py new file mode 100644 index 0000000..18ab3b4 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/user/permission.py @@ -0,0 +1,24 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.admin import Permission + + +class PermissionResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + name: str + + +def to_response(permission: Permission) -> PermissionResponse: + response: PermissionResponse = PermissionResponse( + id=permission.id, + created_date=permission.created_date, + last_modified_date=permission.last_modified_date, + version=permission.version, + name=str(permission.name) + ) + return response diff --git a/kontor-model/src/kontor_model/schema/user/profile.py b/kontor-model/src/kontor_model/schema/user/profile.py new file mode 100644 index 0000000..7bb21a6 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/user/profile.py @@ -0,0 +1,50 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.admin import Profile + + +class ProfileResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + first_name: str + last_name: str + user_name: str + email: str + password: str + enabled: bool + +def to_response(profile: Profile) -> ProfileResponse: + response: ProfileResponse = ProfileResponse( + id=profile.id, + created_date=profile.created_date, + last_modified_date=profile.last_modified_date, + version=profile.version, + first_name=str(profile.first_name), + last_name=str(profile.last_name), + user_name=str(profile.user_name), + email=str(profile.email), + password=str(profile.password), + enabled=bool(profile.enabled) + ) + return response + +class ProfileModel(BaseModel): + username: str + email: str + first_name: str + last_name: str + active: bool + +def to_model(profile: Profile) -> ProfileModel: + model: ProfileModel = ProfileModel( + username=profile.user_name, + email=profile.email, + first_name=profile.first_name, + last_name=profile.last_name, + active=profile.enabled, + ) + return model diff --git a/kontor-model/src/kontor_model/schema/user/token.py b/kontor-model/src/kontor_model/schema/user/token.py new file mode 100644 index 0000000..e26409c --- /dev/null +++ b/kontor-model/src/kontor_model/schema/user/token.py @@ -0,0 +1,32 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.admin import Token + + +class TokenResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + token: str + name: str + last_used_date: datetime + enabled: bool + profile_id: str + + +def to_response(token: Token) -> TokenResponse: + response: TokenResponse = TokenResponse( + id=token.id, + created_date=token.created_date, + last_modified_date=token.last_modified_date, + version=token.version, + token=str(token.token), + name=str(token.name), + last_used_date=token.last_used_date, + enabled=bool(token.enabled), + profile_id=str(token.profile_id) + ) + return response diff --git a/kontor-model/uv.lock b/kontor-model/uv.lock new file mode 100644 index 0000000..0193f92 --- /dev/null +++ b/kontor-model/uv.lock @@ -0,0 +1,317 @@ +version = 1 +revision = 3 +requires-python = ">=3.13" + +[[package]] +name = "annotated-types" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/56/a8120250d128bed162cd73c76d45f6ef9991f3e068f62a8ee060afa3104a/annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7", size = 15893, upload-time = "2026-07-23T20:16:13.995Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/91/8acff4f5e50511b911bbccb72b8628a49c68ce14148cd9f6431094859a90/annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0", size = 13427, upload-time = "2026-07-23T20:16:12.938Z" }, +] + +[[package]] +name = "dnspython" +version = "2.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251, upload-time = "2025-09-07T18:58:00.022Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, +] + +[[package]] +name = "email-validator" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dnspython" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238, upload-time = "2025-08-26T13:09:06.831Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" }, +] + +[[package]] +name = "greenlet" +version = "3.5.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/d8/7cc97c142388aef03f622e001c572c4f84e9252a439549d483f555771970/greenlet-3.5.5.tar.gz", hash = "sha256:adb4bae02e91a8e863e48b177e4014bdcac8a6b5e047ea1df687a61534b85e6c", size = 207585, upload-time = "2026-08-10T15:09:36.136Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/3d/8cef5f724ec0d4add2af8961d504535ec60c3cca9e464f6d03bdba29d85b/greenlet-3.5.5-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:b79fd2a5bc099b5e744f34c4c9a58954a5f4cb7529fb4b6e8446057d61b6edaa", size = 294730, upload-time = "2026-08-10T13:27:51.206Z" }, + { url = "https://files.pythonhosted.org/packages/88/4b/8e7aa3f514273aecff30a16ab1bac09ff54cfc7e6860fdd8058c37ff2499/greenlet-3.5.5-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:634cf15a233a949136879dd388e25d3296e16f3f1e217d2456797b8579ebc6ed", size = 614536, upload-time = "2026-08-10T14:14:36.589Z" }, + { url = "https://files.pythonhosted.org/packages/85/48/4e95e9dd5a8a397dc6a6345dd7f1935113d0fca4f85e89d3976da9cd988d/greenlet-3.5.5-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:499adea519f748407fc6806d20eedabac2884fd73b9f38d81236e190ba20dfef", size = 626924, upload-time = "2026-08-10T14:27:27.048Z" }, + { url = "https://files.pythonhosted.org/packages/89/5d/398a1c71fa7a277deeb376c999979de6786f08fc2d5747a0b9d6e11738dd/greenlet-3.5.5-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2eabb980975cba5b93a95f6f69287d05fc05ac955bfd6a320a7c083eeb52c0b0", size = 623906, upload-time = "2026-08-10T13:40:50.501Z" }, + { url = "https://files.pythonhosted.org/packages/04/1b/745450fc5ea9e0cb17d840d248f284db3363de736d362c7d2d883e3eadba/greenlet-3.5.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:03115c2e0a371999bf8ae616aa8d653f96641d4705c457aebaa187276e9f7537", size = 1581430, upload-time = "2026-08-10T14:15:06.853Z" }, + { url = "https://files.pythonhosted.org/packages/d4/29/d51b296e3191bb15d3d81ec375af1909e4466c0f395d744ed475801798a9/greenlet-3.5.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4441153ffba21b90d3ca89fe3d31f5c093ae6c0bf0cfdfc98f54cde22f95b62e", size = 1645684, upload-time = "2026-08-10T13:40:32.133Z" }, + { url = "https://files.pythonhosted.org/packages/12/63/369f1a1625e64e9e31df3963c6044056e3fdfa3fa3fdba3c54ffefa6e987/greenlet-3.5.5-cp313-cp313-win_amd64.whl", hash = "sha256:95c5b1f4b3a193f8a0c2de4bfdcb48d119f7f1063941f1de1f2168051b3e52dd", size = 324075, upload-time = "2026-08-10T13:26:58.974Z" }, + { url = "https://files.pythonhosted.org/packages/45/78/649cb5c09d4d81f6dd1444e75474a7206784743283a21d24171562ac4899/greenlet-3.5.5-cp313-cp313-win_arm64.whl", hash = "sha256:1af90aa4bc129883b340cdd6957a3bc74f60528a4993bbd1f53aaebe1d9981cc", size = 308260, upload-time = "2026-08-10T13:27:50.795Z" }, + { url = "https://files.pythonhosted.org/packages/7f/8c/080e881fa2be95ff1ddbd6994b2bab3b1a78df3b3fcab39306011764fcc7/greenlet-3.5.5-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:d4a389a852e392a6366058651a20fa5ba40d979865aa81bea2ccbdc44805070d", size = 295309, upload-time = "2026-08-10T13:26:03.032Z" }, + { url = "https://files.pythonhosted.org/packages/25/cc/0ac614e6586c0e42d4cc281a5819150f4f43685744a4c5ff77139286409d/greenlet-3.5.5-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70b157cd319873e8b544ddc2de158f55bbd0a9b0218c8ce9332039801518e328", size = 661185, upload-time = "2026-08-10T14:14:37.867Z" }, + { url = "https://files.pythonhosted.org/packages/5e/b9/6808725354be8ad305dfe5172377664fc9642d4fc043be246b3314cf4482/greenlet-3.5.5-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8bdfd1424abcf26832961e766570cae79efdb9599d709088c9cb6ef82b194926", size = 673419, upload-time = "2026-08-10T14:27:28.652Z" }, + { url = "https://files.pythonhosted.org/packages/42/2e/40c509967da7f254680826a2fa0dd22138ec79946c70b97542d74cde8b43/greenlet-3.5.5-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:182de51c6b572a705f2fafaab2e783bcf7d2760940229dfe73086cbae037af3e", size = 670822, upload-time = "2026-08-10T13:40:51.833Z" }, + { url = "https://files.pythonhosted.org/packages/2d/22/c3c2eee4a8fe191d6d1d183086c56133d646024e3d70bfd414829f64560b/greenlet-3.5.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8fec3f165dfe332e490c3247c0f6c23b0bfc45f06496ad7f00ddb00e3d35e4dc", size = 1628469, upload-time = "2026-08-10T14:15:08.11Z" }, + { url = "https://files.pythonhosted.org/packages/f7/87/25babd09b94cb1f03e71db815fde463f0262e40cfbd953d58a8d77311351/greenlet-3.5.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c6ce25fee6cabc8bf22cb8b52e642cbb821be5b9aec8094d07ff03378141b8e9", size = 1691952, upload-time = "2026-08-10T13:40:33.502Z" }, + { url = "https://files.pythonhosted.org/packages/2e/3d/5cc9701117ea4dc0eb7bf1f4f9b7888a6e2e5277ddfae095805ace50f2b6/greenlet-3.5.5-cp314-cp314-win_amd64.whl", hash = "sha256:7dffc5c859fe6059974df1e37d7923d654a83e2ae18fdd616994270e001115e1", size = 327458, upload-time = "2026-08-10T13:27:02.868Z" }, + { url = "https://files.pythonhosted.org/packages/a7/6b/594fa2de7fae7629168a404a4305d7d7e31a5742c50a801b1839543cb93d/greenlet-3.5.5-cp314-cp314-win_arm64.whl", hash = "sha256:5e2afcfc4d4305dd715809b03da5cbe437c8984f61d8917751eb5fe4aefa3e07", size = 311146, upload-time = "2026-08-10T13:27:25.046Z" }, + { url = "https://files.pythonhosted.org/packages/24/e0/50cd600b469e5734c72709b6b1838b6bc63f307b573c772c3132d6ecfe92/greenlet-3.5.5-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:0e5a7de979d764aea1f5b6e95cf92b5b37741b9823702041f34b126e7f690277", size = 305471, upload-time = "2026-08-10T13:26:20.568Z" }, + { url = "https://files.pythonhosted.org/packages/75/a3/77acd66dfc6387b5219b2080806c0cabb73c10eb1bb44b413c40a62015ba/greenlet-3.5.5-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fef01bd457f11fc158b130ca0027a3c365693280e8e231b65bdaf57999f39f5b", size = 672470, upload-time = "2026-08-10T14:14:39.058Z" }, + { url = "https://files.pythonhosted.org/packages/b9/71/0d178142dca3ec19f46fb2212ae73d30ad53b9d548dc64804086033a7089/greenlet-3.5.5-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5173a72310725a74afc82c164f0e52cb8ad0de62f2bb623f24f6c0cc07d80272", size = 679973, upload-time = "2026-08-10T14:27:30.072Z" }, + { url = "https://files.pythonhosted.org/packages/6e/31/46eb8567302eaf787abf88d09df014e14ae3baf460af1b8b0efdbd3efcd5/greenlet-3.5.5-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44f08341873200ba8a60a8bc14ace3d91f1754f7fa7bc66157714a8cd420a476", size = 676634, upload-time = "2026-08-10T13:40:53.004Z" }, + { url = "https://files.pythonhosted.org/packages/a3/e9/b88bbf5b29970cb84172dc2c32aa3e5e579ceb94c808e81c826454138850/greenlet-3.5.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d246c0db9a2513cd45f019ba178ea4d4d4705bd210ee465e2c15d76a1ab13874", size = 1637320, upload-time = "2026-08-10T14:15:09.317Z" }, + { url = "https://files.pythonhosted.org/packages/6d/8c/7631ed29cc6f0392f11830076e172ce4885e70b0bc2c1bce1731176d4b4e/greenlet-3.5.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:72507285b5caa1d17904a3f7c322ca780823a54170a0e04ec3f37bcc60d4db71", size = 1697412, upload-time = "2026-08-10T13:40:34.924Z" }, + { url = "https://files.pythonhosted.org/packages/da/0f/f7dd935f9c4cb1be49098770587f54d8a78518e55c89bce86c4fb4109057/greenlet-3.5.5-cp314-cp314t-win_amd64.whl", hash = "sha256:7805655781fb8f28a55d05fe57ed61f5f10f1892fb587673e3bb5264f28041f0", size = 331514, upload-time = "2026-08-10T13:29:20.611Z" }, + { url = "https://files.pythonhosted.org/packages/b7/e5/681b01f8fbc1b55232822f99e8f8afeb78a55a7c76a7bf9dbdc7ccb03a6d/greenlet-3.5.5-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:c0db80fcd5b8aece93f66c64f78a786bbb6b96c5fe63ef5a5a4581ecf8bab206", size = 295975, upload-time = "2026-08-10T13:28:45.985Z" }, + { url = "https://files.pythonhosted.org/packages/11/f2/69b488cd9e7267bf4b0fe8cdebf25d8d6df680d21bdf41150d23e23d6652/greenlet-3.5.5-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b241c32f912ada659808d68e308c568baf577eebf757d15471472de0c18cfad", size = 666823, upload-time = "2026-08-10T14:14:40.222Z" }, + { url = "https://files.pythonhosted.org/packages/84/d4/d5bc2fdebbdda0c94555925ba79948b8395d75a7f6a36cc85dce5bab9f11/greenlet-3.5.5-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ef6a08349401d8eaf3cb12688ac8557de95788556b8631ef17555a4a173022c0", size = 677613, upload-time = "2026-08-10T14:27:31.543Z" }, + { url = "https://files.pythonhosted.org/packages/bd/93/542d8a3a90f3b35c6ad8bf7e56a03010287f2cafa289a5b7985b5207db39/greenlet-3.5.5-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f2e3d061b8e13aec2f0441689b3c71b244a20e5d274a52cb0f7e31bd1d139552", size = 675930, upload-time = "2026-08-10T13:40:54.205Z" }, + { url = "https://files.pythonhosted.org/packages/52/b5/89c9f2e8460d71101037d47a1feed11928615a5edd42370be290e0657eeb/greenlet-3.5.5-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:9ab5f5b93655e77fe0d6c2dfd22b5eac751bb1f876d8ec21761b7c1fb9266007", size = 1633878, upload-time = "2026-08-10T14:15:10.693Z" }, + { url = "https://files.pythonhosted.org/packages/b8/60/297de93f3b02ac78a5e04d32bb8bbe3080f4a73d8ed95016561463b70618/greenlet-3.5.5-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:f0e5a21bd4452a88cf032fc43c4a5b307ab1380eacb63b5988f9c0317885e773", size = 1696597, upload-time = "2026-08-10T13:40:36.252Z" }, + { url = "https://files.pythonhosted.org/packages/18/25/54c6eaff4f337fb670215e89eb2d00d9499487b658e709d4b477be4a342e/greenlet-3.5.5-cp315-cp315-win_amd64.whl", hash = "sha256:469dbb0a78625642f4a626cfd0c6e8bccc0385b5e49189b6308bbe849ec88a8e", size = 327700, upload-time = "2026-08-10T13:28:06.752Z" }, + { url = "https://files.pythonhosted.org/packages/67/67/857e88a36301caa0e029870132c2478bd55d896630321432afab03a3115f/greenlet-3.5.5-cp315-cp315-win_arm64.whl", hash = "sha256:2d57406c3efd32d7a81e17a674314e8bd00792cdab49ea3228a49aa1bfb2e769", size = 311750, upload-time = "2026-08-10T13:34:08.815Z" }, + { url = "https://files.pythonhosted.org/packages/10/e2/3144c0a116067ac1e30457b0139a94d60d1d36a86e015de68e9ac87cb3bc/greenlet-3.5.5-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:68184dfcf50ccaa8e864770fe0633a7e27250ea9329f8192ef47ee9ecfd78e1c", size = 306387, upload-time = "2026-08-10T13:27:00.897Z" }, + { url = "https://files.pythonhosted.org/packages/5c/a1/cb4223a7e9b9f43b8807e8eb212358bfe2dfaa174a9ea2889eb1714dcba2/greenlet-3.5.5-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9ec0dc0e59dc9c61af5c47348365ccbbd7addfafe0a93b00336ff3da2907bdc6", size = 676472, upload-time = "2026-08-10T14:14:41.417Z" }, + { url = "https://files.pythonhosted.org/packages/9e/cd/a154b4498e5d8f12ada291cfb3b8d596eadde2177f5bf09a9be699d2a446/greenlet-3.5.5-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e604f58e35833fc46ef20302bcb314dddbfd3fcf33a4f936216d51dd678d63ae", size = 684238, upload-time = "2026-08-10T14:27:32.946Z" }, + { url = "https://files.pythonhosted.org/packages/bf/bb/b0031d260c2968a3c87deebc51d80c64e499377f993aafe06ee3b7488cc2/greenlet-3.5.5-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:40239b5384f96da3963585cc6d7eaa9b56f8ae67e8d92cc82dd9e202fc847de3", size = 681246, upload-time = "2026-08-10T13:40:55.402Z" }, + { url = "https://files.pythonhosted.org/packages/9a/07/da554b71ab88e649da146e1065d86a48a5c5d92e50ab74ef41b504aa7f56/greenlet-3.5.5-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:a1eaccf5c3a1d3e46dead602c72e6836731e8e245c9de6a27764567b6b62d4c0", size = 1642735, upload-time = "2026-08-10T14:15:11.92Z" }, + { url = "https://files.pythonhosted.org/packages/78/76/26a3782a051677668af9d92beaa47cd87ba9dd5072f762961144a03dd4c6/greenlet-3.5.5-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:19e4e026fe20691f333b8eb1a3bc9625eceba8c3f9d62ec5a6f8581afbc6b5a5", size = 1700925, upload-time = "2026-08-10T13:40:37.656Z" }, + { url = "https://files.pythonhosted.org/packages/28/d9/fe7baf4190c2ae71f267efb9de21b3172bb35bc0ed1ef53dd6027d658e33/greenlet-3.5.5-cp315-cp315t-win_amd64.whl", hash = "sha256:712aee154f648bde84634654bb38bb78c69ac640c37a45c9effed800735049d8", size = 331829, upload-time = "2026-08-10T13:26:48.851Z" }, + { url = "https://files.pythonhosted.org/packages/df/af/419a4e383bd600858a9b67e9b280a60fdc383ee3f2fe5b6c0c1ef04e74d1/greenlet-3.5.5-cp315-cp315t-win_arm64.whl", hash = "sha256:7f049911ee81a16a03c33d5450d8d5867d27f596ca5fb201b86f4524e874468b", size = 315093, upload-time = "2026-08-10T13:29:34.949Z" }, +] + +[[package]] +name = "idna" +version = "3.18" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, +] + +[[package]] +name = "kontor-model" +version = "0.3.0" +source = { editable = "." } +dependencies = [ + { name = "msgspec", extra = ["toml", "yaml"] }, + { name = "pydantic", extra = ["email"] }, + { name = "sqlalchemy" }, +] + +[package.metadata] +requires-dist = [ + { name = "msgspec", extras = ["toml", "yaml"], specifier = ">=0.21.1" }, + { name = "pydantic", extras = ["email"], specifier = ">=2.13.4" }, + { name = "sqlalchemy", specifier = ">=2.0.52" }, +] + +[[package]] +name = "msgspec" +version = "0.21.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/60/f79b9b013a16fa3a58350c9295ddc6789f2e335f36ea61ed10a21b215364/msgspec-0.21.1.tar.gz", hash = "sha256:2313508e394b0d208f8f56892ca9b2799e2561329de9763b19619595a6c0f72c", size = 319193, upload-time = "2026-04-12T21:44:50.394Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/74/f11ede02839b19ff459f88e3145df5d711626ca84da4e23520cebf819367/msgspec-0.21.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:764173717a01743f007e9f74520ed281f24672c604514f7d76c1c3a10e8edb66", size = 196176, upload-time = "2026-04-12T21:44:17.613Z" }, + { url = "https://files.pythonhosted.org/packages/bb/40/4476c1bd341418a046c4955aff632ec769315d1e3cb94e6acf86d461f9ed/msgspec-0.21.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:344c7cd0eaed1fb81d7959f99100ef71ec9b536881a376f11b9a6c4803365697", size = 188524, upload-time = "2026-04-12T21:44:18.815Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d9/9e9d7d7e5061b47540d03d640fab9b3965ba7ae49c1b2154861c8f007518/msgspec-0.21.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48943e278b3854c2f89f955ddc6f9f430d3f0784b16e47d10604ee0463cd21f5", size = 218880, upload-time = "2026-04-12T21:44:20.028Z" }, + { url = "https://files.pythonhosted.org/packages/74/66/2bb344f34abb4b57e60c7c9c761994e0417b9718ec1460bf00c296f2a7ea/msgspec-0.21.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9aa659ebb0101b1cbc31461212b87e341d961f0ab0772aaf068a99e001ec4aa", size = 225050, upload-time = "2026-04-12T21:44:21.577Z" }, + { url = "https://files.pythonhosted.org/packages/1a/84/7c1e412f76092277bf760cef12b7979d03314d259ab5b5cafde5d0c1722d/msgspec-0.21.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7b27d1a8ead2b6f5b0c4f2d07b8be1ccfcc041c8a0e704781edebe3ae13c484", size = 222713, upload-time = "2026-04-12T21:44:22.83Z" }, + { url = "https://files.pythonhosted.org/packages/4e/27/0bba04b2b4ef05f3d068429410bc71d2cea925f1596a8f41152cccd5edb8/msgspec-0.21.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38fe93e86b61328fe544cb7fd871fad5a27c8734bfda90f65e5dbe288ae50f61", size = 227259, upload-time = "2026-04-12T21:44:24.11Z" }, + { url = "https://files.pythonhosted.org/packages/b0/2d/09574b0eea02fed2c2c1383dbaae2c7f79dc16dcd6487a886000afb5d7c4/msgspec-0.21.1-cp313-cp313-win_amd64.whl", hash = "sha256:8bc666331c35fcce05a7cd2d6221adbe0f6058f8e750711413d22793c080ac6a", size = 189857, upload-time = "2026-04-12T21:44:25.359Z" }, + { url = "https://files.pythonhosted.org/packages/46/34/105b1576ad182879914f0c821f17ee1d13abb165cb060448f96fe2aff078/msgspec-0.21.1-cp313-cp313-win_arm64.whl", hash = "sha256:42bb1241e0750c1a4346f2aa84db26c5ffd99a4eb3a954927d9f149ff2f42898", size = 175403, upload-time = "2026-04-12T21:44:26.608Z" }, + { url = "https://files.pythonhosted.org/packages/5a/ad/86954e987d1d6a5c579e2c2e7832b65e0fff194179fdac4f581536086024/msgspec-0.21.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fab48eb45fdbfbdb2c0edfec00ffc53b6b6085beefc6b50b61e01659f9f8757f", size = 196261, upload-time = "2026-04-12T21:44:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a1/c5e46c3e42b866199365e35d11dddfd1fbd8bba4fdb3c52f965b1607ce94/msgspec-0.21.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3cb779ea0c35bc807ff941d415875c1f69ca0be91a2e907ab99a171811d86a9a", size = 188729, upload-time = "2026-04-12T21:44:28.99Z" }, + { url = "https://files.pythonhosted.org/packages/85/7d/1e29a319d678d6cb962ae5bdf32a6858ebdf38f73bc654c0e9c742a0c2c8/msgspec-0.21.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68604db36b3b4dd9bf160e436e12798a4738848144cea1aca1cb984011eb160f", size = 219866, upload-time = "2026-04-12T21:44:31.104Z" }, + { url = "https://files.pythonhosted.org/packages/25/1f/cca084ca2572810fff12ea9dbdcbe39eac048f40daf4a9077b49fcbe8cee/msgspec-0.21.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3d6b9dc50948eaf65df54d2fd0ff66e6d8c32f116037209ee861810eb9b676cb", size = 224993, upload-time = "2026-04-12T21:44:32.649Z" }, + { url = "https://files.pythonhosted.org/packages/71/94/d2120fc9d419a89a3a7c13e5b7078798c4b392a96a02a6e2b3ce43a8766c/msgspec-0.21.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:52c5e21930942302394429c5a582ce7e6b62c7f983b3760834c2ce107e0dd6df", size = 223535, upload-time = "2026-04-12T21:44:33.839Z" }, + { url = "https://files.pythonhosted.org/packages/75/17/42418b66a3ad972a89bab73dd78b79cc6282bb488a25e73c853cee7443b9/msgspec-0.21.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:abbb39d65681fa24ed394e01af3d59d869068324f900c61d06062b7fb9980f2f", size = 227222, upload-time = "2026-04-12T21:44:35.093Z" }, + { url = "https://files.pythonhosted.org/packages/c4/33/265c894268cca88ff67b144ca2b4c522fc8b9a6f1966a3640c70516e78e1/msgspec-0.21.1-cp314-cp314-win_amd64.whl", hash = "sha256:5666b1b560b97b6ec2eb3fca8a502298ebac56e13bbca1f88523538ce83d01ea", size = 193810, upload-time = "2026-04-12T21:44:36.612Z" }, + { url = "https://files.pythonhosted.org/packages/3b/8f/a6d35f25bf1fc63c492fdd88fdce01ba0875ead48c2b91f90f33653b4131/msgspec-0.21.1-cp314-cp314-win_arm64.whl", hash = "sha256:d8b8578e4c83b14ceea4cef0d0b747e31d9330fe4b03b2b2ad4063866a178f93", size = 179125, upload-time = "2026-04-12T21:44:38.198Z" }, + { url = "https://files.pythonhosted.org/packages/c6/39/74839641e64b99d87da55af0fc472854d42b46e2183b9e2a67fe1bb2a512/msgspec-0.21.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:15f523d51c00ebad412213bfe9f06f0a50ec2b93e0c19e824a2d267cabb48ea2", size = 200171, upload-time = "2026-04-12T21:44:39.414Z" }, + { url = "https://files.pythonhosted.org/packages/70/9b/ce0cca6d2d87fcd4b6ff97600790494e64f26a2c55d61507cd2755c16193/msgspec-0.21.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4e47390360583ba3d5c6cb44cf0a9f61b0a06a899d3c2c00627cedebb2e2884b", size = 192879, upload-time = "2026-04-12T21:44:40.882Z" }, + { url = "https://files.pythonhosted.org/packages/a7/08/673a7bb05e5702dc787ddd3011195b509f9867927970da59052211929987/msgspec-0.21.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f60800e6299b798142dc40b0644da77ceac5ea0568be58228417eae14135c847", size = 226281, upload-time = "2026-04-12T21:44:42.181Z" }, + { url = "https://files.pythonhosted.org/packages/7d/45/86508cf57283e9070b3c447e3ab25b792a7a0855a3ea4e0c6d111ac34c97/msgspec-0.21.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5f8e9dfcd98419cf7568808470c4317a3fb30bef0e3715b568730a2b272a20d7", size = 229863, upload-time = "2026-04-12T21:44:43.442Z" }, + { url = "https://files.pythonhosted.org/packages/2c/62/e7c9367cd08d590559faacd711edbae36840342843e669440363f33c7d36/msgspec-0.21.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:92d89dfad13bd1ea640dc3e37e724ed380da1030b272bdf5ecafb983c3ad7c75", size = 230445, upload-time = "2026-04-12T21:44:44.806Z" }, + { url = "https://files.pythonhosted.org/packages/42/b4/c0f54632103846b658a10930025f4de41c8724b5e4805a5f3b395586cb7e/msgspec-0.21.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0d03867786e5d7ba25d666df4b11320c27170f4aeafcb8e3a8b0a50a4fb742ca", size = 231822, upload-time = "2026-04-12T21:44:46.343Z" }, + { url = "https://files.pythonhosted.org/packages/ea/1d/0d85cc79d0ccf5508e9c846cc66552a6a16bf92abd1dbd8362617f7b35cd/msgspec-0.21.1-cp314-cp314t-win_amd64.whl", hash = "sha256:740fbf1c9d59992ca3537d6fbe9ebbf9eaf726a65fbf31448e0ecbc710697a63", size = 206650, upload-time = "2026-04-12T21:44:47.601Z" }, + { url = "https://files.pythonhosted.org/packages/90/91/56c5d560f20e6c20e9e4f55bd0e458f7f162aa689ee350346c04c48eac0b/msgspec-0.21.1-cp314-cp314t-win_arm64.whl", hash = "sha256:0d2cc73df6058d811a126ac3a8ad63a4dfa210c82f9cf5a004802eaf4712de90", size = 183149, upload-time = "2026-04-12T21:44:48.833Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli-w" }, +] +yaml = [ + { name = "pyyaml" }, +] + +[[package]] +name = "pydantic" +version = "2.13.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, +] + +[package.optional-dependencies] +email = [ + { name = "email-validator" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" }, + { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" }, + { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" }, + { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" }, + { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" }, + { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" }, + { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.52" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3b/21/77b4c147963073040dc3c3a5cb7a8c3001a1893c0209432cb77f9df836aa/sqlalchemy-2.0.52.tar.gz", hash = "sha256:5e2d46356ac2ccb7d268ab6c2319ac6a2b42f1b8d5fd8bd3d46855cd82abee97", size = 9945637, upload-time = "2026-08-11T19:07:09.829Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/18/e30c6fe1eca1bf34a39fbdd6066121cc9974c850faf6f349eac563697a26/sqlalchemy-2.0.52-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2eb3c6a64b1bfe6704777cfd504e7b8ad093a5f3e03ce67663a5e6742f294e43", size = 2167724, upload-time = "2026-08-11T20:58:12.679Z" }, + { url = "https://files.pythonhosted.org/packages/d0/56/2e17d161a4f7ecc1c2ffb93e607b4e1898bb551b451b283235acb8f6ce47/sqlalchemy-2.0.52-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:923bb183c1dc64fdf7b717965e3d59938ec4f8b8710b419a21ce403e5da9a9e1", size = 3321189, upload-time = "2026-08-11T21:02:41.932Z" }, + { url = "https://files.pythonhosted.org/packages/cf/b8/8490916e893f3f8d74dc9cc54c078619364999dee37047a188e73abbc852/sqlalchemy-2.0.52-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:651d6d8782e80679e6151707c7b490834d46ada526328895abf567f25e63d29c", size = 3338185, upload-time = "2026-08-11T21:17:02.597Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f7/752cc8ee453da222829b3f5c4613614bf750d97429363b70414fa10478e4/sqlalchemy-2.0.52-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b08cddb8989775e3c88799d86704bdfc3ee6e9846118201aa5997f16f27e3a15", size = 3271698, upload-time = "2026-08-11T21:02:43.963Z" }, + { url = "https://files.pythonhosted.org/packages/51/e6/074ade0c07b9e4c8e8bca46820320ed94df9702afdb6f2af06623068d2e6/sqlalchemy-2.0.52-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ab66fa9618269390d4dfa222f2f2f88f7bc4bf5da13905131b818217db7e8057", size = 3308936, upload-time = "2026-08-11T21:17:04.172Z" }, + { url = "https://files.pythonhosted.org/packages/66/07/557c0d04716705599227945ac14e0a17ad0338e899f37d8c2ddff4dcc663/sqlalchemy-2.0.52-cp313-cp313-win32.whl", hash = "sha256:c63bda077685c85ca513286547a531ba57e7a68cf0a7ed3bafcc2bbd18896f4d", size = 2127308, upload-time = "2026-08-11T21:14:53.879Z" }, + { url = "https://files.pythonhosted.org/packages/96/4e/226eda27654318ce525d043025221f689abef883da2c7126f9065121618c/sqlalchemy-2.0.52-cp313-cp313-win_amd64.whl", hash = "sha256:9876b09b9f1ce7398b0ffece585c0a911244c53191187341f6bcae640e133751", size = 2153876, upload-time = "2026-08-11T21:14:55.527Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f5/71cb30af58c9b80a4e1fac0b73bb48f86d497a774a6a2eb6d2f1e657bb73/sqlalchemy-2.0.52-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:410d52be41d17f1a236d19520fbe776257dc16516ed06bd16d433311842aefd9", size = 2169537, upload-time = "2026-08-11T20:58:13.855Z" }, + { url = "https://files.pythonhosted.org/packages/4c/93/d07ebd645d1b07b6b5ed63450a70f063a346a7e0f2c8810daf2e532400cb/sqlalchemy-2.0.52-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfe9ce533dbe4d0a2ae1486546619bd30b76bcd670539a44d910361376175f5e", size = 3319606, upload-time = "2026-08-11T21:02:45.829Z" }, + { url = "https://files.pythonhosted.org/packages/ae/5c/290c84c7c2566ecd3b65baaae0fddec9bc33b033b398a06123bb86fbfc6e/sqlalchemy-2.0.52-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:812bae5138bfc0aa46fb0686da0fc7f581f68e2bbb05bc24c3713bebaedd1437", size = 3323642, upload-time = "2026-08-11T21:17:05.675Z" }, + { url = "https://files.pythonhosted.org/packages/13/f5/2cc160590ca49173359557880b92a0572293ccb899e8f6cedf150c5a3ddf/sqlalchemy-2.0.52-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:50bff43b632a56fbf5ed9afdd76307e1512b62051bcd5afb341ae67205bbb6c8", size = 3268125, upload-time = "2026-08-11T21:02:47.649Z" }, + { url = "https://files.pythonhosted.org/packages/35/f3/ea8933fc9f7d1353e9c2ff9965eae687c4cef181120574591ed2fa0633e1/sqlalchemy-2.0.52-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:49565daf5af554f538e23aef1fc81a95a4e49658f152285e45c02f5fc44f04cd", size = 3289516, upload-time = "2026-08-11T21:17:07.267Z" }, + { url = "https://files.pythonhosted.org/packages/45/67/05cf86541c1e1716fca1e4a996954a439cd74501707cda607fb7cb02ef50/sqlalchemy-2.0.52-cp314-cp314-win32.whl", hash = "sha256:ab9da41e61b9979b910499d633b241df20c51ee5037e5405b11c2faac3cbe1a2", size = 2130249, upload-time = "2026-08-11T21:14:57.273Z" }, + { url = "https://files.pythonhosted.org/packages/96/d7/8ac6ffa1e36169e762ef65bd835046abb2251b1bc17f8f6708e14ed8d31f/sqlalchemy-2.0.52-cp314-cp314-win_amd64.whl", hash = "sha256:a593db51b3bae75db17a5738ad5f992244b3a03863f83c28117ee482c6a3f76d", size = 2156718, upload-time = "2026-08-11T21:14:58.667Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4b/e01a737eef378e734cc6394a82248a6ce13b167dfa36c731075ce9fc9c64/sqlalchemy-2.0.52-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1e61d08bdf4ee2f41024569e3400de7d6734ba498144766b11260936ccfa582", size = 2190344, upload-time = "2026-08-11T19:53:21.393Z" }, + { url = "https://files.pythonhosted.org/packages/b3/3f/3582293d1e185e71d19d7c731c3e2ee20ba21981c4a1115c0806c1f62120/sqlalchemy-2.0.52-py3-none-any.whl", hash = "sha256:3b81b8363a919ce53453591cdb93702e6bd54ade6c4fa2f468fc053baee5ed89", size = 1950700, upload-time = "2026-08-11T20:47:21.603Z" }, +] + +[[package]] +name = "tomli-w" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184, upload-time = "2025-01-15T12:07:24.262Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675, upload-time = "2025-01-15T12:07:22.074Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c09092e6b34058f36a460eea2d4c3e8b910c695975a0/typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47", size = 76928, upload-time = "2026-08-12T12:37:25.997Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload-time = "2026-08-12T12:37:24.648Z" }, +] diff --git a/kontor-quarkus/Containerfile b/kontor-quarkus/Containerfile new file mode 100644 index 0000000..50e36f1 --- /dev/null +++ b/kontor-quarkus/Containerfile @@ -0,0 +1,33 @@ +# ----------------------------------------------------------------------- # +FROM docker.io/library/gradle:9.2-jdk AS builder +WORKDIR / +COPY ./src/ ./src/ +COPY ./build.gradle.kts ./ +COPY ./gradle.properties ./ +COPY ./settings.gradle.kts ./ +RUN gradle build --no-daemon + +# ----------------------------------------------------------------------- # +#FROM alpine/java:21-jdk AS run + +#COPY --from=builder /build/libs/kontor-quarkus-0.2.0-SNAPSHOT.jar app.jar + +#EXPOSE 8300 +#CMD ["java", "-jar", "-Dquarkus.http.host=0.0.0.0", "app.jar"] + +# ----------------------------------------------------------------------- # +FROM registry.access.redhat.com/ubi9/openjdk-21:1.23 + +ENV LANGUAGE='de_DE:de' + +# We make four distinct layers so if there are application changes the library layers can be re-used +COPY --from=builder build/quarkus-app/lib/ /deployments/lib/ +COPY --from=builder build/quarkus-app/*.jar /deployments/ +COPY --from=builder build/quarkus-app/app/ /deployments/app/ +COPY --from=builder build/quarkus-app/quarkus/ /deployments/quarkus/ + +EXPOSE 8300 +ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" + +ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ] diff --git a/kontor-quarkus/Dockerfile b/kontor-quarkus/Dockerfile deleted file mode 100644 index 5784e01..0000000 --- a/kontor-quarkus/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -# ----------------------------------------------------------------------- # -FROM gradle:9.2-jdk AS builder -WORKDIR / -COPY ./src/ ./src/ -COPY ./build.gradle.kts ./ -COPY ./gradle.properties ./ -COPY ./settings.gradle.kts ./ -RUN gradle build --no-daemon - -# ----------------------------------------------------------------------- # -#FROM alpine/java:21-jdk AS run - -#RUN adduser --system appuser - -#COPY --from=builder --chown=appuser:appuser /build/libs/kontor-quarkus-0.2.0-SNAPSHOT.jar app.jar - -#EXPOSE 8800 -#USER appuser -#CMD ["java", "-jar", "-Dquarkus.http.host=0.0.0.0", "app.jar"] - -# ----------------------------------------------------------------------- # -FROM registry.access.redhat.com/ubi9/openjdk-21:1.23 - -ENV LANGUAGE='en_US:en' - -# We make four distinct layers so if there are application changes the library layers can be re-used -COPY --from=builder --chown=185 build/quarkus-app/lib/ /deployments/lib/ -COPY --from=builder --chown=185 build/quarkus-app/*.jar /deployments/ -COPY --from=builder --chown=185 build/quarkus-app/app/ /deployments/app/ -COPY --from=builder --chown=185 build/quarkus-app/quarkus/ /deployments/quarkus/ - -EXPOSE 8800 -USER 185 -ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" -ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" - -ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ] diff --git a/kontor-quarkus/src/main/kotlin/de/thpeetz/kontor/KontorApplication.kt b/kontor-quarkus/src/main/kotlin/de/thpeetz/kontor/KontorApplication.kt index f43d1c4..aabdcb4 100644 --- a/kontor-quarkus/src/main/kotlin/de/thpeetz/kontor/KontorApplication.kt +++ b/kontor-quarkus/src/main/kotlin/de/thpeetz/kontor/KontorApplication.kt @@ -8,7 +8,7 @@ import org.eclipse.microprofile.openapi.annotations.tags.Tag @OpenAPIDefinition( info = Info( title = "Kontor", - version = "0.2.0" + version = "0.3.0" ) ) class KontorApplication: Application() \ No newline at end of file diff --git a/kontor-quarkus/src/main/resources/application.properties b/kontor-quarkus/src/main/resources/application.properties index de2e006..bac81bd 100644 --- a/kontor-quarkus/src/main/resources/application.properties +++ b/kontor-quarkus/src/main/resources/application.properties @@ -1,4 +1,4 @@ -quarkus.http.port=8800 +quarkus.http.port=8300 quarkus.swagger-ui.always-include=true quarkus.datasource.db-kind=postgresql quarkus.datasource.username=kontor diff --git a/kontor-rails/.dockerignore b/kontor-rails/.dockerignore new file mode 100644 index 0000000..aab1e74 --- /dev/null +++ b/kontor-rails/.dockerignore @@ -0,0 +1,50 @@ +# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. + +# Ignore git directory. +/.gitignore + +# Ignore bundler config. +/.bundle + +# Ignore all environment files. +/.env* + +# Ignore all default key files. +/config/master.key +/config/credentials/*.key + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/.keep + +# Ignore storage (uploaded files in development and any SQLite databases). +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/.keep + +# Ignore assets. +/node_modules/ +/app/assets/builds/* +!/app/assets/builds/.keep +/public/assets + +# Ignore CI service files. +/.github + +# Ignore Kamal files. +/config/deploy*.yml +/.kamal + +# Ignore development files +/.devcontainer + +# Ignore Docker-related files +/.dockerignore +/Dockerfile* diff --git a/kontor-rails/.gitattributes b/kontor-rails/.gitattributes new file mode 100644 index 0000000..8dc4323 --- /dev/null +++ b/kontor-rails/.gitattributes @@ -0,0 +1,9 @@ +# See https://git-scm.com/docs/gitattributes for more about git attribute files. + +# Mark the database schema as having been generated. +db/schema.rb linguist-generated + +# Mark any vendored files as having been vendored. +vendor/* linguist-vendored +config/credentials/*.yml.enc diff=rails_credentials +config/credentials.yml.enc diff=rails_credentials diff --git a/kontor-rails/.gitignore b/kontor-rails/.gitignore new file mode 100644 index 0000000..bbb6721 --- /dev/null +++ b/kontor-rails/.gitignore @@ -0,0 +1,34 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# Temporary files generated by your text editor or operating system +# belong in git's global ignore instead: +# `$XDG_CONFIG_HOME/git/ignore` or `~/.config/git/ignore` + +# Ignore bundler config. +.bundle + +# Ignore all environment files. +.env* + +# Ignore all logfiles and tempfiles. +log/* +tmp/* +!log/.keep +!tmp/.keep + +# Ignore pidfiles, but keep the directory. +tmp/pids/* +!tmp/pids/ +!tmp/pids/.keep + +# Ignore storage (uploaded files in development and any SQLite databases). +storage/* +!storage/.keep +tmp/storage/* +!tmp/storage/ +!tmp/storage/.keep + +public/assets + +# Ignore master key for decrypting credentials and more. +config/master.key diff --git a/kontor-rails/.kamal/hooks/docker-setup.sample b/kontor-rails/.kamal/hooks/docker-setup.sample new file mode 100755 index 0000000..2fb07d7 --- /dev/null +++ b/kontor-rails/.kamal/hooks/docker-setup.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Docker set up on $KAMAL_HOSTS..." diff --git a/kontor-rails/.kamal/hooks/post-app-boot.sample b/kontor-rails/.kamal/hooks/post-app-boot.sample new file mode 100755 index 0000000..70f9c4b --- /dev/null +++ b/kontor-rails/.kamal/hooks/post-app-boot.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Booted app version $KAMAL_VERSION on $KAMAL_HOSTS..." diff --git a/kontor-rails/.kamal/hooks/post-deploy.sample b/kontor-rails/.kamal/hooks/post-deploy.sample new file mode 100755 index 0000000..fd364c2 --- /dev/null +++ b/kontor-rails/.kamal/hooks/post-deploy.sample @@ -0,0 +1,14 @@ +#!/bin/sh + +# A sample post-deploy hook +# +# These environment variables are available: +# KAMAL_RECORDED_AT +# KAMAL_PERFORMER +# KAMAL_VERSION +# KAMAL_HOSTS +# KAMAL_ROLES (if set) +# KAMAL_DESTINATION (if set) +# KAMAL_RUNTIME + +echo "$KAMAL_PERFORMER deployed $KAMAL_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds" diff --git a/kontor-rails/.kamal/hooks/post-proxy-reboot.sample b/kontor-rails/.kamal/hooks/post-proxy-reboot.sample new file mode 100755 index 0000000..1435a67 --- /dev/null +++ b/kontor-rails/.kamal/hooks/post-proxy-reboot.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Rebooted kamal-proxy on $KAMAL_HOSTS" diff --git a/kontor-rails/.kamal/hooks/pre-app-boot.sample b/kontor-rails/.kamal/hooks/pre-app-boot.sample new file mode 100755 index 0000000..45f7355 --- /dev/null +++ b/kontor-rails/.kamal/hooks/pre-app-boot.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Booting app version $KAMAL_VERSION on $KAMAL_HOSTS..." diff --git a/kontor-rails/.kamal/hooks/pre-build.sample b/kontor-rails/.kamal/hooks/pre-build.sample new file mode 100755 index 0000000..c5a5567 --- /dev/null +++ b/kontor-rails/.kamal/hooks/pre-build.sample @@ -0,0 +1,51 @@ +#!/bin/sh + +# A sample pre-build hook +# +# Checks: +# 1. We have a clean checkout +# 2. A remote is configured +# 3. The branch has been pushed to the remote +# 4. The version we are deploying matches the remote +# +# These environment variables are available: +# KAMAL_RECORDED_AT +# KAMAL_PERFORMER +# KAMAL_VERSION +# KAMAL_HOSTS +# KAMAL_ROLES (if set) +# KAMAL_DESTINATION (if set) + +if [ -n "$(git status --porcelain)" ]; then + echo "Git checkout is not clean, aborting..." >&2 + git status --porcelain >&2 + exit 1 +fi + +first_remote=$(git remote) + +if [ -z "$first_remote" ]; then + echo "No git remote set, aborting..." >&2 + exit 1 +fi + +current_branch=$(git branch --show-current) + +if [ -z "$current_branch" ]; then + echo "Not on a git branch, aborting..." >&2 + exit 1 +fi + +remote_head=$(git ls-remote $first_remote --tags $current_branch | cut -f1) + +if [ -z "$remote_head" ]; then + echo "Branch not pushed to remote, aborting..." >&2 + exit 1 +fi + +if [ "$KAMAL_VERSION" != "$remote_head" ]; then + echo "Version ($KAMAL_VERSION) does not match remote HEAD ($remote_head), aborting..." >&2 + exit 1 +fi + +exit 0 diff --git a/kontor-rails/.kamal/hooks/pre-connect.sample b/kontor-rails/.kamal/hooks/pre-connect.sample new file mode 100755 index 0000000..77744bd --- /dev/null +++ b/kontor-rails/.kamal/hooks/pre-connect.sample @@ -0,0 +1,47 @@ +#!/usr/bin/env ruby + +# A sample pre-connect check +# +# Warms DNS before connecting to hosts in parallel +# +# These environment variables are available: +# KAMAL_RECORDED_AT +# KAMAL_PERFORMER +# KAMAL_VERSION +# KAMAL_HOSTS +# KAMAL_ROLES (if set) +# KAMAL_DESTINATION (if set) +# KAMAL_RUNTIME + +hosts = ENV["KAMAL_HOSTS"].split(",") +results = nil +max = 3 + +elapsed = Benchmark.realtime do + results = hosts.map do |host| + Thread.new do + tries = 1 + + begin + Socket.getaddrinfo(host, 0, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) + rescue SocketError + if tries < max + puts "Retrying DNS warmup: #{host}" + tries += 1 + sleep rand + retry + else + puts "DNS warmup failed: #{host}" + host + end + end + + tries + end + end.map(&:value) +end + +retries = results.sum - hosts.size +nopes = results.count { |r| r == max } + +puts "Prewarmed %d DNS lookups in %.2f sec: %d retries, %d failures" % [ hosts.size, elapsed, retries, nopes ] diff --git a/kontor-rails/.kamal/hooks/pre-deploy.sample b/kontor-rails/.kamal/hooks/pre-deploy.sample new file mode 100755 index 0000000..05b3055 --- /dev/null +++ b/kontor-rails/.kamal/hooks/pre-deploy.sample @@ -0,0 +1,122 @@ +#!/usr/bin/env ruby + +# A sample pre-deploy hook +# +# Checks the Github status of the build, waiting for a pending build to complete for up to 720 seconds. +# +# Fails unless the combined status is "success" +# +# These environment variables are available: +# KAMAL_RECORDED_AT +# KAMAL_PERFORMER +# KAMAL_VERSION +# KAMAL_HOSTS +# KAMAL_COMMAND +# KAMAL_SUBCOMMAND +# KAMAL_ROLES (if set) +# KAMAL_DESTINATION (if set) + +# Only check the build status for production deployments +if ENV["KAMAL_COMMAND"] == "rollback" || ENV["KAMAL_DESTINATION"] != "production" + exit 0 +end + +require "bundler/inline" + +# true = install gems so this is fast on repeat invocations +gemfile(true, quiet: true) do + source "https://rubygems.org" + + gem "octokit" + gem "faraday-retry" +end + +MAX_ATTEMPTS = 72 +ATTEMPTS_GAP = 10 + +def exit_with_error(message) + $stderr.puts message + exit 1 +end + +class GithubStatusChecks + attr_reader :remote_url, :git_sha, :github_client, :combined_status + + def initialize + @remote_url = github_repo_from_remote_url + @git_sha = `git rev-parse HEAD`.strip + @github_client = Octokit::Client.new(access_token: ENV["GITHUB_TOKEN"]) + refresh! + end + + def refresh! + @combined_status = github_client.combined_status(remote_url, git_sha) + end + + def state + combined_status[:state] + end + + def first_status_url + first_status = combined_status[:statuses].find { |status| status[:state] == state } + first_status && first_status[:target_url] + end + + def complete_count + combined_status[:statuses].count { |status| status[:state] != "pending"} + end + + def total_count + combined_status[:statuses].count + end + + def current_status + if total_count > 0 + "Completed #{complete_count}/#{total_count} checks, see #{first_status_url} ..." + else + "Build not started..." + end + end + + private + def github_repo_from_remote_url + url = `git config --get remote.origin.url`.strip.delete_suffix(".git") + if url.start_with?("https://github.com/") + url.delete_prefix("https://github.com/") + elsif url.start_with?("git@github.com:") + url.delete_prefix("git@github.com:") + else + url + end + end +end + + +$stdout.sync = true + +begin + puts "Checking build status..." + + attempts = 0 + checks = GithubStatusChecks.new + + loop do + case checks.state + when "success" + puts "Checks passed, see #{checks.first_status_url}" + exit 0 + when "failure" + exit_with_error "Checks failed, see #{checks.first_status_url}" + when "pending" + attempts += 1 + end + + exit_with_error "Checks are still pending, gave up after #{MAX_ATTEMPTS * ATTEMPTS_GAP} seconds" if attempts == MAX_ATTEMPTS + + puts checks.current_status + sleep(ATTEMPTS_GAP) + checks.refresh! + end +rescue Octokit::NotFound + exit_with_error "Build status could not be found" +end diff --git a/kontor-rails/.kamal/hooks/pre-proxy-reboot.sample b/kontor-rails/.kamal/hooks/pre-proxy-reboot.sample new file mode 100755 index 0000000..061f805 --- /dev/null +++ b/kontor-rails/.kamal/hooks/pre-proxy-reboot.sample @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Rebooting kamal-proxy on $KAMAL_HOSTS..." diff --git a/kontor-rails/.kamal/secrets b/kontor-rails/.kamal/secrets new file mode 100644 index 0000000..9a771a3 --- /dev/null +++ b/kontor-rails/.kamal/secrets @@ -0,0 +1,17 @@ +# Secrets defined here are available for reference under registry/password, env/secret, builder/secrets, +# and accessories/*/env/secret in config/deploy.yml. All secrets should be pulled from either +# password manager, ENV, or a file. DO NOT ENTER RAW CREDENTIALS HERE! This file needs to be safe for git. + +# Example of extracting secrets from 1password (or another compatible pw manager) +# SECRETS=$(kamal secrets fetch --adapter 1password --account your-account --from Vault/Item KAMAL_REGISTRY_PASSWORD RAILS_MASTER_KEY) +# KAMAL_REGISTRY_PASSWORD=$(kamal secrets extract KAMAL_REGISTRY_PASSWORD ${SECRETS}) +# RAILS_MASTER_KEY=$(kamal secrets extract RAILS_MASTER_KEY ${SECRETS}) + +# Use a GITHUB_TOKEN if private repositories are needed for the image +# GITHUB_TOKEN=$(gh config get -h github.com oauth_token) + +# Grab the registry password from ENV +KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD + +# Improve security by using a password manager. Never check config/master.key into git! +RAILS_MASTER_KEY=$(cat config/master.key) diff --git a/kontor-rails/.rubocop.yml b/kontor-rails/.rubocop.yml new file mode 100644 index 0000000..f9d86d4 --- /dev/null +++ b/kontor-rails/.rubocop.yml @@ -0,0 +1,8 @@ +# Omakase Ruby styling for Rails +inherit_gem: { rubocop-rails-omakase: rubocop.yml } + +# Overwrite or add rules to create your own house style +# +# # Use `[a, [b, c]]` not `[ a, [ b, c ] ]` +# Layout/SpaceInsideArrayLiteralBrackets: +# Enabled: false diff --git a/kontor-rails/.ruby-version b/kontor-rails/.ruby-version new file mode 100644 index 0000000..e3cc07a --- /dev/null +++ b/kontor-rails/.ruby-version @@ -0,0 +1 @@ +ruby-3.4.4 diff --git a/kontor-rails/Dockerfile b/kontor-rails/Dockerfile new file mode 100644 index 0000000..6b9bba1 --- /dev/null +++ b/kontor-rails/Dockerfile @@ -0,0 +1,72 @@ +# syntax=docker/dockerfile:1 +# check=error=true + +# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand: +# docker build -t kontor_rails . +# docker run -d -p 80:80 -e RAILS_MASTER_KEY= --name kontor_rails kontor_rails + +# For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html + +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version +ARG RUBY_VERSION=3.4.4 +FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base + +# Rails app lives here +WORKDIR /rails + +# Install base packages +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y curl libjemalloc2 libvips sqlite3 && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + +# Set production environment +ENV RAILS_ENV="production" \ + BUNDLE_DEPLOYMENT="1" \ + BUNDLE_PATH="/usr/local/bundle" \ + BUNDLE_WITHOUT="development" + +# Throw-away build stage to reduce size of final image +FROM base AS build + +# Install packages needed to build gems +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y build-essential git libyaml-dev pkg-config && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + +# Install application gems +COPY Gemfile Gemfile.lock ./ +RUN bundle install && \ + rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ + bundle exec bootsnap precompile --gemfile + +# Copy application code +COPY . . + +# Precompile bootsnap code for faster boot times +RUN bundle exec bootsnap precompile app/ lib/ + +# Precompiling assets for production without requiring secret RAILS_MASTER_KEY +RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile + + + + +# Final stage for app image +FROM base + +# Copy built artifacts: gems, application +COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" +COPY --from=build /rails /rails + +# Run and own only the runtime files as a non-root user for security +RUN groupadd --system --gid 1000 rails && \ + useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \ + chown -R rails:rails db log storage tmp +USER 1000:1000 + +# Entrypoint prepares the database. +ENTRYPOINT ["/rails/bin/docker-entrypoint"] + +# Start server via Thruster by default, this can be overwritten at runtime +EXPOSE 80 +CMD ["./bin/thrust", "./bin/rails", "server"] diff --git a/kontor-rails/Gemfile b/kontor-rails/Gemfile new file mode 100644 index 0000000..139b7ae --- /dev/null +++ b/kontor-rails/Gemfile @@ -0,0 +1,64 @@ +source "https://rubygems.org" + +# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" +gem "rails", "~> 8.0.2" +# The modern asset pipeline for Rails [https://github.com/rails/propshaft] +gem "propshaft" +# Use sqlite3 as the database for Active Record +gem "sqlite3", ">= 2.1" +# Use the Puma web server [https://github.com/puma/puma] +gem "puma", ">= 5.0" +# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] +gem "importmap-rails" +# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] +gem "turbo-rails" +# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] +gem "stimulus-rails" +# Build JSON APIs with ease [https://github.com/rails/jbuilder] +gem "jbuilder" + +# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] +# gem "bcrypt", "~> 3.1.7" + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem "tzinfo-data", platforms: %i[ windows jruby ] + +# Use the database-backed adapters for Rails.cache, Active Job, and Action Cable +gem "solid_cache" +gem "solid_queue" +gem "solid_cable" + +# Reduces boot times through caching; required in config/boot.rb +gem "bootsnap", require: false + +# Deploy this application anywhere as a Docker container [https://kamal-deploy.org] +gem "kamal", require: false + +# Add HTTP asset caching/compression and X-Sendfile acceleration to Puma [https://github.com/basecamp/thruster/] +gem "thruster", require: false + +# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] +# gem "image_processing", "~> 1.2" + +group :development, :test do + # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem + gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" + + # Static analysis for security vulnerabilities [https://brakemanscanner.org/] + gem "brakeman", require: false + + # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/] + gem "rubocop-rails-omakase", require: false +end + +group :development do + # Use console on exceptions pages [https://github.com/rails/web-console] + gem "web-console" + gem "rails-erd" +end + +group :test do + # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] + gem "capybara" + gem "selenium-webdriver" +end diff --git a/kontor-rails/Gemfile.lock b/kontor-rails/Gemfile.lock new file mode 100644 index 0000000..24c94b3 --- /dev/null +++ b/kontor-rails/Gemfile.lock @@ -0,0 +1,394 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (8.0.2) + actionpack (= 8.0.2) + activesupport (= 8.0.2) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + zeitwerk (~> 2.6) + actionmailbox (8.0.2) + actionpack (= 8.0.2) + activejob (= 8.0.2) + activerecord (= 8.0.2) + activestorage (= 8.0.2) + activesupport (= 8.0.2) + mail (>= 2.8.0) + actionmailer (8.0.2) + actionpack (= 8.0.2) + actionview (= 8.0.2) + activejob (= 8.0.2) + activesupport (= 8.0.2) + mail (>= 2.8.0) + rails-dom-testing (~> 2.2) + actionpack (8.0.2) + actionview (= 8.0.2) + activesupport (= 8.0.2) + nokogiri (>= 1.8.5) + rack (>= 2.2.4) + rack-session (>= 1.0.1) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + useragent (~> 0.16) + actiontext (8.0.2) + actionpack (= 8.0.2) + activerecord (= 8.0.2) + activestorage (= 8.0.2) + activesupport (= 8.0.2) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (8.0.2) + activesupport (= 8.0.2) + builder (~> 3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (8.0.2) + activesupport (= 8.0.2) + globalid (>= 0.3.6) + activemodel (8.0.2) + activesupport (= 8.0.2) + activerecord (8.0.2) + activemodel (= 8.0.2) + activesupport (= 8.0.2) + timeout (>= 0.4.0) + activestorage (8.0.2) + actionpack (= 8.0.2) + activejob (= 8.0.2) + activerecord (= 8.0.2) + activesupport (= 8.0.2) + marcel (~> 1.0) + activesupport (8.0.2) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + ast (2.4.3) + base64 (0.3.0) + bcrypt_pbkdf (1.1.1) + benchmark (0.4.1) + bigdecimal (3.2.2) + bindex (0.8.1) + bootsnap (1.18.6) + msgpack (~> 1.2) + brakeman (7.0.2) + racc + builder (3.3.0) + capybara (3.40.0) + addressable + matrix + mini_mime (>= 0.1.3) + nokogiri (~> 1.11) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (>= 1.5, < 3.0) + xpath (~> 3.2) + choice (0.2.0) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) + crass (1.0.6) + date (3.4.1) + debug (1.11.0) + irb (~> 1.10) + reline (>= 0.3.8) + dotenv (3.1.8) + drb (2.2.3) + ed25519 (1.4.0) + erb (5.0.1) + erubi (1.13.1) + et-orbi (1.2.11) + tzinfo + fugit (1.11.1) + et-orbi (~> 1, >= 1.2.11) + raabro (~> 1.4) + globalid (1.2.1) + activesupport (>= 6.1) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + importmap-rails (2.1.0) + actionpack (>= 6.0.0) + activesupport (>= 6.0.0) + railties (>= 6.0.0) + io-console (0.8.0) + irb (1.15.2) + pp (>= 0.6.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + jbuilder (2.13.0) + actionview (>= 5.0.0) + activesupport (>= 5.0.0) + json (2.12.2) + kamal (2.7.0) + activesupport (>= 7.0) + base64 (~> 0.2) + bcrypt_pbkdf (~> 1.0) + concurrent-ruby (~> 1.2) + dotenv (~> 3.1) + ed25519 (~> 1.4) + net-ssh (~> 7.3) + sshkit (>= 1.23.0, < 2.0) + thor (~> 1.3) + zeitwerk (>= 2.6.18, < 3.0) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + logger (1.7.0) + loofah (2.24.1) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + mail (2.8.1) + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + marcel (1.0.4) + matrix (0.4.3) + mini_mime (1.1.5) + minitest (5.25.5) + msgpack (1.8.0) + net-imap (0.5.9) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-scp (4.1.0) + net-ssh (>= 2.6.5, < 8.0.0) + net-sftp (4.0.0) + net-ssh (>= 5.0.0, < 8.0.0) + net-smtp (0.5.1) + net-protocol + net-ssh (7.3.0) + nio4r (2.7.4) + nokogiri (1.18.8-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.8-aarch64-linux-musl) + racc (~> 1.4) + nokogiri (1.18.8-arm-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.8-arm-linux-musl) + racc (~> 1.4) + nokogiri (1.18.8-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.8-x86_64-linux-musl) + racc (~> 1.4) + ostruct (0.6.2) + parallel (1.27.0) + parser (3.3.8.0) + ast (~> 2.4.1) + racc + pp (0.6.2) + prettyprint + prettyprint (0.2.0) + prism (1.4.0) + propshaft (1.1.0) + actionpack (>= 7.0.0) + activesupport (>= 7.0.0) + rack + railties (>= 7.0.0) + psych (5.2.6) + date + stringio + public_suffix (6.0.2) + puma (6.6.0) + nio4r (~> 2.0) + raabro (1.4.0) + racc (1.8.1) + rack (3.1.16) + rack-session (2.1.1) + base64 (>= 0.1.0) + rack (>= 3.0.0) + rack-test (2.2.0) + rack (>= 1.3) + rackup (2.2.1) + rack (>= 3) + rails (8.0.2) + actioncable (= 8.0.2) + actionmailbox (= 8.0.2) + actionmailer (= 8.0.2) + actionpack (= 8.0.2) + actiontext (= 8.0.2) + actionview (= 8.0.2) + activejob (= 8.0.2) + activemodel (= 8.0.2) + activerecord (= 8.0.2) + activestorage (= 8.0.2) + activesupport (= 8.0.2) + bundler (>= 1.15.0) + railties (= 8.0.2) + rails-dom-testing (2.3.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-erd (1.7.2) + activerecord (>= 4.2) + activesupport (>= 4.2) + choice (~> 0.2.0) + ruby-graphviz (~> 1.2) + rails-html-sanitizer (1.6.2) + loofah (~> 2.21) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + railties (8.0.2) + actionpack (= 8.0.2) + activesupport (= 8.0.2) + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + rainbow (3.1.1) + rake (13.3.0) + rdoc (6.14.1) + erb + psych (>= 4.0.0) + regexp_parser (2.10.0) + reline (0.6.1) + io-console (~> 0.5) + rexml (3.4.1) + rubocop (1.77.0) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.45.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.45.1) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-performance (1.25.0) + lint_roller (~> 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.38.0, < 2.0) + rubocop-rails (2.32.0) + activesupport (>= 4.2.0) + lint_roller (~> 1.1) + rack (>= 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) + rubocop-rails-omakase (1.1.0) + rubocop (>= 1.72) + rubocop-performance (>= 1.24) + rubocop-rails (>= 2.30) + ruby-graphviz (1.2.5) + rexml + ruby-progressbar (1.13.0) + rubyzip (2.4.1) + securerandom (0.4.1) + selenium-webdriver (4.33.0) + base64 (~> 0.2) + logger (~> 1.4) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) + solid_cable (3.0.11) + actioncable (>= 7.2) + activejob (>= 7.2) + activerecord (>= 7.2) + railties (>= 7.2) + solid_cache (1.0.7) + activejob (>= 7.2) + activerecord (>= 7.2) + railties (>= 7.2) + solid_queue (1.1.5) + activejob (>= 7.1) + activerecord (>= 7.1) + concurrent-ruby (>= 1.3.1) + fugit (~> 1.11.0) + railties (>= 7.1) + thor (~> 1.3.1) + sqlite3 (2.7.0-aarch64-linux-gnu) + sqlite3 (2.7.0-aarch64-linux-musl) + sqlite3 (2.7.0-arm-linux-gnu) + sqlite3 (2.7.0-arm-linux-musl) + sqlite3 (2.7.0-x86_64-linux-gnu) + sqlite3 (2.7.0-x86_64-linux-musl) + sshkit (1.24.0) + base64 + logger + net-scp (>= 1.1.2) + net-sftp (>= 2.1.2) + net-ssh (>= 2.8.0) + ostruct + stimulus-rails (1.3.4) + railties (>= 6.0.0) + stringio (3.1.7) + thor (1.3.2) + thruster (0.1.14) + thruster (0.1.14-aarch64-linux) + thruster (0.1.14-x86_64-linux) + timeout (0.4.3) + turbo-rails (2.0.16) + actionpack (>= 7.1.0) + railties (>= 7.1.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (3.1.4) + unicode-emoji (~> 4.0, >= 4.0.4) + unicode-emoji (4.0.4) + uri (1.0.3) + useragent (0.16.11) + web-console (4.2.1) + actionview (>= 6.0.0) + activemodel (>= 6.0.0) + bindex (>= 0.4.0) + railties (>= 6.0.0) + websocket (1.2.11) + websocket-driver (0.8.0) + base64 + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + xpath (3.2.0) + nokogiri (~> 1.8) + zeitwerk (2.7.3) + +PLATFORMS + aarch64-linux + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + x86_64-linux + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + bootsnap + brakeman + capybara + debug + importmap-rails + jbuilder + kamal + propshaft + puma (>= 5.0) + rails (~> 8.0.2) + rails-erd + rubocop-rails-omakase + selenium-webdriver + solid_cable + solid_cache + solid_queue + sqlite3 (>= 2.1) + stimulus-rails + thruster + turbo-rails + tzinfo-data + web-console + +BUNDLED WITH + 2.6.9 diff --git a/kontor-rails/README.md b/kontor-rails/README.md new file mode 100644 index 0000000..7db80e4 --- /dev/null +++ b/kontor-rails/README.md @@ -0,0 +1,24 @@ +# README + +This README would normally document whatever steps are necessary to get the +application up and running. + +Things you may want to cover: + +* Ruby version + +* System dependencies + +* Configuration + +* Database creation + +* Database initialization + +* How to run the test suite + +* Services (job queues, cache servers, search engines, etc.) + +* Deployment instructions + +* ... diff --git a/kontor-rails/Rakefile b/kontor-rails/Rakefile new file mode 100644 index 0000000..9a5ea73 --- /dev/null +++ b/kontor-rails/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require_relative "config/application" + +Rails.application.load_tasks diff --git a/kontor-gui/src/kontor_gui/__init__.py b/kontor-rails/app/assets/images/.keep similarity index 100% rename from kontor-gui/src/kontor_gui/__init__.py rename to kontor-rails/app/assets/images/.keep diff --git a/kontor-rails/app/assets/stylesheets/application.css b/kontor-rails/app/assets/stylesheets/application.css new file mode 100644 index 0000000..fe93333 --- /dev/null +++ b/kontor-rails/app/assets/stylesheets/application.css @@ -0,0 +1,10 @@ +/* + * This is a manifest file that'll be compiled into application.css. + * + * With Propshaft, assets are served efficiently without preprocessing steps. You can still include + * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard + * cascading order, meaning styles declared later in the document or manifest will override earlier ones, + * depending on specificity. + * + * Consider organizing styles into separate files for maintainability. + */ diff --git a/kontor-rails/app/controllers/application_controller.rb b/kontor-rails/app/controllers/application_controller.rb new file mode 100644 index 0000000..0d95db2 --- /dev/null +++ b/kontor-rails/app/controllers/application_controller.rb @@ -0,0 +1,4 @@ +class ApplicationController < ActionController::Base + # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. + allow_browser versions: :modern +end diff --git a/kontor-gui/tests/__init__.py b/kontor-rails/app/controllers/concerns/.keep similarity index 100% rename from kontor-gui/tests/__init__.py rename to kontor-rails/app/controllers/concerns/.keep diff --git a/kontor-rails/app/controllers/publisher_controller.rb b/kontor-rails/app/controllers/publisher_controller.rb new file mode 100644 index 0000000..a407b81 --- /dev/null +++ b/kontor-rails/app/controllers/publisher_controller.rb @@ -0,0 +1,4 @@ +class PublisherController < ApplicationController + def index + end +end diff --git a/kontor-rails/app/helpers/application_helper.rb b/kontor-rails/app/helpers/application_helper.rb new file mode 100644 index 0000000..de6be79 --- /dev/null +++ b/kontor-rails/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/kontor-rails/app/helpers/publisher_helper.rb b/kontor-rails/app/helpers/publisher_helper.rb new file mode 100644 index 0000000..0284dee --- /dev/null +++ b/kontor-rails/app/helpers/publisher_helper.rb @@ -0,0 +1,2 @@ +module PublisherHelper +end diff --git a/kontor-rails/app/javascript/application.js b/kontor-rails/app/javascript/application.js new file mode 100644 index 0000000..0d7b494 --- /dev/null +++ b/kontor-rails/app/javascript/application.js @@ -0,0 +1,3 @@ +// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails +import "@hotwired/turbo-rails" +import "controllers" diff --git a/kontor-rails/app/javascript/controllers/application.js b/kontor-rails/app/javascript/controllers/application.js new file mode 100644 index 0000000..1213e85 --- /dev/null +++ b/kontor-rails/app/javascript/controllers/application.js @@ -0,0 +1,9 @@ +import { Application } from "@hotwired/stimulus" + +const application = Application.start() + +// Configure Stimulus development experience +application.debug = false +window.Stimulus = application + +export { application } diff --git a/kontor-rails/app/javascript/controllers/hello_controller.js b/kontor-rails/app/javascript/controllers/hello_controller.js new file mode 100644 index 0000000..5975c07 --- /dev/null +++ b/kontor-rails/app/javascript/controllers/hello_controller.js @@ -0,0 +1,7 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + connect() { + this.element.textContent = "Hello World!" + } +} diff --git a/kontor-rails/app/javascript/controllers/index.js b/kontor-rails/app/javascript/controllers/index.js new file mode 100644 index 0000000..1156bf8 --- /dev/null +++ b/kontor-rails/app/javascript/controllers/index.js @@ -0,0 +1,4 @@ +// Import and register all your controllers from the importmap via controllers/**/*_controller +import { application } from "controllers/application" +import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" +eagerLoadControllersFrom("controllers", application) diff --git a/kontor-rails/app/jobs/application_job.rb b/kontor-rails/app/jobs/application_job.rb new file mode 100644 index 0000000..d394c3d --- /dev/null +++ b/kontor-rails/app/jobs/application_job.rb @@ -0,0 +1,7 @@ +class ApplicationJob < ActiveJob::Base + # Automatically retry jobs that encountered a deadlock + # retry_on ActiveRecord::Deadlocked + + # Most jobs are safe to ignore if the underlying records are no longer available + # discard_on ActiveJob::DeserializationError +end diff --git a/kontor-rails/app/mailers/application_mailer.rb b/kontor-rails/app/mailers/application_mailer.rb new file mode 100644 index 0000000..3c34c81 --- /dev/null +++ b/kontor-rails/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: "from@example.com" + layout "mailer" +end diff --git a/kontor-rails/app/models/application_record.rb b/kontor-rails/app/models/application_record.rb new file mode 100644 index 0000000..b63caeb --- /dev/null +++ b/kontor-rails/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + primary_abstract_class +end diff --git a/kontor-rails/app/models/artist.rb b/kontor-rails/app/models/artist.rb new file mode 100644 index 0000000..82a8b73 --- /dev/null +++ b/kontor-rails/app/models/artist.rb @@ -0,0 +1,2 @@ +class Artist < ApplicationRecord +end diff --git a/kontor-rails/app/models/comic.rb b/kontor-rails/app/models/comic.rb new file mode 100644 index 0000000..80f30a3 --- /dev/null +++ b/kontor-rails/app/models/comic.rb @@ -0,0 +1,8 @@ +class Comic < ApplicationRecord + belongs_to :publisher + has_many :issues, optional = true + has_many :story_arcs, optional = true + has_many :trade_paperbacks, optional = true + has_many :volumes, optional = true + has_many :comic_works, optional = true +end diff --git a/kontor-rails/app/models/comic_work.rb b/kontor-rails/app/models/comic_work.rb new file mode 100644 index 0000000..c05ab67 --- /dev/null +++ b/kontor-rails/app/models/comic_work.rb @@ -0,0 +1,2 @@ +class ComicWork < ApplicationRecord +end diff --git a/kontor-scripts/db/__init__.py b/kontor-rails/app/models/concerns/.keep similarity index 100% rename from kontor-scripts/db/__init__.py rename to kontor-rails/app/models/concerns/.keep diff --git a/kontor-rails/app/models/issue.rb b/kontor-rails/app/models/issue.rb new file mode 100644 index 0000000..86d4347 --- /dev/null +++ b/kontor-rails/app/models/issue.rb @@ -0,0 +1,6 @@ +class Issue < ApplicationRecord + belongs_to :comic + belongs_to :volume, optional = true + belongs_to :story_arc, optional = true + has_many :issue_works +end diff --git a/kontor-rails/app/models/issue_work.rb b/kontor-rails/app/models/issue_work.rb new file mode 100644 index 0000000..ab0e4dd --- /dev/null +++ b/kontor-rails/app/models/issue_work.rb @@ -0,0 +1,2 @@ +class IssueWork < ApplicationRecord +end diff --git a/kontor-rails/app/models/publisher.rb b/kontor-rails/app/models/publisher.rb new file mode 100644 index 0000000..6a92294 --- /dev/null +++ b/kontor-rails/app/models/publisher.rb @@ -0,0 +1,4 @@ +class Publisher < ApplicationRecord + has_many :imprints, class_name: "Publisher", foreign_key: "parent_publisher_id" + has_many :comics +end diff --git a/kontor-rails/app/models/story_arc.rb b/kontor-rails/app/models/story_arc.rb new file mode 100644 index 0000000..d32b474 --- /dev/null +++ b/kontor-rails/app/models/story_arc.rb @@ -0,0 +1,5 @@ +class StoryArc < ApplicationRecord + belongs_to :comics + belongs_to :volumes + has_many :issues +end diff --git a/kontor-rails/app/models/trade_paperback.rb b/kontor-rails/app/models/trade_paperback.rb new file mode 100644 index 0000000..01824c4 --- /dev/null +++ b/kontor-rails/app/models/trade_paperback.rb @@ -0,0 +1,3 @@ +class TradePaperback < ApplicationRecord + belongs_to :comics +end diff --git a/kontor-rails/app/models/volume.rb b/kontor-rails/app/models/volume.rb new file mode 100644 index 0000000..87b9f78 --- /dev/null +++ b/kontor-rails/app/models/volume.rb @@ -0,0 +1,5 @@ +class Volume < ApplicationRecord + belongs_to :comics + has_many :story_arcs, optional = true + has_many :issues, optional = true +end diff --git a/kontor-rails/app/models/worktype.rb b/kontor-rails/app/models/worktype.rb new file mode 100644 index 0000000..717c4d2 --- /dev/null +++ b/kontor-rails/app/models/worktype.rb @@ -0,0 +1,2 @@ +class Worktype < ApplicationRecord +end diff --git a/kontor-rails/app/views/layouts/application.html.erb b/kontor-rails/app/views/layouts/application.html.erb new file mode 100644 index 0000000..923cc07 --- /dev/null +++ b/kontor-rails/app/views/layouts/application.html.erb @@ -0,0 +1,28 @@ + + + + <%= content_for(:title) || "Kontor Rails" %> + + + + <%= csrf_meta_tags %> + <%= csp_meta_tag %> + + <%= yield :head %> + + <%# Enable PWA manifest for installable apps (make sure to enable in config/routes.rb too!) %> + <%#= tag.link rel: "manifest", href: pwa_manifest_path(format: :json) %> + + + + + + <%# Includes all stylesheet files in app/assets/stylesheets %> + <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %> + <%= javascript_importmap_tags %> + + + + <%= yield %> + + diff --git a/kontor-rails/app/views/layouts/mailer.html.erb b/kontor-rails/app/views/layouts/mailer.html.erb new file mode 100644 index 0000000..3aac900 --- /dev/null +++ b/kontor-rails/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/kontor-rails/app/views/layouts/mailer.text.erb b/kontor-rails/app/views/layouts/mailer.text.erb new file mode 100644 index 0000000..37f0bdd --- /dev/null +++ b/kontor-rails/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/kontor-rails/app/views/publisher/index.html.erb b/kontor-rails/app/views/publisher/index.html.erb new file mode 100644 index 0000000..b1231ad --- /dev/null +++ b/kontor-rails/app/views/publisher/index.html.erb @@ -0,0 +1,2 @@ +

    Publisher#index

    +

    Find me in app/views/publisher/index.html.erb

    diff --git a/kontor-rails/app/views/pwa/manifest.json.erb b/kontor-rails/app/views/pwa/manifest.json.erb new file mode 100644 index 0000000..d9ba711 --- /dev/null +++ b/kontor-rails/app/views/pwa/manifest.json.erb @@ -0,0 +1,22 @@ +{ + "name": "KontorRails", + "icons": [ + { + "src": "/icon.png", + "type": "image/png", + "sizes": "512x512" + }, + { + "src": "/icon.png", + "type": "image/png", + "sizes": "512x512", + "purpose": "maskable" + } + ], + "start_url": "/", + "display": "standalone", + "scope": "/", + "description": "KontorRails.", + "theme_color": "red", + "background_color": "red" +} diff --git a/kontor-rails/app/views/pwa/service-worker.js b/kontor-rails/app/views/pwa/service-worker.js new file mode 100644 index 0000000..b3a13fb --- /dev/null +++ b/kontor-rails/app/views/pwa/service-worker.js @@ -0,0 +1,26 @@ +// Add a service worker for processing Web Push notifications: +// +// self.addEventListener("push", async (event) => { +// const { title, options } = await event.data.json() +// event.waitUntil(self.registration.showNotification(title, options)) +// }) +// +// self.addEventListener("notificationclick", function(event) { +// event.notification.close() +// event.waitUntil( +// clients.matchAll({ type: "window" }).then((clientList) => { +// for (let i = 0; i < clientList.length; i++) { +// let client = clientList[i] +// let clientPath = (new URL(client.url)).pathname +// +// if (clientPath == event.notification.data.path && "focus" in client) { +// return client.focus() +// } +// } +// +// if (clients.openWindow) { +// return clients.openWindow(event.notification.data.path) +// } +// }) +// ) +// }) diff --git a/kontor-rails/bin/brakeman b/kontor-rails/bin/brakeman new file mode 100755 index 0000000..ace1c9b --- /dev/null +++ b/kontor-rails/bin/brakeman @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +ARGV.unshift("--ensure-latest") + +load Gem.bin_path("brakeman", "brakeman") diff --git a/kontor-rails/bin/bundle b/kontor-rails/bin/bundle new file mode 100755 index 0000000..50da5fd --- /dev/null +++ b/kontor-rails/bin/bundle @@ -0,0 +1,109 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'bundle' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "rubygems" + +m = Module.new do + module_function + + def invoked_as_script? + File.expand_path($0) == File.expand_path(__FILE__) + end + + def env_var_version + ENV["BUNDLER_VERSION"] + end + + def cli_arg_version + return unless invoked_as_script? # don't want to hijack other binstubs + return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` + bundler_version = nil + update_index = nil + ARGV.each_with_index do |a, i| + if update_index && update_index.succ == i && a.match?(Gem::Version::ANCHORED_VERSION_PATTERN) + bundler_version = a + end + next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/ + bundler_version = $1 + update_index = i + end + bundler_version + end + + def gemfile + gemfile = ENV["BUNDLE_GEMFILE"] + return gemfile if gemfile && !gemfile.empty? + + File.expand_path("../Gemfile", __dir__) + end + + def lockfile + lockfile = + case File.basename(gemfile) + when "gems.rb" then gemfile.sub(/\.rb$/, ".locked") + else "#{gemfile}.lock" + end + File.expand_path(lockfile) + end + + def lockfile_version + return unless File.file?(lockfile) + lockfile_contents = File.read(lockfile) + return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/ + Regexp.last_match(1) + end + + def bundler_requirement + @bundler_requirement ||= + env_var_version || + cli_arg_version || + bundler_requirement_for(lockfile_version) + end + + def bundler_requirement_for(version) + return "#{Gem::Requirement.default}.a" unless version + + bundler_gem_version = Gem::Version.new(version) + + bundler_gem_version.approximate_recommendation + end + + def load_bundler! + ENV["BUNDLE_GEMFILE"] ||= gemfile + + activate_bundler + end + + def activate_bundler + gem_error = activation_error_handling do + gem "bundler", bundler_requirement + end + return if gem_error.nil? + require_error = activation_error_handling do + require "bundler/version" + end + return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) + warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`" + exit 42 + end + + def activation_error_handling + yield + nil + rescue StandardError, LoadError => e + e + end +end + +m.load_bundler! + +if m.invoked_as_script? + load Gem.bin_path("bundler", "bundle") +end diff --git a/kontor-rails/bin/dev b/kontor-rails/bin/dev new file mode 100755 index 0000000..5f91c20 --- /dev/null +++ b/kontor-rails/bin/dev @@ -0,0 +1,2 @@ +#!/usr/bin/env ruby +exec "./bin/rails", "server", *ARGV diff --git a/kontor-rails/bin/docker-entrypoint b/kontor-rails/bin/docker-entrypoint new file mode 100755 index 0000000..57567d6 --- /dev/null +++ b/kontor-rails/bin/docker-entrypoint @@ -0,0 +1,14 @@ +#!/bin/bash -e + +# Enable jemalloc for reduced memory usage and latency. +if [ -z "${LD_PRELOAD+x}" ]; then + LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit) + export LD_PRELOAD +fi + +# If running the rails server then create or migrate existing database +if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then + ./bin/rails db:prepare +fi + +exec "${@}" diff --git a/kontor-rails/bin/importmap b/kontor-rails/bin/importmap new file mode 100755 index 0000000..36502ab --- /dev/null +++ b/kontor-rails/bin/importmap @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby + +require_relative "../config/application" +require "importmap/commands" diff --git a/kontor-rails/bin/jobs b/kontor-rails/bin/jobs new file mode 100755 index 0000000..dcf59f3 --- /dev/null +++ b/kontor-rails/bin/jobs @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby + +require_relative "../config/environment" +require "solid_queue/cli" + +SolidQueue::Cli.start(ARGV) diff --git a/kontor-rails/bin/kamal b/kontor-rails/bin/kamal new file mode 100755 index 0000000..cbe59b9 --- /dev/null +++ b/kontor-rails/bin/kamal @@ -0,0 +1,27 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'kamal' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +bundle_binstub = File.expand_path("bundle", __dir__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") + load(bundle_binstub) + else + abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. +Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") + end +end + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("kamal", "kamal") diff --git a/kontor-rails/bin/rails b/kontor-rails/bin/rails new file mode 100755 index 0000000..efc0377 --- /dev/null +++ b/kontor-rails/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path("../config/application", __dir__) +require_relative "../config/boot" +require "rails/commands" diff --git a/kontor-rails/bin/rake b/kontor-rails/bin/rake new file mode 100755 index 0000000..4fbf10b --- /dev/null +++ b/kontor-rails/bin/rake @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +require_relative "../config/boot" +require "rake" +Rake.application.run diff --git a/kontor-rails/bin/rubocop b/kontor-rails/bin/rubocop new file mode 100755 index 0000000..40330c0 --- /dev/null +++ b/kontor-rails/bin/rubocop @@ -0,0 +1,8 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +# explicit rubocop config increases performance slightly while avoiding config confusion. +ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) + +load Gem.bin_path("rubocop", "rubocop") diff --git a/kontor-rails/bin/setup b/kontor-rails/bin/setup new file mode 100755 index 0000000..be3db3c --- /dev/null +++ b/kontor-rails/bin/setup @@ -0,0 +1,34 @@ +#!/usr/bin/env ruby +require "fileutils" + +APP_ROOT = File.expand_path("..", __dir__) + +def system!(*args) + system(*args, exception: true) +end + +FileUtils.chdir APP_ROOT do + # This script is a way to set up or update your development environment automatically. + # This script is idempotent, so that you can run it at any time and get an expectable outcome. + # Add necessary setup steps to this file. + + puts "== Installing dependencies ==" + system("bundle check") || system!("bundle install") + + # puts "\n== Copying sample files ==" + # unless File.exist?("config/database.yml") + # FileUtils.cp "config/database.yml.sample", "config/database.yml" + # end + + puts "\n== Preparing database ==" + system! "bin/rails db:prepare" + + puts "\n== Removing old logs and tempfiles ==" + system! "bin/rails log:clear tmp:clear" + + unless ARGV.include?("--skip-server") + puts "\n== Starting development server ==" + STDOUT.flush # flush the output before exec(2) so that it displays + exec "bin/dev" + end +end diff --git a/kontor-rails/bin/thrust b/kontor-rails/bin/thrust new file mode 100755 index 0000000..36bde2d --- /dev/null +++ b/kontor-rails/bin/thrust @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("thruster", "thrust") diff --git a/kontor-rails/config.ru b/kontor-rails/config.ru new file mode 100644 index 0000000..4a3c09a --- /dev/null +++ b/kontor-rails/config.ru @@ -0,0 +1,6 @@ +# This file is used by Rack-based servers to start the application. + +require_relative "config/environment" + +run Rails.application +Rails.application.load_server diff --git a/kontor-rails/config/application.rb b/kontor-rails/config/application.rb new file mode 100644 index 0000000..da6e3be --- /dev/null +++ b/kontor-rails/config/application.rb @@ -0,0 +1,27 @@ +require_relative "boot" + +require "rails/all" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module KontorRails + class Application < Rails::Application + # Initialize configuration defaults for originally generated Rails version. + config.load_defaults 8.0 + + # Please, add to the `ignore` list any other `lib` subdirectories that do + # not contain `.rb` files, or that should not be reloaded or eager loaded. + # Common ones are `templates`, `generators`, or `middleware`, for example. + config.autoload_lib(ignore: %w[assets tasks]) + + # Configuration for the application, engines, and railties goes here. + # + # These settings can be overridden in specific environments using the files + # in config/environments, which are processed later. + # + # config.time_zone = "Central Time (US & Canada)" + # config.eager_load_paths << Rails.root.join("extras") + end +end diff --git a/kontor-rails/config/boot.rb b/kontor-rails/config/boot.rb new file mode 100644 index 0000000..988a5dd --- /dev/null +++ b/kontor-rails/config/boot.rb @@ -0,0 +1,4 @@ +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +require "bundler/setup" # Set up gems listed in the Gemfile. +require "bootsnap/setup" # Speed up boot time by caching expensive operations. diff --git a/kontor-rails/config/cable.yml b/kontor-rails/config/cable.yml new file mode 100644 index 0000000..b9adc5a --- /dev/null +++ b/kontor-rails/config/cable.yml @@ -0,0 +1,17 @@ +# Async adapter only works within the same process, so for manually triggering cable updates from a console, +# and seeing results in the browser, you must do so from the web console (running inside the dev process), +# not a terminal started via bin/rails console! Add "console" to any action or any ERB template view +# to make the web console appear. +development: + adapter: async + +test: + adapter: test + +production: + adapter: solid_cable + connects_to: + database: + writing: cable + polling_interval: 0.1.seconds + message_retention: 1.day diff --git a/kontor-rails/config/cache.yml b/kontor-rails/config/cache.yml new file mode 100644 index 0000000..19d4908 --- /dev/null +++ b/kontor-rails/config/cache.yml @@ -0,0 +1,16 @@ +default: &default + store_options: + # Cap age of oldest cache entry to fulfill retention policies + # max_age: <%= 60.days.to_i %> + max_size: <%= 256.megabytes %> + namespace: <%= Rails.env %> + +development: + <<: *default + +test: + <<: *default + +production: + database: cache + <<: *default diff --git a/kontor-rails/config/credentials.yml.enc b/kontor-rails/config/credentials.yml.enc new file mode 100644 index 0000000..1f8f699 --- /dev/null +++ b/kontor-rails/config/credentials.yml.enc @@ -0,0 +1 @@ +t8FSFiJrxGKOHpFnBBeN9S63fGe9snKet6ZYLZlBJjUjOS8hoDkfSQt3BHgx/mxWBzW7W/eFWKBiKdzE36CyF06WdnTzo4pjIuObhvciymfhhLuo0q4jI423V+xsU93dUHyh8I5aTjYhRD/Lv/qOdqMjciAswI4OoExj0QBqDcZjpHzaESA8ZdZIXsbYbz71A5e7aJwoWEqHrPuuoVDmc2S/N3CRJqQ0BWw3uw/RUv+5gGiaTOJ4KFpNPZCV2+msinPVJpFIRq+1cNqFkFougaNUwx5ZoRTBG8nDRzG+9qm075p8MtmVTxOAyJOguAlnn147ynr2FBQZkaQRm1/WsQ3exRNcgcmEe0RRHu8aGt/WjJt+agjyPbd+Id1VhenCj1Y6viEyd/D09T5yuPsor+qhP7lINFcrCrx/aAsQ+Fge+RjyKzCpvd9m/XHuK0ifQOWgoFyL7vzhdJSHIh1v/zPIBbky4C4kavxwfa2oIJyRiM+v9p5iViIj--MAt5kpQ++sIpKuf0--Ff2KX/WtcoorBRz21SYiKg== \ No newline at end of file diff --git a/kontor-rails/config/database.yml b/kontor-rails/config/database.yml new file mode 100644 index 0000000..2640cb5 --- /dev/null +++ b/kontor-rails/config/database.yml @@ -0,0 +1,41 @@ +# SQLite. Versions 3.8.0 and up are supported. +# gem install sqlite3 +# +# Ensure the SQLite 3 gem is defined in your Gemfile +# gem "sqlite3" +# +default: &default + adapter: sqlite3 + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + timeout: 5000 + +development: + <<: *default + database: storage/development.sqlite3 + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: storage/test.sqlite3 + + +# Store production database in the storage/ directory, which by default +# is mounted as a persistent Docker volume in config/deploy.yml. +production: + primary: + <<: *default + database: storage/production.sqlite3 + cache: + <<: *default + database: storage/production_cache.sqlite3 + migrations_paths: db/cache_migrate + queue: + <<: *default + database: storage/production_queue.sqlite3 + migrations_paths: db/queue_migrate + cable: + <<: *default + database: storage/production_cable.sqlite3 + migrations_paths: db/cable_migrate diff --git a/kontor-rails/config/deploy.yml b/kontor-rails/config/deploy.yml new file mode 100644 index 0000000..1df4a3b --- /dev/null +++ b/kontor-rails/config/deploy.yml @@ -0,0 +1,116 @@ +# Name of your application. Used to uniquely configure containers. +service: kontor_rails + +# Name of the container image. +image: your-user/kontor_rails + +# Deploy to these servers. +servers: + web: + - 192.168.0.1 + # job: + # hosts: + # - 192.168.0.1 + # cmd: bin/jobs + +# Enable SSL auto certification via Let's Encrypt and allow for multiple apps on a single web server. +# Remove this section when using multiple web servers and ensure you terminate SSL at your load balancer. +# +# Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption. +proxy: + ssl: true + host: app.example.com + +# Credentials for your image host. +registry: + # Specify the registry server, if you're not using Docker Hub + # server: registry.digitalocean.com / ghcr.io / ... + username: your-user + + # Always use an access token rather than real password when possible. + password: + - KAMAL_REGISTRY_PASSWORD + +# Inject ENV variables into containers (secrets come from .kamal/secrets). +env: + secret: + - RAILS_MASTER_KEY + clear: + # Run the Solid Queue Supervisor inside the web server's Puma process to do jobs. + # When you start using multiple servers, you should split out job processing to a dedicated machine. + SOLID_QUEUE_IN_PUMA: true + + # Set number of processes dedicated to Solid Queue (default: 1) + # JOB_CONCURRENCY: 3 + + # Set number of cores available to the application on each server (default: 1). + # WEB_CONCURRENCY: 2 + + # Match this to any external database server to configure Active Record correctly + # Use kontor_rails-db for a db accessory server on same machine via local kamal docker network. + # DB_HOST: 192.168.0.2 + + # Log everything from Rails + # RAILS_LOG_LEVEL: debug + +# Aliases are triggered with "bin/kamal ". You can overwrite arguments on invocation: +# "bin/kamal logs -r job" will tail logs from the first server in the job section. +aliases: + console: app exec --interactive --reuse "bin/rails console" + shell: app exec --interactive --reuse "bash" + logs: app logs -f + dbc: app exec --interactive --reuse "bin/rails dbconsole" + + +# Use a persistent storage volume for sqlite database files and local Active Storage files. +# Recommended to change this to a mounted volume path that is backed up off server. +volumes: + - "kontor_rails_storage:/rails/storage" + + +# Bridge fingerprinted assets, like JS and CSS, between versions to avoid +# hitting 404 on in-flight requests. Combines all files from new and old +# version inside the asset_path. +asset_path: /rails/public/assets + +# Configure the image builder. +builder: + arch: amd64 + + # # Build image via remote server (useful for faster amd64 builds on arm64 computers) + # remote: ssh://docker@docker-builder-server + # + # # Pass arguments and secrets to the Docker build process + # args: + # RUBY_VERSION: ruby-3.4.4 + # secrets: + # - GITHUB_TOKEN + # - RAILS_MASTER_KEY + +# Use a different ssh user than root +# ssh: +# user: app + +# Use accessory services (secrets come from .kamal/secrets). +# accessories: +# db: +# image: mysql:8.0 +# host: 192.168.0.2 +# # Change to 3306 to expose port to the world instead of just local network. +# port: "127.0.0.1:3306:3306" +# env: +# clear: +# MYSQL_ROOT_HOST: '%' +# secret: +# - MYSQL_ROOT_PASSWORD +# files: +# - config/mysql/production.cnf:/etc/mysql/my.cnf +# - db/production.sql:/docker-entrypoint-initdb.d/setup.sql +# directories: +# - data:/var/lib/mysql +# redis: +# image: redis:7.0 +# host: 192.168.0.2 +# port: 6379 +# directories: +# - data:/data diff --git a/kontor-rails/config/environment.rb b/kontor-rails/config/environment.rb new file mode 100644 index 0000000..cac5315 --- /dev/null +++ b/kontor-rails/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative "application" + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/kontor-rails/config/environments/development.rb b/kontor-rails/config/environments/development.rb new file mode 100644 index 0000000..4cc21c4 --- /dev/null +++ b/kontor-rails/config/environments/development.rb @@ -0,0 +1,72 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Make code changes take effect immediately without server restart. + config.enable_reloading = true + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable server timing. + config.server_timing = true + + # Enable/disable Action Controller caching. By default Action Controller caching is disabled. + # Run rails dev:cache to toggle Action Controller caching. + if Rails.root.join("tmp/caching-dev.txt").exist? + config.action_controller.perform_caching = true + config.action_controller.enable_fragment_cache_logging = true + config.public_file_server.headers = { "cache-control" => "public, max-age=#{2.days.to_i}" } + else + config.action_controller.perform_caching = false + end + + # Change to :null_store to avoid any caching. + config.cache_store = :memory_store + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + # Make template changes take effect immediately. + config.action_mailer.perform_caching = false + + # Set localhost to be used by links generated in mailer templates. + config.action_mailer.default_url_options = { host: "localhost", port: 3000 } + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + + # Append comments with runtime information tags to SQL queries in logs. + config.active_record.query_log_tags_enabled = true + + # Highlight code that enqueued background job in logs. + config.active_job.verbose_enqueue_logs = true + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + config.action_view.annotate_rendered_view_with_filenames = true + + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true + + # Raise error when a before_action's only/except options reference missing actions. + config.action_controller.raise_on_missing_callback_actions = true + + # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. + # config.generators.apply_rubocop_autocorrect_after_generate! +end diff --git a/kontor-rails/config/environments/production.rb b/kontor-rails/config/environments/production.rb new file mode 100644 index 0000000..bdcd01d --- /dev/null +++ b/kontor-rails/config/environments/production.rb @@ -0,0 +1,90 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.enable_reloading = false + + # Eager load code on boot for better performance and memory savings (ignored by Rake tasks). + config.eager_load = true + + # Full error reports are disabled. + config.consider_all_requests_local = false + + # Turn on fragment caching in view templates. + config.action_controller.perform_caching = true + + # Cache assets for far-future expiry since they are all digest stamped. + config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" } + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.asset_host = "http://assets.example.com" + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Assume all access to the app is happening through a SSL-terminating reverse proxy. + config.assume_ssl = true + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + config.force_ssl = true + + # Skip http-to-https redirect for the default health check endpoint. + # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } + + # Log to STDOUT with the current request id as a default log tag. + config.log_tags = [ :request_id ] + config.logger = ActiveSupport::TaggedLogging.logger(STDOUT) + + # Change to "debug" to log everything (including potentially personally-identifiable information!) + config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") + + # Prevent health checks from clogging up the logs. + config.silence_healthcheck_path = "/up" + + # Don't log any deprecations. + config.active_support.report_deprecations = false + + # Replace the default in-process memory cache store with a durable alternative. + config.cache_store = :solid_cache_store + + # Replace the default in-process and non-durable queuing backend for Active Job. + config.active_job.queue_adapter = :solid_queue + config.solid_queue.connects_to = { database: { writing: :queue } } + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Set host to be used by links generated in mailer templates. + config.action_mailer.default_url_options = { host: "example.com" } + + # Specify outgoing SMTP server. Remember to add smtp/* credentials via rails credentials:edit. + # config.action_mailer.smtp_settings = { + # user_name: Rails.application.credentials.dig(:smtp, :user_name), + # password: Rails.application.credentials.dig(:smtp, :password), + # address: "smtp.example.com", + # port: 587, + # authentication: :plain + # } + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false + + # Only use :id for inspections in production. + config.active_record.attributes_for_inspect = [ :id ] + + # Enable DNS rebinding protection and other `Host` header attacks. + # config.hosts = [ + # "example.com", # Allow requests from example.com + # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` + # ] + # + # Skip DNS rebinding protection for the default health check endpoint. + # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } +end diff --git a/kontor-rails/config/environments/test.rb b/kontor-rails/config/environments/test.rb new file mode 100644 index 0000000..c2095b1 --- /dev/null +++ b/kontor-rails/config/environments/test.rb @@ -0,0 +1,53 @@ +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # While tests run files are not watched, reloading is not necessary. + config.enable_reloading = false + + # Eager loading loads your entire application. When running a single test locally, + # this is usually not necessary, and can slow down your test suite. However, it's + # recommended that you enable it in continuous integration systems to ensure eager + # loading is working properly before deploying your code. + config.eager_load = ENV["CI"].present? + + # Configure public file server for tests with cache-control for performance. + config.public_file_server.headers = { "cache-control" => "public, max-age=3600" } + + # Show full error reports. + config.consider_all_requests_local = true + config.cache_store = :null_store + + # Render exception templates for rescuable exceptions and raise for other exceptions. + config.action_dispatch.show_exceptions = :rescuable + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory. + config.active_storage.service = :test + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Set host to be used by links generated in mailer templates. + config.action_mailer.default_url_options = { host: "example.com" } + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true + + # Raise error when a before_action's only/except options reference missing actions. + config.action_controller.raise_on_missing_callback_actions = true +end diff --git a/kontor-rails/config/importmap.rb b/kontor-rails/config/importmap.rb new file mode 100644 index 0000000..909dfc5 --- /dev/null +++ b/kontor-rails/config/importmap.rb @@ -0,0 +1,7 @@ +# Pin npm packages by running ./bin/importmap + +pin "application" +pin "@hotwired/turbo-rails", to: "turbo.min.js" +pin "@hotwired/stimulus", to: "stimulus.min.js" +pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" +pin_all_from "app/javascript/controllers", under: "controllers" diff --git a/kontor-rails/config/initializers/assets.rb b/kontor-rails/config/initializers/assets.rb new file mode 100644 index 0000000..4873244 --- /dev/null +++ b/kontor-rails/config/initializers/assets.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = "1.0" + +# Add additional assets to the asset load path. +# Rails.application.config.assets.paths << Emoji.images_path diff --git a/kontor-rails/config/initializers/content_security_policy.rb b/kontor-rails/config/initializers/content_security_policy.rb new file mode 100644 index 0000000..b3076b3 --- /dev/null +++ b/kontor-rails/config/initializers/content_security_policy.rb @@ -0,0 +1,25 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide content security policy. +# See the Securing Rails Applications Guide for more information: +# https://guides.rubyonrails.org/security.html#content-security-policy-header + +# Rails.application.configure do +# config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end +# +# # Generate session nonces for permitted importmap, inline scripts, and inline styles. +# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } +# config.content_security_policy_nonce_directives = %w(script-src style-src) +# +# # Report violations without enforcing the policy. +# # config.content_security_policy_report_only = true +# end diff --git a/kontor-rails/config/initializers/filter_parameter_logging.rb b/kontor-rails/config/initializers/filter_parameter_logging.rb new file mode 100644 index 0000000..c0b717f --- /dev/null +++ b/kontor-rails/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. +# Use this to limit dissemination of sensitive information. +# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. +Rails.application.config.filter_parameters += [ + :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc +] diff --git a/kontor-rails/config/initializers/inflections.rb b/kontor-rails/config/initializers/inflections.rb new file mode 100644 index 0000000..3860f65 --- /dev/null +++ b/kontor-rails/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, "\\1en" +# inflect.singular /^(ox)en/i, "\\1" +# inflect.irregular "person", "people" +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym "RESTful" +# end diff --git a/kontor-rails/config/locales/en.yml b/kontor-rails/config/locales/en.yml new file mode 100644 index 0000000..6c349ae --- /dev/null +++ b/kontor-rails/config/locales/en.yml @@ -0,0 +1,31 @@ +# Files in the config/locales directory are used for internationalization and +# are automatically loaded by Rails. If you want to use locales other than +# English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t "hello" +# +# In views, this is aliased to just `t`: +# +# <%= t("hello") %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# To learn more about the API, please read the Rails Internationalization guide +# at https://guides.rubyonrails.org/i18n.html. +# +# Be aware that YAML interprets the following case-insensitive strings as +# booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings +# must be quoted to be interpreted as strings. For example: +# +# en: +# "yes": yup +# enabled: "ON" + +en: + hello: "Hello world" diff --git a/kontor-rails/config/puma.rb b/kontor-rails/config/puma.rb new file mode 100644 index 0000000..6c88450 --- /dev/null +++ b/kontor-rails/config/puma.rb @@ -0,0 +1,41 @@ +# This configuration file will be evaluated by Puma. The top-level methods that +# are invoked here are part of Puma's configuration DSL. For more information +# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html. +# +# Puma starts a configurable number of processes (workers) and each process +# serves each request in a thread from an internal thread pool. +# +# You can control the number of workers using ENV["WEB_CONCURRENCY"]. You +# should only set this value when you want to run 2 or more workers. The +# default is already 1. +# +# The ideal number of threads per worker depends both on how much time the +# application spends waiting for IO operations and on how much you wish to +# prioritize throughput over latency. +# +# As a rule of thumb, increasing the number of threads will increase how much +# traffic a given process can handle (throughput), but due to CRuby's +# Global VM Lock (GVL) it has diminishing returns and will degrade the +# response time (latency) of the application. +# +# The default is set to 3 threads as it's deemed a decent compromise between +# throughput and latency for the average Rails application. +# +# Any libraries that use a connection pool or another resource pool should +# be configured to provide at least as many connections as the number of +# threads. This includes Active Record's `pool` parameter in `database.yml`. +threads_count = ENV.fetch("RAILS_MAX_THREADS", 3) +threads threads_count, threads_count + +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +port ENV.fetch("PORT", 7000) + +# Allow puma to be restarted by `bin/rails restart` command. +plugin :tmp_restart + +# Run the Solid Queue supervisor inside of Puma for single-server deployments +plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"] + +# Specify the PID file. Defaults to tmp/pids/server.pid in development. +# In other environments, only set the PID file if requested. +pidfile ENV["PIDFILE"] if ENV["PIDFILE"] diff --git a/kontor-rails/config/queue.yml b/kontor-rails/config/queue.yml new file mode 100644 index 0000000..9eace59 --- /dev/null +++ b/kontor-rails/config/queue.yml @@ -0,0 +1,18 @@ +default: &default + dispatchers: + - polling_interval: 1 + batch_size: 500 + workers: + - queues: "*" + threads: 3 + processes: <%= ENV.fetch("JOB_CONCURRENCY", 1) %> + polling_interval: 0.1 + +development: + <<: *default + +test: + <<: *default + +production: + <<: *default diff --git a/kontor-rails/config/recurring.yml b/kontor-rails/config/recurring.yml new file mode 100644 index 0000000..d045b19 --- /dev/null +++ b/kontor-rails/config/recurring.yml @@ -0,0 +1,10 @@ +# production: +# periodic_cleanup: +# class: CleanSoftDeletedRecordsJob +# queue: background +# args: [ 1000, { batch_size: 500 } ] +# schedule: every hour +# periodic_command: +# command: "SoftDeletedRecord.due.delete_all" +# priority: 2 +# schedule: at 5am every day diff --git a/kontor-rails/config/routes.rb b/kontor-rails/config/routes.rb new file mode 100644 index 0000000..46aa3ec --- /dev/null +++ b/kontor-rails/config/routes.rb @@ -0,0 +1,15 @@ +Rails.application.routes.draw do + get "/comic/publishers/", to: "publisher#index" + # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html + + # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. + # Can be used by load balancers and uptime monitors to verify that the app is live. + get "up" => "rails/health#show", as: :rails_health_check + + # Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb) + # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest + # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker + + # Defines the root path route ("/") + # root "posts#index" +end diff --git a/kontor-rails/config/storage.yml b/kontor-rails/config/storage.yml new file mode 100644 index 0000000..4942ab6 --- /dev/null +++ b/kontor-rails/config/storage.yml @@ -0,0 +1,34 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) +# amazon: +# service: S3 +# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> +# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> +# region: us-east-1 +# bucket: your_own_bucket-<%= Rails.env %> + +# Remember not to checkin your GCS keyfile to a repository +# google: +# service: GCS +# project: your_project +# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> +# bucket: your_own_bucket-<%= Rails.env %> + +# Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) +# microsoft: +# service: AzureStorage +# storage_account_name: your_account_name +# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> +# container: your_container_name-<%= Rails.env %> + +# mirror: +# service: Mirror +# primary: local +# mirrors: [ amazon, google, microsoft ] diff --git a/kontor-rails/db/cable_schema.rb b/kontor-rails/db/cable_schema.rb new file mode 100644 index 0000000..2366660 --- /dev/null +++ b/kontor-rails/db/cable_schema.rb @@ -0,0 +1,11 @@ +ActiveRecord::Schema[7.1].define(version: 1) do + create_table "solid_cable_messages", force: :cascade do |t| + t.binary "channel", limit: 1024, null: false + t.binary "payload", limit: 536870912, null: false + t.datetime "created_at", null: false + t.integer "channel_hash", limit: 8, null: false + t.index ["channel"], name: "index_solid_cable_messages_on_channel" + t.index ["channel_hash"], name: "index_solid_cable_messages_on_channel_hash" + t.index ["created_at"], name: "index_solid_cable_messages_on_created_at" + end +end diff --git a/kontor-rails/db/cache_schema.rb b/kontor-rails/db/cache_schema.rb new file mode 100644 index 0000000..6005a29 --- /dev/null +++ b/kontor-rails/db/cache_schema.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +ActiveRecord::Schema[7.2].define(version: 1) do + create_table "solid_cache_entries", force: :cascade do |t| + t.binary "key", limit: 1024, null: false + t.binary "value", limit: 536870912, null: false + t.datetime "created_at", null: false + t.integer "key_hash", limit: 8, null: false + t.integer "byte_size", limit: 4, null: false + t.index ["byte_size"], name: "index_solid_cache_entries_on_byte_size" + t.index ["key_hash", "byte_size"], name: "index_solid_cache_entries_on_key_hash_and_byte_size" + t.index ["key_hash"], name: "index_solid_cache_entries_on_key_hash", unique: true + end +end diff --git a/kontor-rails/db/migrate/20250626095145_create_publishers.rb b/kontor-rails/db/migrate/20250626095145_create_publishers.rb new file mode 100644 index 0000000..8cd1a7d --- /dev/null +++ b/kontor-rails/db/migrate/20250626095145_create_publishers.rb @@ -0,0 +1,13 @@ +class CreatePublishers < ActiveRecord::Migration[8.0] + def change + create_table :publishers do |t| + t.datetime :created_date + t.datetime :last_modified_date + t.integer :version + t.string :name + t.string :weblink + t.string :parent_publisher_id + end + change_column :publishers, :id, :string + end +end diff --git a/kontor-rails/db/migrate/20250626095203_create_comics.rb b/kontor-rails/db/migrate/20250626095203_create_comics.rb new file mode 100644 index 0000000..d9e8cb5 --- /dev/null +++ b/kontor-rails/db/migrate/20250626095203_create_comics.rb @@ -0,0 +1,15 @@ +class CreateComics < ActiveRecord::Migration[8.0] + def change + create_table :comics do |t| + t.datetime :created_date + t.datetime :last_modified_date + t.integer :version + t.string :title + t.boolean :current_order + t.boolean :completed + t.string :weblink + t.belongs_to :publisher + end + change_column :comics, :id, :string + end +end diff --git a/kontor-rails/db/migrate/20250626095807_create_volumes.rb b/kontor-rails/db/migrate/20250626095807_create_volumes.rb new file mode 100644 index 0000000..6372159 --- /dev/null +++ b/kontor-rails/db/migrate/20250626095807_create_volumes.rb @@ -0,0 +1,12 @@ +class CreateVolumes < ActiveRecord::Migration[8.0] + def change + create_table :volumes do |t| + t.datetime :created_date + t.datetime :last_modified_date + t.integer :version + t.string :name + t.belongs_to :comic + end + change_column :volumes, :id, :string + end +end diff --git a/kontor-rails/db/migrate/20250626095827_create_trade_paperbacks.rb b/kontor-rails/db/migrate/20250626095827_create_trade_paperbacks.rb new file mode 100644 index 0000000..06b4491 --- /dev/null +++ b/kontor-rails/db/migrate/20250626095827_create_trade_paperbacks.rb @@ -0,0 +1,14 @@ +class CreateTradePaperbacks < ActiveRecord::Migration[8.0] + def change + create_table :trade_paperbacks do |t| + t.datetime :created_date + t.datetime :last_modified_date + t.integer :version + t.string :name + t.integer :issue_start + t.integer :issue_end + t.belongs_to :comic + end + change_column :trade_paperbacks, :id, :string + end +end diff --git a/kontor-rails/db/migrate/20250626095841_create_story_arcs.rb b/kontor-rails/db/migrate/20250626095841_create_story_arcs.rb new file mode 100644 index 0000000..5c9581b --- /dev/null +++ b/kontor-rails/db/migrate/20250626095841_create_story_arcs.rb @@ -0,0 +1,12 @@ +class CreateStoryArcs < ActiveRecord::Migration[8.0] + def change + create_table :story_arcs do |t| + t.datetime :created_date + t.datetime :last_modified_date + t.integer :version + t.string :name + t.belongs_to :comic + end + change_column :story_arcs, :id, :string + end +end diff --git a/kontor-rails/db/migrate/20250626095943_create_issues.rb b/kontor-rails/db/migrate/20250626095943_create_issues.rb new file mode 100644 index 0000000..c4a1420 --- /dev/null +++ b/kontor-rails/db/migrate/20250626095943_create_issues.rb @@ -0,0 +1,18 @@ +class CreateIssues < ActiveRecord::Migration[8.0] + def change + create_table :issues do |t| + t.datetime :created_date + t.datetime :last_modified_date + t.integer :version + t.string :issueNumber + t.string :title + t.datetime :published_on + t.boolean :in_stock + t.boolean :is_read + t.belongs_to :comic + t.belongs_to :volume + t.belongs_to :story_arc + end + change_column :issues, :id, :string + end +end diff --git a/kontor-rails/db/migrate/20250626100003_create_artists.rb b/kontor-rails/db/migrate/20250626100003_create_artists.rb new file mode 100644 index 0000000..c2be790 --- /dev/null +++ b/kontor-rails/db/migrate/20250626100003_create_artists.rb @@ -0,0 +1,9 @@ +class CreateArtists < ActiveRecord::Migration[8.0] + def change + create_table :artists do |t| + t.string :name + + t.timestamps + end + end +end diff --git a/kontor-rails/db/migrate/20250626100135_create_worktypes.rb b/kontor-rails/db/migrate/20250626100135_create_worktypes.rb new file mode 100644 index 0000000..43fe62b --- /dev/null +++ b/kontor-rails/db/migrate/20250626100135_create_worktypes.rb @@ -0,0 +1,9 @@ +class CreateWorktypes < ActiveRecord::Migration[8.0] + def change + create_table :worktypes do |t| + t.string :name + + t.timestamps + end + end +end diff --git a/kontor-rails/db/migrate/20250626100206_create_comic_works.rb b/kontor-rails/db/migrate/20250626100206_create_comic_works.rb new file mode 100644 index 0000000..3561758 --- /dev/null +++ b/kontor-rails/db/migrate/20250626100206_create_comic_works.rb @@ -0,0 +1,7 @@ +class CreateComicWorks < ActiveRecord::Migration[8.0] + def change + create_table :comic_works do |t| + t.timestamps + end + end +end diff --git a/kontor-rails/db/migrate/20250626100213_create_issue_works.rb b/kontor-rails/db/migrate/20250626100213_create_issue_works.rb new file mode 100644 index 0000000..09fd7a0 --- /dev/null +++ b/kontor-rails/db/migrate/20250626100213_create_issue_works.rb @@ -0,0 +1,7 @@ +class CreateIssueWorks < ActiveRecord::Migration[8.0] + def change + create_table :issue_works do |t| + t.timestamps + end + end +end diff --git a/kontor-rails/db/queue_schema.rb b/kontor-rails/db/queue_schema.rb new file mode 100644 index 0000000..85194b6 --- /dev/null +++ b/kontor-rails/db/queue_schema.rb @@ -0,0 +1,129 @@ +ActiveRecord::Schema[7.1].define(version: 1) do + create_table "solid_queue_blocked_executions", force: :cascade do |t| + t.bigint "job_id", null: false + t.string "queue_name", null: false + t.integer "priority", default: 0, null: false + t.string "concurrency_key", null: false + t.datetime "expires_at", null: false + t.datetime "created_at", null: false + t.index [ "concurrency_key", "priority", "job_id" ], name: "index_solid_queue_blocked_executions_for_release" + t.index [ "expires_at", "concurrency_key" ], name: "index_solid_queue_blocked_executions_for_maintenance" + t.index [ "job_id" ], name: "index_solid_queue_blocked_executions_on_job_id", unique: true + end + + create_table "solid_queue_claimed_executions", force: :cascade do |t| + t.bigint "job_id", null: false + t.bigint "process_id" + t.datetime "created_at", null: false + t.index [ "job_id" ], name: "index_solid_queue_claimed_executions_on_job_id", unique: true + t.index [ "process_id", "job_id" ], name: "index_solid_queue_claimed_executions_on_process_id_and_job_id" + end + + create_table "solid_queue_failed_executions", force: :cascade do |t| + t.bigint "job_id", null: false + t.text "error" + t.datetime "created_at", null: false + t.index [ "job_id" ], name: "index_solid_queue_failed_executions_on_job_id", unique: true + end + + create_table "solid_queue_jobs", force: :cascade do |t| + t.string "queue_name", null: false + t.string "class_name", null: false + t.text "arguments" + t.integer "priority", default: 0, null: false + t.string "active_job_id" + t.datetime "scheduled_at" + t.datetime "finished_at" + t.string "concurrency_key" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index [ "active_job_id" ], name: "index_solid_queue_jobs_on_active_job_id" + t.index [ "class_name" ], name: "index_solid_queue_jobs_on_class_name" + t.index [ "finished_at" ], name: "index_solid_queue_jobs_on_finished_at" + t.index [ "queue_name", "finished_at" ], name: "index_solid_queue_jobs_for_filtering" + t.index [ "scheduled_at", "finished_at" ], name: "index_solid_queue_jobs_for_alerting" + end + + create_table "solid_queue_pauses", force: :cascade do |t| + t.string "queue_name", null: false + t.datetime "created_at", null: false + t.index [ "queue_name" ], name: "index_solid_queue_pauses_on_queue_name", unique: true + end + + create_table "solid_queue_processes", force: :cascade do |t| + t.string "kind", null: false + t.datetime "last_heartbeat_at", null: false + t.bigint "supervisor_id" + t.integer "pid", null: false + t.string "hostname" + t.text "metadata" + t.datetime "created_at", null: false + t.string "name", null: false + t.index [ "last_heartbeat_at" ], name: "index_solid_queue_processes_on_last_heartbeat_at" + t.index [ "name", "supervisor_id" ], name: "index_solid_queue_processes_on_name_and_supervisor_id", unique: true + t.index [ "supervisor_id" ], name: "index_solid_queue_processes_on_supervisor_id" + end + + create_table "solid_queue_ready_executions", force: :cascade do |t| + t.bigint "job_id", null: false + t.string "queue_name", null: false + t.integer "priority", default: 0, null: false + t.datetime "created_at", null: false + t.index [ "job_id" ], name: "index_solid_queue_ready_executions_on_job_id", unique: true + t.index [ "priority", "job_id" ], name: "index_solid_queue_poll_all" + t.index [ "queue_name", "priority", "job_id" ], name: "index_solid_queue_poll_by_queue" + end + + create_table "solid_queue_recurring_executions", force: :cascade do |t| + t.bigint "job_id", null: false + t.string "task_key", null: false + t.datetime "run_at", null: false + t.datetime "created_at", null: false + t.index [ "job_id" ], name: "index_solid_queue_recurring_executions_on_job_id", unique: true + t.index [ "task_key", "run_at" ], name: "index_solid_queue_recurring_executions_on_task_key_and_run_at", unique: true + end + + create_table "solid_queue_recurring_tasks", force: :cascade do |t| + t.string "key", null: false + t.string "schedule", null: false + t.string "command", limit: 2048 + t.string "class_name" + t.text "arguments" + t.string "queue_name" + t.integer "priority", default: 0 + t.boolean "static", default: true, null: false + t.text "description" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index [ "key" ], name: "index_solid_queue_recurring_tasks_on_key", unique: true + t.index [ "static" ], name: "index_solid_queue_recurring_tasks_on_static" + end + + create_table "solid_queue_scheduled_executions", force: :cascade do |t| + t.bigint "job_id", null: false + t.string "queue_name", null: false + t.integer "priority", default: 0, null: false + t.datetime "scheduled_at", null: false + t.datetime "created_at", null: false + t.index [ "job_id" ], name: "index_solid_queue_scheduled_executions_on_job_id", unique: true + t.index [ "scheduled_at", "priority", "job_id" ], name: "index_solid_queue_dispatch_all" + end + + create_table "solid_queue_semaphores", force: :cascade do |t| + t.string "key", null: false + t.integer "value", default: 1, null: false + t.datetime "expires_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index [ "expires_at" ], name: "index_solid_queue_semaphores_on_expires_at" + t.index [ "key", "value" ], name: "index_solid_queue_semaphores_on_key_and_value" + t.index [ "key" ], name: "index_solid_queue_semaphores_on_key", unique: true + end + + add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade + add_foreign_key "solid_queue_claimed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade + add_foreign_key "solid_queue_failed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade + add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade + add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade + add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade +end diff --git a/kontor-rails/db/schema.rb b/kontor-rails/db/schema.rb new file mode 100644 index 0000000..f3a5aaa --- /dev/null +++ b/kontor-rails/db/schema.rb @@ -0,0 +1,108 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema[8.0].define(version: 2025_06_26_100213) do + create_table "artists", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "comic_works", force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "comics", id: false, force: :cascade do |t| + t.string "id" + t.datetime "created_date" + t.datetime "last_modified_date" + t.integer "version" + t.string "title" + t.boolean "current_order" + t.boolean "completed" + t.string "weblink" + t.integer "publisher_id" + t.index ["publisher_id"], name: "index_comics_on_publisher_id" + end + + create_table "issue_works", force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "issues", id: false, force: :cascade do |t| + t.string "id" + t.datetime "created_date" + t.datetime "last_modified_date" + t.integer "version" + t.string "issueNumber" + t.string "title" + t.datetime "published_on" + t.boolean "in_stock" + t.boolean "is_read" + t.integer "comic_id" + t.integer "volume_id" + t.integer "story_arc_id" + t.index ["comic_id"], name: "index_issues_on_comic_id" + t.index ["story_arc_id"], name: "index_issues_on_story_arc_id" + t.index ["volume_id"], name: "index_issues_on_volume_id" + end + + create_table "publishers", id: false, force: :cascade do |t| + t.string "id" + t.datetime "created_date" + t.datetime "last_modified_date" + t.integer "version" + t.string "name" + t.string "weblink" + t.string "parent_publisher_id" + end + + create_table "story_arcs", id: false, force: :cascade do |t| + t.string "id" + t.datetime "created_date" + t.datetime "last_modified_date" + t.integer "version" + t.string "name" + t.integer "comic_id" + t.index ["comic_id"], name: "index_story_arcs_on_comic_id" + end + + create_table "trade_paperbacks", id: false, force: :cascade do |t| + t.string "id" + t.datetime "created_date" + t.datetime "last_modified_date" + t.integer "version" + t.string "name" + t.integer "issue_start" + t.integer "issue_end" + t.integer "comic_id" + t.index ["comic_id"], name: "index_trade_paperbacks_on_comic_id" + end + + create_table "volumes", id: false, force: :cascade do |t| + t.string "id" + t.datetime "created_date" + t.datetime "last_modified_date" + t.integer "version" + t.string "name" + t.integer "comic_id" + t.index ["comic_id"], name: "index_volumes_on_comic_id" + end + + create_table "worktypes", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end +end diff --git a/kontor-rails/db/seeds.rb b/kontor-rails/db/seeds.rb new file mode 100644 index 0000000..4fbd6ed --- /dev/null +++ b/kontor-rails/db/seeds.rb @@ -0,0 +1,9 @@ +# This file should ensure the existence of records required to run the application in every environment (production, +# development, test). The code here should be idempotent so that it can be executed at any point in every environment. +# The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). +# +# Example: +# +# ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| +# MovieGenre.find_or_create_by!(name: genre_name) +# end diff --git a/kontor-scripts/db/repository/__init__.py b/kontor-rails/lib/tasks/.keep similarity index 100% rename from kontor-scripts/db/repository/__init__.py rename to kontor-rails/lib/tasks/.keep diff --git a/kontor-rails/log/.keep b/kontor-rails/log/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/public/400.html b/kontor-rails/public/400.html new file mode 100644 index 0000000..282dbc8 --- /dev/null +++ b/kontor-rails/public/400.html @@ -0,0 +1,114 @@ + + + + + + + The server cannot process the request due to a client error (400 Bad Request) + + + + + + + + + + + + + +
    +
    + +
    +
    +

    The server cannot process the request due to a client error. Please check the request and try again. If you’re the application owner check the logs for more information.

    +
    +
    + + + + diff --git a/kontor-rails/public/404.html b/kontor-rails/public/404.html new file mode 100644 index 0000000..c0670bc --- /dev/null +++ b/kontor-rails/public/404.html @@ -0,0 +1,114 @@ + + + + + + + The page you were looking for doesn’t exist (404 Not found) + + + + + + + + + + + + + +
    +
    + +
    +
    +

    The page you were looking for doesn’t exist. You may have mistyped the address or the page may have moved. If you’re the application owner check the logs for more information.

    +
    +
    + + + + diff --git a/kontor-rails/public/406-unsupported-browser.html b/kontor-rails/public/406-unsupported-browser.html new file mode 100644 index 0000000..9532a9c --- /dev/null +++ b/kontor-rails/public/406-unsupported-browser.html @@ -0,0 +1,114 @@ + + + + + + + Your browser is not supported (406 Not Acceptable) + + + + + + + + + + + + + +
    +
    + +
    +
    +

    Your browser is not supported.
    Please upgrade your browser to continue.

    +
    +
    + + + + diff --git a/kontor-rails/public/422.html b/kontor-rails/public/422.html new file mode 100644 index 0000000..8bcf060 --- /dev/null +++ b/kontor-rails/public/422.html @@ -0,0 +1,114 @@ + + + + + + + The change you wanted was rejected (422 Unprocessable Entity) + + + + + + + + + + + + + +
    +
    + +
    +
    +

    The change you wanted was rejected. Maybe you tried to change something you didn’t have access to. If you’re the application owner check the logs for more information.

    +
    +
    + + + + diff --git a/kontor-rails/public/500.html b/kontor-rails/public/500.html new file mode 100644 index 0000000..d77718c --- /dev/null +++ b/kontor-rails/public/500.html @@ -0,0 +1,114 @@ + + + + + + + We’re sorry, but something went wrong (500 Internal Server Error) + + + + + + + + + + + + + +
    +
    + +
    +
    +

    We’re sorry, but something went wrong.
    If you’re the application owner check the logs for more information.

    +
    +
    + + + + diff --git a/kontor-rails/public/icon.png b/kontor-rails/public/icon.png new file mode 100644 index 0000000..c4c9dbf Binary files /dev/null and b/kontor-rails/public/icon.png differ diff --git a/kontor-rails/public/icon.svg b/kontor-rails/public/icon.svg new file mode 100644 index 0000000..04b34bf --- /dev/null +++ b/kontor-rails/public/icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/kontor-rails/public/robots.txt b/kontor-rails/public/robots.txt new file mode 100644 index 0000000..c19f78a --- /dev/null +++ b/kontor-rails/public/robots.txt @@ -0,0 +1 @@ +# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file diff --git a/kontor-rails/script/.keep b/kontor-rails/script/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/storage/.keep b/kontor-rails/storage/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/test/application_system_test_case.rb b/kontor-rails/test/application_system_test_case.rb new file mode 100644 index 0000000..cee29fd --- /dev/null +++ b/kontor-rails/test/application_system_test_case.rb @@ -0,0 +1,5 @@ +require "test_helper" + +class ApplicationSystemTestCase < ActionDispatch::SystemTestCase + driven_by :selenium, using: :headless_chrome, screen_size: [ 1400, 1400 ] +end diff --git a/kontor-rails/test/controllers/.keep b/kontor-rails/test/controllers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/test/controllers/publisher_controller_test.rb b/kontor-rails/test/controllers/publisher_controller_test.rb new file mode 100644 index 0000000..48b9889 --- /dev/null +++ b/kontor-rails/test/controllers/publisher_controller_test.rb @@ -0,0 +1,8 @@ +require "test_helper" + +class PublisherControllerTest < ActionDispatch::IntegrationTest + test "should get index" do + get publisher_index_url + assert_response :success + end +end diff --git a/kontor-rails/test/fixtures/artists.yml b/kontor-rails/test/fixtures/artists.yml new file mode 100644 index 0000000..7d41224 --- /dev/null +++ b/kontor-rails/test/fixtures/artists.yml @@ -0,0 +1,7 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + +two: + name: MyString diff --git a/kontor-rails/test/fixtures/comic_works.yml b/kontor-rails/test/fixtures/comic_works.yml new file mode 100644 index 0000000..d7a3329 --- /dev/null +++ b/kontor-rails/test/fixtures/comic_works.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the "{}" from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/kontor-rails/test/fixtures/comics.yml b/kontor-rails/test/fixtures/comics.yml new file mode 100644 index 0000000..64d88ef --- /dev/null +++ b/kontor-rails/test/fixtures/comics.yml @@ -0,0 +1,7 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + title: MyString + +two: + title: MyString diff --git a/kontor-rails/test/fixtures/files/.keep b/kontor-rails/test/fixtures/files/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/test/fixtures/issue_works.yml b/kontor-rails/test/fixtures/issue_works.yml new file mode 100644 index 0000000..d7a3329 --- /dev/null +++ b/kontor-rails/test/fixtures/issue_works.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the "{}" from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/kontor-rails/test/fixtures/issues.yml b/kontor-rails/test/fixtures/issues.yml new file mode 100644 index 0000000..42b49fc --- /dev/null +++ b/kontor-rails/test/fixtures/issues.yml @@ -0,0 +1,7 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + issueNumber: MyString + +two: + issueNumber: MyString diff --git a/kontor-rails/test/fixtures/publishers.yml b/kontor-rails/test/fixtures/publishers.yml new file mode 100644 index 0000000..7d41224 --- /dev/null +++ b/kontor-rails/test/fixtures/publishers.yml @@ -0,0 +1,7 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + +two: + name: MyString diff --git a/kontor-rails/test/fixtures/story_arcs.yml b/kontor-rails/test/fixtures/story_arcs.yml new file mode 100644 index 0000000..7d41224 --- /dev/null +++ b/kontor-rails/test/fixtures/story_arcs.yml @@ -0,0 +1,7 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + +two: + name: MyString diff --git a/kontor-rails/test/fixtures/trade_paperbacks.yml b/kontor-rails/test/fixtures/trade_paperbacks.yml new file mode 100644 index 0000000..7d41224 --- /dev/null +++ b/kontor-rails/test/fixtures/trade_paperbacks.yml @@ -0,0 +1,7 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + +two: + name: MyString diff --git a/kontor-rails/test/fixtures/volumes.yml b/kontor-rails/test/fixtures/volumes.yml new file mode 100644 index 0000000..7d41224 --- /dev/null +++ b/kontor-rails/test/fixtures/volumes.yml @@ -0,0 +1,7 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + +two: + name: MyString diff --git a/kontor-rails/test/fixtures/worktypes.yml b/kontor-rails/test/fixtures/worktypes.yml new file mode 100644 index 0000000..7d41224 --- /dev/null +++ b/kontor-rails/test/fixtures/worktypes.yml @@ -0,0 +1,7 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + +two: + name: MyString diff --git a/kontor-rails/test/helpers/.keep b/kontor-rails/test/helpers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/test/integration/.keep b/kontor-rails/test/integration/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/test/mailers/.keep b/kontor-rails/test/mailers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/test/models/.keep b/kontor-rails/test/models/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/test/models/artist_test.rb b/kontor-rails/test/models/artist_test.rb new file mode 100644 index 0000000..371a734 --- /dev/null +++ b/kontor-rails/test/models/artist_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class ArtistTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/kontor-rails/test/models/comic_test.rb b/kontor-rails/test/models/comic_test.rb new file mode 100644 index 0000000..5b3b293 --- /dev/null +++ b/kontor-rails/test/models/comic_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class ComicTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/kontor-rails/test/models/comic_work_test.rb b/kontor-rails/test/models/comic_work_test.rb new file mode 100644 index 0000000..b0e2daf --- /dev/null +++ b/kontor-rails/test/models/comic_work_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class ComicWorkTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/kontor-rails/test/models/issue_test.rb b/kontor-rails/test/models/issue_test.rb new file mode 100644 index 0000000..7e15ee9 --- /dev/null +++ b/kontor-rails/test/models/issue_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class IssueTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/kontor-rails/test/models/issue_work_test.rb b/kontor-rails/test/models/issue_work_test.rb new file mode 100644 index 0000000..aa4e3a0 --- /dev/null +++ b/kontor-rails/test/models/issue_work_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class IssueWorkTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/kontor-rails/test/models/publisher_test.rb b/kontor-rails/test/models/publisher_test.rb new file mode 100644 index 0000000..85792c1 --- /dev/null +++ b/kontor-rails/test/models/publisher_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class PublisherTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/kontor-rails/test/models/story_arc_test.rb b/kontor-rails/test/models/story_arc_test.rb new file mode 100644 index 0000000..3d16db1 --- /dev/null +++ b/kontor-rails/test/models/story_arc_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class StoryArcTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/kontor-rails/test/models/trade_paperback_test.rb b/kontor-rails/test/models/trade_paperback_test.rb new file mode 100644 index 0000000..e5da7dc --- /dev/null +++ b/kontor-rails/test/models/trade_paperback_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class TradePaperbackTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/kontor-rails/test/models/volume_test.rb b/kontor-rails/test/models/volume_test.rb new file mode 100644 index 0000000..c88c19a --- /dev/null +++ b/kontor-rails/test/models/volume_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class VolumeTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/kontor-rails/test/models/worktype_test.rb b/kontor-rails/test/models/worktype_test.rb new file mode 100644 index 0000000..ee1ddb6 --- /dev/null +++ b/kontor-rails/test/models/worktype_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class WorktypeTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/kontor-rails/test/system/.keep b/kontor-rails/test/system/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/test/test_helper.rb b/kontor-rails/test/test_helper.rb new file mode 100644 index 0000000..0c22470 --- /dev/null +++ b/kontor-rails/test/test_helper.rb @@ -0,0 +1,15 @@ +ENV["RAILS_ENV"] ||= "test" +require_relative "../config/environment" +require "rails/test_help" + +module ActiveSupport + class TestCase + # Run tests in parallel with specified workers + parallelize(workers: :number_of_processors) + + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + + # Add more helper methods to be used by all tests here... + end +end diff --git a/kontor-rails/tmp/.keep b/kontor-rails/tmp/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/tmp/pids/.keep b/kontor-rails/tmp/pids/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/tmp/storage/.keep b/kontor-rails/tmp/storage/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/vendor/.keep b/kontor-rails/vendor/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-rails/vendor/javascript/.keep b/kontor-rails/vendor/javascript/.keep new file mode 100644 index 0000000..e69de29 diff --git a/kontor-robyn/.python-version b/kontor-robyn/.python-version new file mode 100644 index 0000000..24ee5b1 --- /dev/null +++ b/kontor-robyn/.python-version @@ -0,0 +1 @@ +3.13 diff --git a/kontor-robyn/README.md b/kontor-robyn/README.md new file mode 100644 index 0000000..e69de29 diff --git a/kontor-robyn/pyproject.toml b/kontor-robyn/pyproject.toml new file mode 100644 index 0000000..c572298 --- /dev/null +++ b/kontor-robyn/pyproject.toml @@ -0,0 +1,22 @@ +[project] +name = "kontor-robyn" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +authors = [ + { name = "Thomas Peetz", email = "thomas.peetz@thpeetz.de" } +] +requires-python = ">=3.13" +dependencies = [ + "asyncpg>=0.31.0", + "msgspec[toml,yaml]>=0.21.1", + "robyn[all]>=0.88.0", + "sqlalchemy>=2.0.51", +] + +[project.scripts] +kontor = "kontor_robyn:main" + +[build-system] +requires = ["uv_build>=0.12.1,<0.13.0"] +build-backend = "uv_build" diff --git a/kontor-robyn/src/kontor_robyn/__init__.py b/kontor-robyn/src/kontor_robyn/__init__.py new file mode 100644 index 0000000..5adedf5 --- /dev/null +++ b/kontor-robyn/src/kontor_robyn/__init__.py @@ -0,0 +1,79 @@ +""" +Main entypoint for kontor-robyn +""" + +from contextvars import ContextVar +import time + +from robyn import Request, Response, Robyn + +from kontor_robyn.apis.version1 import api_router +from kontor_robyn.db.models import Base, engine + +from .core.log_conf import logger + +_request_start: ContextVar[float] = ContextVar("request_start") + + +def create_tables() -> None: + """ + Create table with SQLAlchemy + """ + logger.info("create tables") + Base.metadata.create_all(bind=engine) + logger.info("tables created") + + +def add_logging(app: Robyn) -> None: + """ + set logging for every request + """ + + def logging_before_handler(request: Request): + _request_start.set(time.perf_counter()) + return request + + def log_request(request: Request, response: Response): + """ + log used time and return code + """ + start = _request_start.get(None) + duration_ms = (time.perf_counter() - start) * 1000 if start is not None else 0.0 + logger.info( + "%s %s -> %s (%.2fms)", + request.method, + request.url.path, + response.status_code, + duration_ms, + ) + return response + + logging_before_handler = app.before_request()(logging_before_handler) # type: ignore # noqa: F823 + log_request = app.after_request()(log_request) # type: ignore # noqa: F823 + + +def include_router(app: Robyn): + """ + Add routes + """ + app.include_router(api_router) + + +def start_application() -> None: + """ + Start Robyn framework and configure routes + """ + app = Robyn(__file__) + add_logging(app) + include_router(app) + create_tables() + app.start(port=8280) + + +def main() -> None: + """ + Start Framework Robyn + """ + logger.info("starting kontor-robyn") + start_application() + logger.info("kontor-robyn exited") diff --git a/kontor-robyn/src/kontor_robyn/apis/version1/__init__.py b/kontor-robyn/src/kontor_robyn/apis/version1/__init__.py new file mode 100644 index 0000000..3127f59 --- /dev/null +++ b/kontor-robyn/src/kontor_robyn/apis/version1/__init__.py @@ -0,0 +1,16 @@ +""" +Provide subrouter for api/v1 +""" + +from robyn import SubRouter + + +api_router = SubRouter(prefix="/api/v1") + + +@api_router.get("/health") +def health(): + """ + Return health info + """ + return {"status": "ok"} diff --git a/kontor-robyn/src/kontor_robyn/core/__init__.py b/kontor-robyn/src/kontor_robyn/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kontor-robyn/src/kontor_robyn/core/log_conf.py b/kontor-robyn/src/kontor_robyn/core/log_conf.py new file mode 100644 index 0000000..8d7d6e4 --- /dev/null +++ b/kontor-robyn/src/kontor_robyn/core/log_conf.py @@ -0,0 +1,43 @@ +""" +Define logging configuration for kontor-robyn +""" + +import logging +import logging.config +from typing import Any + +LOGGING_CONFIG: dict[str, Any] = { + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "default": { + "fmt": "%(asctime)s - %(name)s - %(levelprefix)s %(message)s", + }, + "access": { + "fmt": '%(asctime)s - %(name)s - %(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s', # noqa: E501 + }, + "access_file": { + "fmt": '%(asctime)s - %(name)s - %(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s', # noqa: E501 + "use_colors": False, + }, + }, + "handlers": { + "default": { + "formatter": "default", + "class": "logging.StreamHandler", + "stream": "ext://sys.stdout", + }, + "error": { + "formatter": "access", + "class": "logging.StreamHandler", + "stream": "ext://sys.stderr", + }, + }, + "loggers": { + "root": {"handlers": ["default"], "level": "INFO", "propagate": False}, + "kontor": {"handlers": ["default"], "level": "INFO", "propagate": False}, + }, +} + +logging.config.dictConfig(LOGGING_CONFIG) +logger = logging.getLogger("kontor") diff --git a/kontor-robyn/src/kontor_robyn/db/models/__init__.py b/kontor-robyn/src/kontor_robyn/db/models/__init__.py new file mode 100644 index 0000000..edd45f5 --- /dev/null +++ b/kontor-robyn/src/kontor_robyn/db/models/__init__.py @@ -0,0 +1,46 @@ +""" +Definition of models +""" + +from typing import Optional +import uuid +from datetime import datetime + +from sqlalchemy import create_engine, func +from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, sessionmaker + +DATABASE_URL = "sqlite:///./kontor.db" + +engine = create_engine(DATABASE_URL) +SESSION_LOCAL = sessionmaker(autocommit=False, autoflush=False, bind=engine) + + +class Base(DeclarativeBase): + """ + Base class for all Models + """ + + +class BaseMixin: + """ + Base mixin to provide standard fields id, version, created_date, last_modified_date + """ + + id: Mapped[str] = mapped_column(primary_key=True, default=str(uuid.uuid4())) + created_date: Mapped[datetime] = mapped_column(default=func.now()) + last_modified_date: Mapped[datetime] = mapped_column(default=func.now()) + version: Mapped[int] = mapped_column(default=0) + + +class BaseVideoMixin: + """ + Base mixin to provide additional fields for video links. + """ + + cloud_link: Mapped[Optional[str]] + file_name: Mapped[Optional[str]] + path: Mapped[str] + review: Mapped[bool] + title: Mapped[str] + url: Mapped[str] + should_download: Mapped[bool] diff --git a/kontor-robyn/src/kontor_robyn/db/models/media.py b/kontor-robyn/src/kontor_robyn/db/models/media.py new file mode 100644 index 0000000..95499ce --- /dev/null +++ b/kontor-robyn/src/kontor_robyn/db/models/media.py @@ -0,0 +1,102 @@ +from typing import List, Optional + +from sqlalchemy import ForeignKey +from sqlalchemy.orm import Mapped, relationship, mapped_column + +from kontor_robyn.db.models import Base, BaseMixin, BaseVideoMixin + + +class MediaFile(Base, BaseMixin, BaseVideoMixin): + """ + MediaFile represents video link. + """ + + __tablename__ = "media_file" + media_actor_files: Mapped[List["MediaActorFile"]] = relationship( + back_populates="media_file" + ) + + def __repr__(self): + return f"MediaFile({self.id} {self.title} {self.title})" + + def __str__(self): + return f"{self.title}({self.id})" + + def update_title(self): + """ + Update title from url. + """ + + +class MediaActor(Base, BaseMixin): + """ + MediaActor represents actor for MediaFile + """ + + __tablename__ = "media_actor" + name: Mapped[str] + url: Mapped[Optional[str]] = mapped_column(unique=True) + media_actor_files = relationship("MediaActorFile") + + def __repr__(self) -> str: + return f"MediaActor({self.id} {self.name} {self.url})" + + def __str__(self) -> str: + return f"{self.url}({self.id})" + + +class MediaActorFile(Base, BaseMixin): + """ + MediaActorFile defines the connection between MediaFile and MediaActor + """ + + __tablename__ = "media_actor_file" + media_actor_id: Mapped[str] = mapped_column( + ForeignKey("media_actor.id"), nullable=False + ) + media_actor: Mapped[MediaActor] = relationship(back_populates="media_actor_files") + media_file_id: Mapped[str] = mapped_column( + ForeignKey("media_file.id"), nullable=True + ) + media_file: Mapped[MediaFile] = relationship(back_populates="media_actor_files") + + def __repr__(self): + return f"MediaActorFile({self.id} {self.media_actor_id} {self.media_file_id})" + + def __str__(self) -> str: + return f"{self.id} {self.media_actor_id} {self.media_file_id}" + + +class MediaArticle(Base, BaseMixin): + """ + MediaArticle represents a link to an article + """ + + __tablename__ = "media_article" + review: Mapped[bool] + title: Mapped[str] + url: Mapped[str] = mapped_column(unique=True) + + +class MediaVideo(Base, BaseMixin): + """ + MediaFile represents video link. + """ + + __tablename__ = "media_video" + cloud_link: Mapped[str] + file_name: Mapped[str] + path: Mapped[str] + review: Mapped[bool] + title: Mapped[str] + url: Mapped[str] = mapped_column(unique=True) + should_download: Mapped[bool] + + def __repr__(self): + return f"MediaFile({self.id} {self.title} {self.url})" + + def __str__(self): + if self.title is None: + return f"{self.url}({self.id})" + else: + return f"{self.title}({self.id})" diff --git a/kontor-robyn/uv.lock b/kontor-robyn/uv.lock new file mode 100644 index 0000000..88a95d6 --- /dev/null +++ b/kontor-robyn/uv.lock @@ -0,0 +1,595 @@ +version = 1 +revision = 3 +requires-python = ">=3.13" + +[[package]] +name = "annotated-types" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/56/a8120250d128bed162cd73c76d45f6ef9991f3e068f62a8ee060afa3104a/annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7", size = 15893, upload-time = "2026-07-23T20:16:13.995Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/91/8acff4f5e50511b911bbccb72b8628a49c68ce14148cd9f6431094859a90/annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0", size = 13427, upload-time = "2026-07-23T20:16:12.938Z" }, +] + +[[package]] +name = "asyncpg" +version = "0.31.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/cc/d18065ce2380d80b1bcce927c24a2642efd38918e33fd724bc4bca904877/asyncpg-0.31.0.tar.gz", hash = "sha256:c989386c83940bfbd787180f2b1519415e2d3d6277a70d9d0f0145ac73500735", size = 993667, upload-time = "2025-11-24T23:27:00.812Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/11/97b5c2af72a5d0b9bc3fa30cd4b9ce22284a9a943a150fdc768763caf035/asyncpg-0.31.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c204fab1b91e08b0f47e90a75d1b3c62174dab21f670ad6c5d0f243a228f015b", size = 661111, upload-time = "2025-11-24T23:26:04.467Z" }, + { url = "https://files.pythonhosted.org/packages/1b/71/157d611c791a5e2d0423f09f027bd499935f0906e0c2a416ce712ba51ef3/asyncpg-0.31.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:54a64f91839ba59008eccf7aad2e93d6e3de688d796f35803235ea1c4898ae1e", size = 636928, upload-time = "2025-11-24T23:26:05.944Z" }, + { url = "https://files.pythonhosted.org/packages/2e/fc/9e3486fb2bbe69d4a867c0b76d68542650a7ff1574ca40e84c3111bb0c6e/asyncpg-0.31.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0e0822b1038dc7253b337b0f3f676cadc4ac31b126c5d42691c39691962e403", size = 3424067, upload-time = "2025-11-24T23:26:07.957Z" }, + { url = "https://files.pythonhosted.org/packages/12/c6/8c9d076f73f07f995013c791e018a1cd5f31823c2a3187fc8581706aa00f/asyncpg-0.31.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bef056aa502ee34204c161c72ca1f3c274917596877f825968368b2c33f585f4", size = 3518156, upload-time = "2025-11-24T23:26:09.591Z" }, + { url = "https://files.pythonhosted.org/packages/ae/3b/60683a0baf50fbc546499cfb53132cb6835b92b529a05f6a81471ab60d0c/asyncpg-0.31.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0bfbcc5b7ffcd9b75ab1558f00db2ae07db9c80637ad1b2469c43df79d7a5ae2", size = 3319636, upload-time = "2025-11-24T23:26:11.168Z" }, + { url = "https://files.pythonhosted.org/packages/50/dc/8487df0f69bd398a61e1792b3cba0e47477f214eff085ba0efa7eac9ce87/asyncpg-0.31.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:22bc525ebbdc24d1261ecbf6f504998244d4e3be1721784b5f64664d61fbe602", size = 3472079, upload-time = "2025-11-24T23:26:13.164Z" }, + { url = "https://files.pythonhosted.org/packages/13/a1/c5bbeeb8531c05c89135cb8b28575ac2fac618bcb60119ee9696c3faf71c/asyncpg-0.31.0-cp313-cp313-win32.whl", hash = "sha256:f890de5e1e4f7e14023619399a471ce4b71f5418cd67a51853b9910fdfa73696", size = 527606, upload-time = "2025-11-24T23:26:14.78Z" }, + { url = "https://files.pythonhosted.org/packages/91/66/b25ccb84a246b470eb943b0107c07edcae51804912b824054b3413995a10/asyncpg-0.31.0-cp313-cp313-win_amd64.whl", hash = "sha256:dc5f2fa9916f292e5c5c8b2ac2813763bcd7f58e130055b4ad8a0531314201ab", size = 596569, upload-time = "2025-11-24T23:26:16.189Z" }, + { url = "https://files.pythonhosted.org/packages/3c/36/e9450d62e84a13aea6580c83a47a437f26c7ca6fa0f0fd40b6670793ea30/asyncpg-0.31.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f6b56b91bb0ffc328c4e3ed113136cddd9deefdf5f79ab448598b9772831df44", size = 660867, upload-time = "2025-11-24T23:26:17.631Z" }, + { url = "https://files.pythonhosted.org/packages/82/4b/1d0a2b33b3102d210439338e1beea616a6122267c0df459ff0265cd5807a/asyncpg-0.31.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:334dec28cf20d7f5bb9e45b39546ddf247f8042a690bff9b9573d00086e69cb5", size = 638349, upload-time = "2025-11-24T23:26:19.689Z" }, + { url = "https://files.pythonhosted.org/packages/41/aa/e7f7ac9a7974f08eff9183e392b2d62516f90412686532d27e196c0f0eeb/asyncpg-0.31.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98cc158c53f46de7bb677fd20c417e264fc02b36d901cc2a43bd6cb0dc6dbfd2", size = 3410428, upload-time = "2025-11-24T23:26:21.275Z" }, + { url = "https://files.pythonhosted.org/packages/6f/de/bf1b60de3dede5c2731e6788617a512bc0ebd9693eac297ee74086f101d7/asyncpg-0.31.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9322b563e2661a52e3cdbc93eed3be7748b289f792e0011cb2720d278b366ce2", size = 3471678, upload-time = "2025-11-24T23:26:23.627Z" }, + { url = "https://files.pythonhosted.org/packages/46/78/fc3ade003e22d8bd53aaf8f75f4be48f0b460fa73738f0391b9c856a9147/asyncpg-0.31.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19857a358fc811d82227449b7ca40afb46e75b33eb8897240c3839dd8b744218", size = 3313505, upload-time = "2025-11-24T23:26:25.235Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e9/73eb8a6789e927816f4705291be21f2225687bfa97321e40cd23055e903a/asyncpg-0.31.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ba5f8886e850882ff2c2ace5732300e99193823e8107e2c53ef01c1ebfa1e85d", size = 3434744, upload-time = "2025-11-24T23:26:26.944Z" }, + { url = "https://files.pythonhosted.org/packages/08/4b/f10b880534413c65c5b5862f79b8e81553a8f364e5238832ad4c0af71b7f/asyncpg-0.31.0-cp314-cp314-win32.whl", hash = "sha256:cea3a0b2a14f95834cee29432e4ddc399b95700eb1d51bbc5bfee8f31fa07b2b", size = 532251, upload-time = "2025-11-24T23:26:28.404Z" }, + { url = "https://files.pythonhosted.org/packages/d3/2d/7aa40750b7a19efa5d66e67fc06008ca0f27ba1bd082e457ad82f59aba49/asyncpg-0.31.0-cp314-cp314-win_amd64.whl", hash = "sha256:04d19392716af6b029411a0264d92093b6e5e8285ae97a39957b9a9c14ea72be", size = 604901, upload-time = "2025-11-24T23:26:30.34Z" }, + { url = "https://files.pythonhosted.org/packages/ce/fe/b9dfe349b83b9dee28cc42360d2c86b2cdce4cb551a2c2d27e156bcac84d/asyncpg-0.31.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bdb957706da132e982cc6856bb2f7b740603472b54c3ebc77fe60ea3e57e1bd2", size = 702280, upload-time = "2025-11-24T23:26:32Z" }, + { url = "https://files.pythonhosted.org/packages/6a/81/e6be6e37e560bd91e6c23ea8a6138a04fd057b08cf63d3c5055c98e81c1d/asyncpg-0.31.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6d11b198111a72f47154fa03b85799f9be63701e068b43f84ac25da0bda9cb31", size = 682931, upload-time = "2025-11-24T23:26:33.572Z" }, + { url = "https://files.pythonhosted.org/packages/a6/45/6009040da85a1648dd5bc75b3b0a062081c483e75a1a29041ae63a0bf0dc/asyncpg-0.31.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:18c83b03bc0d1b23e6230f5bf8d4f217dc9bc08644ce0502a9d91dc9e634a9c7", size = 3581608, upload-time = "2025-11-24T23:26:35.638Z" }, + { url = "https://files.pythonhosted.org/packages/7e/06/2e3d4d7608b0b2b3adbee0d0bd6a2d29ca0fc4d8a78f8277df04e2d1fd7b/asyncpg-0.31.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e009abc333464ff18b8f6fd146addffd9aaf63e79aa3bb40ab7a4c332d0c5e9e", size = 3498738, upload-time = "2025-11-24T23:26:37.275Z" }, + { url = "https://files.pythonhosted.org/packages/7d/aa/7d75ede780033141c51d83577ea23236ba7d3a23593929b32b49db8ed36e/asyncpg-0.31.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3b1fbcb0e396a5ca435a8826a87e5c2c2cc0c8c68eb6fadf82168056b0e53a8c", size = 3401026, upload-time = "2025-11-24T23:26:39.423Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7a/15e37d45e7f7c94facc1e9148c0e455e8f33c08f0b8a0b1deb2c5171771b/asyncpg-0.31.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8df714dba348efcc162d2adf02d213e5fab1bd9f557e1305633e851a61814a7a", size = 3429426, upload-time = "2025-11-24T23:26:41.032Z" }, + { url = "https://files.pythonhosted.org/packages/13/d5/71437c5f6ae5f307828710efbe62163974e71237d5d46ebd2869ea052d10/asyncpg-0.31.0-cp314-cp314t-win32.whl", hash = "sha256:1b41f1afb1033f2b44f3234993b15096ddc9cd71b21a42dbd87fc6a57b43d65d", size = 614495, upload-time = "2025-11-24T23:26:42.659Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d7/8fb3044eaef08a310acfe23dae9a8e2e07d305edc29a53497e52bc76eca7/asyncpg-0.31.0-cp314-cp314t-win_amd64.whl", hash = "sha256:bd4107bb7cdd0e9e65fae66a62afd3a249663b844fa34d479f6d5b3bef9c04c3", size = 706062, upload-time = "2025-11-24T23:26:44.086Z" }, +] + +[[package]] +name = "dill" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/81/e1/56027a71e31b02ddc53c7d65b01e68edf64dea2932122fe7746a516f75d5/dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa", size = 187315, upload-time = "2026-01-19T02:36:56.85Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d", size = 120019, upload-time = "2026-01-19T02:36:55.663Z" }, +] + +[[package]] +name = "greenlet" +version = "3.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/74/b13368064b09053253555d3f2839cc2684d22d5aed0d2ccffbf7a6736558/greenlet-3.5.4.tar.gz", hash = "sha256:0232ae1de90a8e07867bb127d7a6ba2301e859145489f25cda8a6096dabe1d20", size = 206538, upload-time = "2026-07-22T12:47:14.468Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/9a/e51225dcd58713f16ccbdcc501a8da21098ea14515b7870f1f94459e5ff5/greenlet-3.5.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:24e61b88cb7e1b1d794b32a10cc346ac779681d6d74ff137a3e0a444d2bf1f02", size = 294831, upload-time = "2026-07-22T11:38:53.389Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ea/de50a50fadf979713ab18b46f22ad5ff5f2dcfc637a3ebdecf669801e1a5/greenlet-3.5.4-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:870d730fec833f5a06906a32596cc099b9161594642a92a520b7a88911c95356", size = 614619, upload-time = "2026-07-22T12:26:42.282Z" }, + { url = "https://files.pythonhosted.org/packages/db/c7/2aae27fea41205b8650294c301f042a2a4bb6155eea48c995b890a92f2c1/greenlet-3.5.4-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ec5ff0d1878df6af3bf9b638a5a92a7d5693291de77c91bff10fa48519c604ef", size = 627021, upload-time = "2026-07-22T12:29:03.445Z" }, + { url = "https://files.pythonhosted.org/packages/eb/56/79fd826f9ccaae0b84e1b4ef68dabba5e105bb044ffcd448a0b782fcba9a/greenlet-3.5.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d84d993f6e575c950d91a23c1345d18fe1a4310d447bf630849d7809196b52f0", size = 624002, upload-time = "2026-07-22T11:51:11.391Z" }, + { url = "https://files.pythonhosted.org/packages/0a/1a/27319f97e731298513dcba1a2e91b63e9d8811d9de22130f960b129b1bf1/greenlet-3.5.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:58023945f421093de5e6fa108c0985a8659d43f49e0216da25099369a121bcbd", size = 1581533, upload-time = "2026-07-22T12:25:05.322Z" }, + { url = "https://files.pythonhosted.org/packages/b1/6d/24240bf562e9786dd2799ee0a4a4dadb4ded22510f41b20245099159ac8c/greenlet-3.5.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bae2728e1897aa8df8cb1af38cd48b3a743aefe29372de7b8b7a9f532501e69f", size = 1645781, upload-time = "2026-07-22T11:51:14.805Z" }, + { url = "https://files.pythonhosted.org/packages/c1/5a/442ab1a9ef7ca6bf7210e5397a95972206a91a31033a03c8900866a10039/greenlet-3.5.4-cp313-cp313-win_amd64.whl", hash = "sha256:ca5726c0b08ca35ae873557266a78b2c3f3b2b7d7401aa5ff886c2045dd0111c", size = 247133, upload-time = "2026-07-22T11:39:20.661Z" }, + { url = "https://files.pythonhosted.org/packages/3e/e6/9160210222386b1a378ff94db846b9508ca24a121cf684991561fdb69280/greenlet-3.5.4-cp313-cp313-win_arm64.whl", hash = "sha256:7c1303791d603080cac6fc3b34df51c3b75b723739c282c8029e48a0d241672f", size = 245500, upload-time = "2026-07-22T11:40:22.185Z" }, + { url = "https://files.pythonhosted.org/packages/a5/a7/6ab1d4f9cd548d15ab90da29947f2076100130bb179b0bde59f795a459e3/greenlet-3.5.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:7e8afa5eac028f8140ceafe5ceec66e6aa127ddcb21452d2a564dcd2900b5f22", size = 295410, upload-time = "2026-07-22T11:40:35.747Z" }, + { url = "https://files.pythonhosted.org/packages/cd/7a/422f63b4715cbc0b24385305407adf38b48f6bb68b3e6b04090e994d0f5a/greenlet-3.5.4-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73b37afe369021423ea53dd3123e04bffa7e93ac64429b9f50835b2e4fcae7cf", size = 661286, upload-time = "2026-07-22T12:26:43.8Z" }, + { url = "https://files.pythonhosted.org/packages/d0/31/5a1cac663bf5582190c5a714ef81364f03cde232227f39748f8ae4c11da5/greenlet-3.5.4-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3ef964f56dfcb6f9bbef2a190d9126795eac408716aeae47b5e7c73c32aafca9", size = 673517, upload-time = "2026-07-22T12:29:04.815Z" }, + { url = "https://files.pythonhosted.org/packages/15/4a/2a82a1e3f8aaca020853ac8d12211280ca2b231aa08ea39f636f1060c319/greenlet-3.5.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c53ff01a5c53a40f2c16820ebc56d7c61a77f5fbe009dadd96292d5682f80f8", size = 670917, upload-time = "2026-07-22T11:51:13.589Z" }, + { url = "https://files.pythonhosted.org/packages/68/b0/e379a152b17bfdfa95795af4049e37c0fd1b4d81f020d426db104ed07c77/greenlet-3.5.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecca4d80d55a01ad6b23b33262662956149fbb7b2c6be2910f1705921958cbf3", size = 1628478, upload-time = "2026-07-22T12:25:06.678Z" }, + { url = "https://files.pythonhosted.org/packages/5e/43/bffdfa64f7317f954c5c1230b5dd5922676ce198689a68c1ac1ed4b1b1a5/greenlet-3.5.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2ffbc533e0eaf8e80d8471411646ab88fe58f641d508c0b02b24494479f4d9ec", size = 1692021, upload-time = "2026-07-22T11:51:17.008Z" }, + { url = "https://files.pythonhosted.org/packages/d0/11/f799f9637e2c6e9b0b716015e339040598b058cf7654dfc0d67468b177ed/greenlet-3.5.4-cp314-cp314-win_amd64.whl", hash = "sha256:305f69e6c4523d7f6979ed001cff4e5853c063e5da04880296603aa0227e544c", size = 248031, upload-time = "2026-07-22T11:40:11.007Z" }, + { url = "https://files.pythonhosted.org/packages/05/75/625bcdd74d5e6b2dca1ecba3c3ac77bcf8a026c21a649a46cef23e421f97/greenlet-3.5.4-cp314-cp314-win_arm64.whl", hash = "sha256:f260930bbbbcf9caee661211235a5111c86dfe5832fdf6ae4570da1e0995320f", size = 246892, upload-time = "2026-07-22T11:40:27.357Z" }, + { url = "https://files.pythonhosted.org/packages/ec/69/35c62ed49c320cb4d98e14698ccca5467d3bfe683984172be9cb564d9ce3/greenlet-3.5.4-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:41ddab54e4b238f4a6c323f39b4e59e176affd5a94d461a9fb7583dac74240a3", size = 305571, upload-time = "2026-07-22T11:40:31.659Z" }, + { url = "https://files.pythonhosted.org/packages/5b/6c/64d60216b3640dcb0b62d913dd9e0d80030c09115bb2e4ba70c95d10ca45/greenlet-3.5.4-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3dabe3e2809013052c68bdf0b7fa5f5f2859c43a80803131ad61af9cabd7867", size = 672568, upload-time = "2026-07-22T12:26:45.298Z" }, + { url = "https://files.pythonhosted.org/packages/5c/de/ba3ab0a96292e53039530333b0d2ae18d9e508f3a325cd7bf15f8172944c/greenlet-3.5.4-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:27d3f00718634d4520a3a150154ac5da36f257869d41321953375b90bfbbc72c", size = 680076, upload-time = "2026-07-22T12:29:06.125Z" }, + { url = "https://files.pythonhosted.org/packages/a5/be/aeada79083c6f1c15f45d77a332f9c441af263ee298e3eb17522cd337d22/greenlet-3.5.4-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cbd60b5763c6543c1827e48faaf14ea9bfbad245f52b1a4d76a2a2d8884c6c66", size = 676733, upload-time = "2026-07-22T11:51:16.027Z" }, + { url = "https://files.pythonhosted.org/packages/e9/10/2392fc3a98948652ef5fd1e7275c04f861dd13f74b78a2b4309f4ee4d090/greenlet-3.5.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f00f910f0e7b35416c63b23ad78b769aeccfc1775f712b43c4ee525624a2eef7", size = 1637327, upload-time = "2026-07-22T12:25:07.879Z" }, + { url = "https://files.pythonhosted.org/packages/55/c6/e7237a3dfa1f205ed0d9ea1e46d70bd2811b32d516266399fb59d28ab90a/greenlet-3.5.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:91c26423753b92caf41ab3f98fd547d7374d4d9fc2d85be041886c1579d9255e", size = 1697493, upload-time = "2026-07-22T11:51:19.214Z" }, + { url = "https://files.pythonhosted.org/packages/55/e3/4ba8154ba2a3d43729e499f72471b4b5c993f3826d3e24da81d5f06d6572/greenlet-3.5.4-cp314-cp314t-win_amd64.whl", hash = "sha256:ee032b91fd8ec29ec6c4cea2b8c561b178435134bd0752c7334b94e9c736c132", size = 251637, upload-time = "2026-07-22T11:40:37.44Z" }, + { url = "https://files.pythonhosted.org/packages/90/03/e3f96dfc100261a29545ddc8270cafe58f9195b6651466910e820910de77/greenlet-3.5.4-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:178111881dd7a6c946471fda85485ec796e1043c2b939f694b096e2ecf986809", size = 296076, upload-time = "2026-07-22T11:39:38.364Z" }, + { url = "https://files.pythonhosted.org/packages/a4/3d/da52d208e5c977bce8667e784729e584e38b5785f4c1ec0f4c836e9a1c42/greenlet-3.5.4-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d92df08dd65fede97fc37aad36c2e9dcda3b31c467f8e0c2c096456cb818e927", size = 666870, upload-time = "2026-07-22T12:26:46.691Z" }, + { url = "https://files.pythonhosted.org/packages/2d/8a/7e6dee25cb8a8cf9b362c8e597cc269593378bd916f16c736c059a52e85a/greenlet-3.5.4-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:99e8f8c4ebc4fd80aa26c1280ae9ad43a0976e786349703a181cf0bae60413e5", size = 677678, upload-time = "2026-07-22T12:29:07.508Z" }, + { url = "https://files.pythonhosted.org/packages/6c/21/5a38699fa45de749e3857d93b8f07e4c20489e77c2d35d915a2e1c456606/greenlet-3.5.4-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:394de08dad5ffcb1f50c2159d93e398d9d2da3ed437645eaa54771fa720db9f0", size = 676067, upload-time = "2026-07-22T11:51:18.163Z" }, + { url = "https://files.pythonhosted.org/packages/5e/ba/863116ab8ff1ca7a729e327800268939d182db47aa433db70e216e7d9194/greenlet-3.5.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:c883d61f2282d72c767a14936641b3efcbde9d82f1080712aaea0b1d3126cb88", size = 1633489, upload-time = "2026-07-22T12:25:09.605Z" }, + { url = "https://files.pythonhosted.org/packages/fa/06/7466ced82818d6132462d7f26b3f83c66ea15d2b193a6c0088d558ed7d95/greenlet-3.5.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2a924f15d17957e252a810acefcb5942f5ca712298e8b6fcaed9a307d357522c", size = 1696584, upload-time = "2026-07-22T11:51:21.304Z" }, + { url = "https://files.pythonhosted.org/packages/f9/4d/55b638489260065de9ffce606c8b5d04507bef705de4b212a0c3d6a1a0df/greenlet-3.5.4-cp315-cp315-win_amd64.whl", hash = "sha256:ed17e5f3420360d5b459de8462efb52060399a5326a613d4cde31cef63ef95da", size = 248297, upload-time = "2026-07-22T11:42:04.055Z" }, + { url = "https://files.pythonhosted.org/packages/bb/08/9dd4ae635da93d41dc268bc34bd62a9d711ed8b8825c5d22ac910c7d6e6d/greenlet-3.5.4-cp315-cp315-win_arm64.whl", hash = "sha256:f908898d6fa484ce4b6f447ce70ea99b52c503fee419e53cf74d60a16bc9e667", size = 247423, upload-time = "2026-07-22T11:44:00.764Z" }, + { url = "https://files.pythonhosted.org/packages/19/66/7c87ed9cdbf1d49c2c6cd1c7b9dd4d16c33b24235ca03972293a1876b30c/greenlet-3.5.4-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:1833637f17d5e7472548a48575c394fe39f1b1890d676d162d86593610f44d8c", size = 306487, upload-time = "2026-07-22T11:41:25.118Z" }, + { url = "https://files.pythonhosted.org/packages/5b/05/0a4201e7c0054866eefc05da234f236dd4c950d0fbf9ca0517141f01b269/greenlet-3.5.4-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:12cda9122e03341f1cb6b8207a19d7a9d375e52f1b4e9243918375f40fd7b4b9", size = 676479, upload-time = "2026-07-22T12:26:48.129Z" }, + { url = "https://files.pythonhosted.org/packages/3d/c0/4b6b8c5a3aec70f0649cd89662d120fdd6421e2bdc8e3b15c3ab5ec568d8/greenlet-3.5.4-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d83ae0e32d14957ab7170785a20f582635c8474deab1bfbb552b17e769a6ce25", size = 684321, upload-time = "2026-07-22T12:29:08.925Z" }, + { url = "https://files.pythonhosted.org/packages/24/c9/b49c31c9a972eee91e260445770e922244a7efc542697f51a012ec046d0f/greenlet-3.5.4-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f1467de1bb767f75db0aa34c195e3a496d8d1278c796e70c24ce205d3e99cde", size = 681293, upload-time = "2026-07-22T11:51:20.43Z" }, + { url = "https://files.pythonhosted.org/packages/95/6f/7f2d4653770500eee667866016d42d7a68e3d3462f80df6b8e3fcd48a0eb/greenlet-3.5.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:0fa53040b78b578120eecdc0265e3f1051487cc425d11a2b7c761daadf4feaa8", size = 1642474, upload-time = "2026-07-22T12:25:10.819Z" }, + { url = "https://files.pythonhosted.org/packages/5a/d8/8cba31036a4caae448087ba5d150660ab03b4a0f54d9150f6495a3be7262/greenlet-3.5.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:60e0bc961d367df506660e9ac0177a76bc6d81305300704b0977d1634f76efe2", size = 1701012, upload-time = "2026-07-22T11:51:23.17Z" }, + { url = "https://files.pythonhosted.org/packages/e3/cd/3f77a4cce3bae631b08eb52f53a82a976669600337e21dfdba811cb50267/greenlet-3.5.4-cp315-cp315t-win_amd64.whl", hash = "sha256:f680e549edb3eaf21eea4e7fe101e15ec180c74b7879ab46adc080f22d4015d2", size = 251977, upload-time = "2026-07-22T11:41:38.125Z" }, + { url = "https://files.pythonhosted.org/packages/93/e8/65e8707d00fe2a49bf12f609a9b2b39ba6dd23c2810eacad877c4fc94bfe/greenlet-3.5.4-cp315-cp315t-win_arm64.whl", hash = "sha256:08fc36de8442d5c3e95b044550dbea9bf144d31ec0cc58e36fb241cb6ef6a994", size = 250538, upload-time = "2026-07-22T11:40:17.985Z" }, +] + +[[package]] +name = "inquirerpy" +version = "0.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pfzy" }, + { name = "prompt-toolkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/64/73/7570847b9da026e07053da3bbe2ac7ea6cde6bb2cbd3c7a5a950fa0ae40b/InquirerPy-0.3.4.tar.gz", hash = "sha256:89d2ada0111f337483cb41ae31073108b2ec1e618a49d7110b0d7ade89fc197e", size = 44431, upload-time = "2022-06-27T23:11:20.598Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/ff/3b59672c47c6284e8005b42e84ceba13864aa0f39f067c973d1af02f5d91/InquirerPy-0.3.4-py3-none-any.whl", hash = "sha256:c65fdfbac1fa00e3ee4fb10679f4d3ed7a012abf4833910e63c295827fe2a7d4", size = 67677, upload-time = "2022-06-27T23:11:17.723Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "kontor-robyn" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "asyncpg" }, + { name = "msgspec", extra = ["toml", "yaml"] }, + { name = "robyn", extra = ["all"] }, + { name = "sqlalchemy" }, +] + +[package.metadata] +requires-dist = [ + { name = "asyncpg", specifier = ">=0.31.0" }, + { name = "msgspec", extras = ["toml", "yaml"], specifier = ">=0.21.1" }, + { name = "robyn", extras = ["all"], specifier = ">=0.88.0" }, + { name = "sqlalchemy", specifier = ">=2.0.51" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "msgspec" +version = "0.21.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/60/f79b9b013a16fa3a58350c9295ddc6789f2e335f36ea61ed10a21b215364/msgspec-0.21.1.tar.gz", hash = "sha256:2313508e394b0d208f8f56892ca9b2799e2561329de9763b19619595a6c0f72c", size = 319193, upload-time = "2026-04-12T21:44:50.394Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/74/f11ede02839b19ff459f88e3145df5d711626ca84da4e23520cebf819367/msgspec-0.21.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:764173717a01743f007e9f74520ed281f24672c604514f7d76c1c3a10e8edb66", size = 196176, upload-time = "2026-04-12T21:44:17.613Z" }, + { url = "https://files.pythonhosted.org/packages/bb/40/4476c1bd341418a046c4955aff632ec769315d1e3cb94e6acf86d461f9ed/msgspec-0.21.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:344c7cd0eaed1fb81d7959f99100ef71ec9b536881a376f11b9a6c4803365697", size = 188524, upload-time = "2026-04-12T21:44:18.815Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d9/9e9d7d7e5061b47540d03d640fab9b3965ba7ae49c1b2154861c8f007518/msgspec-0.21.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48943e278b3854c2f89f955ddc6f9f430d3f0784b16e47d10604ee0463cd21f5", size = 218880, upload-time = "2026-04-12T21:44:20.028Z" }, + { url = "https://files.pythonhosted.org/packages/74/66/2bb344f34abb4b57e60c7c9c761994e0417b9718ec1460bf00c296f2a7ea/msgspec-0.21.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9aa659ebb0101b1cbc31461212b87e341d961f0ab0772aaf068a99e001ec4aa", size = 225050, upload-time = "2026-04-12T21:44:21.577Z" }, + { url = "https://files.pythonhosted.org/packages/1a/84/7c1e412f76092277bf760cef12b7979d03314d259ab5b5cafde5d0c1722d/msgspec-0.21.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7b27d1a8ead2b6f5b0c4f2d07b8be1ccfcc041c8a0e704781edebe3ae13c484", size = 222713, upload-time = "2026-04-12T21:44:22.83Z" }, + { url = "https://files.pythonhosted.org/packages/4e/27/0bba04b2b4ef05f3d068429410bc71d2cea925f1596a8f41152cccd5edb8/msgspec-0.21.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38fe93e86b61328fe544cb7fd871fad5a27c8734bfda90f65e5dbe288ae50f61", size = 227259, upload-time = "2026-04-12T21:44:24.11Z" }, + { url = "https://files.pythonhosted.org/packages/b0/2d/09574b0eea02fed2c2c1383dbaae2c7f79dc16dcd6487a886000afb5d7c4/msgspec-0.21.1-cp313-cp313-win_amd64.whl", hash = "sha256:8bc666331c35fcce05a7cd2d6221adbe0f6058f8e750711413d22793c080ac6a", size = 189857, upload-time = "2026-04-12T21:44:25.359Z" }, + { url = "https://files.pythonhosted.org/packages/46/34/105b1576ad182879914f0c821f17ee1d13abb165cb060448f96fe2aff078/msgspec-0.21.1-cp313-cp313-win_arm64.whl", hash = "sha256:42bb1241e0750c1a4346f2aa84db26c5ffd99a4eb3a954927d9f149ff2f42898", size = 175403, upload-time = "2026-04-12T21:44:26.608Z" }, + { url = "https://files.pythonhosted.org/packages/5a/ad/86954e987d1d6a5c579e2c2e7832b65e0fff194179fdac4f581536086024/msgspec-0.21.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fab48eb45fdbfbdb2c0edfec00ffc53b6b6085beefc6b50b61e01659f9f8757f", size = 196261, upload-time = "2026-04-12T21:44:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a1/c5e46c3e42b866199365e35d11dddfd1fbd8bba4fdb3c52f965b1607ce94/msgspec-0.21.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3cb779ea0c35bc807ff941d415875c1f69ca0be91a2e907ab99a171811d86a9a", size = 188729, upload-time = "2026-04-12T21:44:28.99Z" }, + { url = "https://files.pythonhosted.org/packages/85/7d/1e29a319d678d6cb962ae5bdf32a6858ebdf38f73bc654c0e9c742a0c2c8/msgspec-0.21.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68604db36b3b4dd9bf160e436e12798a4738848144cea1aca1cb984011eb160f", size = 219866, upload-time = "2026-04-12T21:44:31.104Z" }, + { url = "https://files.pythonhosted.org/packages/25/1f/cca084ca2572810fff12ea9dbdcbe39eac048f40daf4a9077b49fcbe8cee/msgspec-0.21.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3d6b9dc50948eaf65df54d2fd0ff66e6d8c32f116037209ee861810eb9b676cb", size = 224993, upload-time = "2026-04-12T21:44:32.649Z" }, + { url = "https://files.pythonhosted.org/packages/71/94/d2120fc9d419a89a3a7c13e5b7078798c4b392a96a02a6e2b3ce43a8766c/msgspec-0.21.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:52c5e21930942302394429c5a582ce7e6b62c7f983b3760834c2ce107e0dd6df", size = 223535, upload-time = "2026-04-12T21:44:33.839Z" }, + { url = "https://files.pythonhosted.org/packages/75/17/42418b66a3ad972a89bab73dd78b79cc6282bb488a25e73c853cee7443b9/msgspec-0.21.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:abbb39d65681fa24ed394e01af3d59d869068324f900c61d06062b7fb9980f2f", size = 227222, upload-time = "2026-04-12T21:44:35.093Z" }, + { url = "https://files.pythonhosted.org/packages/c4/33/265c894268cca88ff67b144ca2b4c522fc8b9a6f1966a3640c70516e78e1/msgspec-0.21.1-cp314-cp314-win_amd64.whl", hash = "sha256:5666b1b560b97b6ec2eb3fca8a502298ebac56e13bbca1f88523538ce83d01ea", size = 193810, upload-time = "2026-04-12T21:44:36.612Z" }, + { url = "https://files.pythonhosted.org/packages/3b/8f/a6d35f25bf1fc63c492fdd88fdce01ba0875ead48c2b91f90f33653b4131/msgspec-0.21.1-cp314-cp314-win_arm64.whl", hash = "sha256:d8b8578e4c83b14ceea4cef0d0b747e31d9330fe4b03b2b2ad4063866a178f93", size = 179125, upload-time = "2026-04-12T21:44:38.198Z" }, + { url = "https://files.pythonhosted.org/packages/c6/39/74839641e64b99d87da55af0fc472854d42b46e2183b9e2a67fe1bb2a512/msgspec-0.21.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:15f523d51c00ebad412213bfe9f06f0a50ec2b93e0c19e824a2d267cabb48ea2", size = 200171, upload-time = "2026-04-12T21:44:39.414Z" }, + { url = "https://files.pythonhosted.org/packages/70/9b/ce0cca6d2d87fcd4b6ff97600790494e64f26a2c55d61507cd2755c16193/msgspec-0.21.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4e47390360583ba3d5c6cb44cf0a9f61b0a06a899d3c2c00627cedebb2e2884b", size = 192879, upload-time = "2026-04-12T21:44:40.882Z" }, + { url = "https://files.pythonhosted.org/packages/a7/08/673a7bb05e5702dc787ddd3011195b509f9867927970da59052211929987/msgspec-0.21.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f60800e6299b798142dc40b0644da77ceac5ea0568be58228417eae14135c847", size = 226281, upload-time = "2026-04-12T21:44:42.181Z" }, + { url = "https://files.pythonhosted.org/packages/7d/45/86508cf57283e9070b3c447e3ab25b792a7a0855a3ea4e0c6d111ac34c97/msgspec-0.21.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5f8e9dfcd98419cf7568808470c4317a3fb30bef0e3715b568730a2b272a20d7", size = 229863, upload-time = "2026-04-12T21:44:43.442Z" }, + { url = "https://files.pythonhosted.org/packages/2c/62/e7c9367cd08d590559faacd711edbae36840342843e669440363f33c7d36/msgspec-0.21.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:92d89dfad13bd1ea640dc3e37e724ed380da1030b272bdf5ecafb983c3ad7c75", size = 230445, upload-time = "2026-04-12T21:44:44.806Z" }, + { url = "https://files.pythonhosted.org/packages/42/b4/c0f54632103846b658a10930025f4de41c8724b5e4805a5f3b395586cb7e/msgspec-0.21.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0d03867786e5d7ba25d666df4b11320c27170f4aeafcb8e3a8b0a50a4fb742ca", size = 231822, upload-time = "2026-04-12T21:44:46.343Z" }, + { url = "https://files.pythonhosted.org/packages/ea/1d/0d85cc79d0ccf5508e9c846cc66552a6a16bf92abd1dbd8362617f7b35cd/msgspec-0.21.1-cp314-cp314t-win_amd64.whl", hash = "sha256:740fbf1c9d59992ca3537d6fbe9ebbf9eaf726a65fbf31448e0ecbc710697a63", size = 206650, upload-time = "2026-04-12T21:44:47.601Z" }, + { url = "https://files.pythonhosted.org/packages/90/91/56c5d560f20e6c20e9e4f55bd0e458f7f162aa689ee350346c04c48eac0b/msgspec-0.21.1-cp314-cp314t-win_arm64.whl", hash = "sha256:0d2cc73df6058d811a126ac3a8ad63a4dfa210c82f9cf5a004802eaf4712de90", size = 183149, upload-time = "2026-04-12T21:44:48.833Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli-w" }, +] +yaml = [ + { name = "pyyaml" }, +] + +[[package]] +name = "multiprocess" +version = "0.70.19" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dill" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a2/f2/e783ac7f2aeeed14e9e12801f22529cc7e6b7ab80928d6dcce4e9f00922d/multiprocess-0.70.19.tar.gz", hash = "sha256:952021e0e6c55a4a9fe4cd787895b86e239a40e76802a789d6305398d3975897", size = 2079989, upload-time = "2026-01-19T06:47:39.744Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/45/8004d1e6b9185c1a444d6b55ac5682acf9d98035e54386d967366035a03a/multiprocess-0.70.19-py310-none-any.whl", hash = "sha256:97404393419dcb2a8385910864eedf47a3cadf82c66345b44f036420eb0b5d87", size = 134948, upload-time = "2026-01-19T06:47:32.325Z" }, + { url = "https://files.pythonhosted.org/packages/86/c2/dec9722dc3474c164a0b6bcd9a7ed7da542c98af8cabce05374abab35edd/multiprocess-0.70.19-py311-none-any.whl", hash = "sha256:928851ae7973aea4ce0eaf330bbdafb2e01398a91518d5c8818802845564f45c", size = 144457, upload-time = "2026-01-19T06:47:33.711Z" }, + { url = "https://files.pythonhosted.org/packages/71/70/38998b950a97ea279e6bd657575d22d1a2047256caf707d9a10fbce4f065/multiprocess-0.70.19-py312-none-any.whl", hash = "sha256:3a56c0e85dd5025161bac5ce138dcac1e49174c7d8e74596537e729fd5c53c28", size = 150281, upload-time = "2026-01-19T06:47:35.037Z" }, + { url = "https://files.pythonhosted.org/packages/7f/74/d2c27e03cb84251dfe7249b8e82923643c6d48fa4883b9476b025e7dc7eb/multiprocess-0.70.19-py313-none-any.whl", hash = "sha256:8d5eb4ec5017ba2fab4e34a747c6d2c2b6fecfe9e7236e77988db91580ada952", size = 156414, upload-time = "2026-01-19T06:47:35.915Z" }, + { url = "https://files.pythonhosted.org/packages/a0/61/af9115673a5870fd885247e2f1b68c4f1197737da315b520a91c757a861a/multiprocess-0.70.19-py314-none-any.whl", hash = "sha256:e8cc7fbdff15c0613f0a1f1f8744bef961b0a164c0ca29bdff53e9d2d93c5e5f", size = 160318, upload-time = "2026-01-19T06:47:37.497Z" }, + { url = "https://files.pythonhosted.org/packages/7e/82/69e539c4c2027f1e1697e09aaa2449243085a0edf81ae2c6341e84d769b6/multiprocess-0.70.19-py39-none-any.whl", hash = "sha256:0d4b4397ed669d371c81dcd1ef33fd384a44d6c3de1bd0ca7ac06d837720d3c5", size = 133477, upload-time = "2026-01-19T06:47:38.619Z" }, +] + +[[package]] +name = "orjson" +version = "3.11.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/0c/964746fcafbd16f8ff53219ad9f6b412b34f345c75f384ad434ceaadb538/orjson-3.11.9.tar.gz", hash = "sha256:4fef17e1f8722c11587a6ef18e35902450221da0028e65dbaaa543619e68e48f", size = 5599163, upload-time = "2026-05-06T15:11:08.309Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/33/93fcc25907235c344ae73122f8a4e01d2d393ef062b4af7d2e2487a32c37/orjson-3.11.9-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4bab1b2d6141fe7b32ae71dac905666ece4f94936efbfb13d55bb7739a3a6021", size = 228458, upload-time = "2026-05-06T15:10:20.079Z" }, + { url = "https://files.pythonhosted.org/packages/8f/27/b1e6dadb3c080313c03fdd8067b85e6a0460c7d8d6a1c3984ef77b904e4d/orjson-3.11.9-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:844417969855fc7a41be124aafe83dc424592a7f77cd4501900c67307122b92c", size = 128368, upload-time = "2026-05-06T15:10:21.549Z" }, + { url = "https://files.pythonhosted.org/packages/21/0f/c9ede0bf052f6b4051e64a7d4fa91b725cccf8321a6a786e86eb03519f00/orjson-3.11.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffe02797b5e9f3a9d8292ddcd289b474ad13e81ad83cd1891a240811f1d2cb81", size = 132070, upload-time = "2026-05-06T15:10:23.371Z" }, + { url = "https://files.pythonhosted.org/packages/fd/26/d398e28048dc18205bbe812f2c88cb9b40313db2470778e25964796458fe/orjson-3.11.9-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e4eed3b200023042814d2fc8a5d2e880f13b52e1ed2485e83da4f3962f7dc1a", size = 127892, upload-time = "2026-05-06T15:10:24.714Z" }, + { url = "https://files.pythonhosted.org/packages/66/60/52b0054c4c700d5aa7fc5b7ca96917400d8f061307778578e67a10e25852/orjson-3.11.9-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aff7da9952a5ad1cef8e68017724d96c7b9a66e99e91d6252e1b133d67a7b10", size = 135217, upload-time = "2026-05-06T15:10:26.084Z" }, + { url = "https://files.pythonhosted.org/packages/d5/97/1e3dc2b2a28b7b2528f403d2fc1d79ec5f39af3bc143ab65d3ec26426385/orjson-3.11.9-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d4e98d6f3b8afed8bc8cd9718ec0cdf46661826beefb53fe8eafb37f2bf0362", size = 145980, upload-time = "2026-05-06T15:10:28.062Z" }, + { url = "https://files.pythonhosted.org/packages/fc/39/31fbfe7850f2de32dee7e7e5c09f26d403ab01e440ac96001c6b01ad3c99/orjson-3.11.9-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a81d52442a7c99b3662333235b3adf96a1715864658b35bb797212be7bddb97", size = 132738, upload-time = "2026-05-06T15:10:29.727Z" }, + { url = "https://files.pythonhosted.org/packages/a1/08/dca0082dd2a194acb93e5457e73455388e2e2ca464a2672449a9ddbb679d/orjson-3.11.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e39364e726a8fff737309aff059ff67d8a8c8d5b677be7bb49a8b3e84b7e218", size = 134033, upload-time = "2026-05-06T15:10:31.152Z" }, + { url = "https://files.pythonhosted.org/packages/11/d4/5bdb0626801230139987385554c5d4c42255218ac906525bf4347f22cd95/orjson-3.11.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4fd66214623f1b17501df9f0543bef0b833979ab5b6ded1e1d123222866aa8c9", size = 141492, upload-time = "2026-05-06T15:10:32.641Z" }, + { url = "https://files.pythonhosted.org/packages/fa/88/a21fb53b3ede6703aede6dce4710ed4111e5b201cfa6bbff5e544f9d47d7/orjson-3.11.9-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:8ecc30f10465fa1e0ce13fd01d9e22c316e5053a719a8d915d4545a09a5ff677", size = 415087, upload-time = "2026-05-06T15:10:34.438Z" }, + { url = "https://files.pythonhosted.org/packages/3d/57/1b30daf70f0d8180e9a73cefbfbdd99e4bf19eb020466502b01fba7e0e50/orjson-3.11.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:97db4c94a7db398a5bd636273324f0b3fd58b350bbbac8bb380ceb825a9b40f4", size = 148031, upload-time = "2026-05-06T15:10:36.358Z" }, + { url = "https://files.pythonhosted.org/packages/04/83/45fbb6d962e260807f99441db9613cee868ceda4baceda59b3720a563f97/orjson-3.11.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9f78cf8fec5bd627f4082b8dfeac7871b43d7f3274904492a43dab39f18a19a0", size = 136915, upload-time = "2026-05-06T15:10:38.013Z" }, + { url = "https://files.pythonhosted.org/packages/5f/cc/2d10025f9056d376e4127ec05a5808b218d46f035fdc08178a5411b34250/orjson-3.11.9-cp313-cp313-win32.whl", hash = "sha256:d4087e5c0209a0a8efe4de3303c234b9c44d1174161dcd851e8eea07c7560b32", size = 131613, upload-time = "2026-05-06T15:10:39.569Z" }, + { url = "https://files.pythonhosted.org/packages/67/bd/2775ff28bfe883b9aa1ff348300542eb2ef1ee18d8ae0e3a49846817a865/orjson-3.11.9-cp313-cp313-win_amd64.whl", hash = "sha256:051b102c93b4f634e89f3866b07b9a9a98915ada541f4ec30f177067b2694979", size = 127086, upload-time = "2026-05-06T15:10:41.262Z" }, + { url = "https://files.pythonhosted.org/packages/91/2b/d26799e580939e32a7da9a39531bc9e58e15ca32ffaa6a8cb3e9bb0d22cd/orjson-3.11.9-cp313-cp313-win_arm64.whl", hash = "sha256:cce9127885941bd28f080cecf1f1d288336b7e0d812c345b08be88b572796254", size = 126696, upload-time = "2026-05-06T15:10:42.651Z" }, + { url = "https://files.pythonhosted.org/packages/8e/eb/5da01e356015aee6ecfa1187ced87aef51364e306f5e695dd52719bf0e78/orjson-3.11.9-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e", size = 228465, upload-time = "2026-05-06T15:10:44.097Z" }, + { url = "https://files.pythonhosted.org/packages/64/62/3e0e0c14c957133bcd855395c62b55ed4e3b0af23ffea11b032cb1dcbdb1/orjson-3.11.9-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:f36b7f32c7c0db4a719f1fc5824db4a9c6f8bd1a354debb91faf26ebf3a4c71e", size = 128364, upload-time = "2026-05-06T15:10:45.839Z" }, + { url = "https://files.pythonhosted.org/packages/5a/5a/07d8aa117211a8ed7630bda80c8c0b14d04e0f8dcf99bcf49656e4a710eb/orjson-3.11.9-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08f4d8ebb44925c794e535b2bebc507cebf32209df81de22ae285fb0d8d66de0", size = 132063, upload-time = "2026-05-06T15:10:47.267Z" }, + { url = "https://files.pythonhosted.org/packages/d6/ec/4acaf21483e18aa945be74a474c74b434f284b549f275a0a39b9f98956e9/orjson-3.11.9-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6cc7923789694fd58f001cbcac7e47abc13af4d560ebbfcf3b41a8b1a0748124", size = 122356, upload-time = "2026-05-06T15:10:48.765Z" }, + { url = "https://files.pythonhosted.org/packages/13/d8/5f0555e7638801323b7a75850f92e7dfa891bc84fe27a1ba4449170d1200/orjson-3.11.9-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea5c46eb2d3af39e806b986f4b09d5c2706a1f5afde3cbf7544ce6616127173c", size = 129592, upload-time = "2026-05-06T15:10:50.13Z" }, + { url = "https://files.pythonhosted.org/packages/b6/30/ed9860412a3603ceb3c5955bfd72d28b9d0e7ba6ed81add14f83d7114236/orjson-3.11.9-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f5d89a2ed90731df3be64bab0aa44f78bff39fdc9d71c291f4a8023aa46425b7", size = 140491, upload-time = "2026-05-06T15:10:51.582Z" }, + { url = "https://files.pythonhosted.org/packages/d0/17/adc514dea7ac7c505527febf884934b815d34f0c7b8693c1a8b39c5c4a57/orjson-3.11.9-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25e4aed0312d292c09f61af25bba34e0b2c88546041472b09088c39a4d828af1", size = 127309, upload-time = "2026-05-06T15:10:53.329Z" }, + { url = "https://files.pythonhosted.org/packages/76/3e/c0b690253f0b82d86e99949af13533363acfb5432ecb5d53dd5b3bce9c34/orjson-3.11.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db", size = 134030, upload-time = "2026-05-06T15:10:54.988Z" }, + { url = "https://files.pythonhosted.org/packages/c1/7a/bc82a0bb25e9faaf92dc4d9ef002732efc09737706af83e346788641d4a7/orjson-3.11.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a028425d1b440c5d92a6be1e1a020739dfe67ea87d96c6dbe828c1b30041728b", size = 141482, upload-time = "2026-05-06T15:10:56.663Z" }, + { url = "https://files.pythonhosted.org/packages/01/55/e69188b939f77d5d32a9833745ace31ea5ccae3ab613a1ec185d3cd2c4fb/orjson-3.11.9-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:5b192c6cf397e4455b11523c5cf2b18ed084c1bbd61b6c0926344d2129481972", size = 415178, upload-time = "2026-05-06T15:10:58.446Z" }, + { url = "https://files.pythonhosted.org/packages/2e/1a/b8a5a7ac527e80b9cb11d51e3f6689b709279183264b9ec5c7bc680bb8b5/orjson-3.11.9-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ea407d4ccf5891d667d045fecae97a7a1e5e87b3b97f97ae1803c2e741130be0", size = 148089, upload-time = "2026-05-06T15:11:00.441Z" }, + { url = "https://files.pythonhosted.org/packages/97/4e/00503f64204bf859b37213a63927028f30fb6268cd8677fb0a5ad48155e1/orjson-3.11.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5f63aaf97afd9f6dec5b1a68e1b8da12bfccb4cb9a9a65c3e0b6c847849e7586", size = 136921, upload-time = "2026-05-06T15:11:02.176Z" }, + { url = "https://files.pythonhosted.org/packages/0d/ba/a23b82a0a8d0ed7bed4e5f5035aae751cad4ff6a1e8d2ecd14d8860f5929/orjson-3.11.9-cp314-cp314-win32.whl", hash = "sha256:e30ab17845bb9fa54ccf67fa4f9f5282652d54faa6d17452f47d0f369d038673", size = 131638, upload-time = "2026-05-06T15:11:03.696Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c3/0c6798456bade745c75c452342dabacce5798196483e77e643be1f53877d/orjson-3.11.9-cp314-cp314-win_amd64.whl", hash = "sha256:32ef5f4283a3be81913947d19608eacb7c6608026851123790cd9cc8982af34b", size = 127078, upload-time = "2026-05-06T15:11:05.123Z" }, + { url = "https://files.pythonhosted.org/packages/16/21/5a3f1e8913103b703a436a5664238e5b965ec392b555fe68943ea3691e6b/orjson-3.11.9-cp314-cp314-win_arm64.whl", hash = "sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9", size = 126687, upload-time = "2026-05-06T15:11:06.602Z" }, +] + +[[package]] +name = "pfzy" +version = "0.3.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d9/5a/32b50c077c86bfccc7bed4881c5a2b823518f5450a30e639db5d3711952e/pfzy-0.3.4.tar.gz", hash = "sha256:717ea765dd10b63618e7298b2d98efd819e0b30cd5905c9707223dceeb94b3f1", size = 8396, upload-time = "2022-01-28T02:26:17.946Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8c/d7/8ff98376b1acc4503253b685ea09981697385ce344d4e3935c2af49e044d/pfzy-0.3.4-py3-none-any.whl", hash = "sha256:5f50d5b2b3207fa72e7ec0ef08372ef652685470974a107d0d4999fc5a903a96", size = 8537, upload-time = "2022-01-28T02:26:16.047Z" }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.53" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/ea/39b988c938f75cb75d7045b5c69f8bfed47ee2152c8837fb403de29d6fb8/prompt_toolkit-3.0.53.tar.gz", hash = "sha256:9ec8a0ad96d5c56148b3f914aa79c1564c3fde5d2e6b876e7bc327e353cf8fa6", size = 435492, upload-time = "2026-07-26T20:56:14.758Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/6f/84908cad2d6aa5144abcf7b42709fe4fdb459bc640ec7ac5786e7693dabc/prompt_toolkit-3.0.53-py3-none-any.whl", hash = "sha256:01c0891d7f9237d5e339f7d3e42cdae80b7534abb1c7c0e3352efba6231492f2", size = 392288, upload-time = "2026-07-26T20:56:12.512Z" }, +] + +[[package]] +name = "pydantic" +version = "2.13.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" }, + { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" }, + { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" }, + { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" }, + { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" }, + { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" }, + { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "robyn" +version = "0.88.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "inquirerpy" }, + { name = "multiprocess" }, + { name = "orjson" }, + { name = "rustimport" }, + { name = "uvloop", marker = "platform_machine != 'armv7l' and platform_python_implementation == 'CPython' and sys_platform != 'win32'" }, + { name = "watchdog" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/a3/c60e52b82a57b3551e9b283a2f583da39276d4526b70a89a0c34c17f999e/robyn-0.88.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:47ff0ab0c99b96cdc57f66843f2875cfb59d8ec58c5ec2277e36795c6ff9fc16", size = 3375497, upload-time = "2026-06-25T03:09:12.491Z" }, + { url = "https://files.pythonhosted.org/packages/7f/79/11bfac75c4e0ad5a71e9f28d5fa444e469ba8543d65b96ebcd28005ef056/robyn-0.88.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3e23102dd820e6f9e1f78929e68111920c1d0d8f361d7afe36dffc8734c1456c", size = 1816052, upload-time = "2026-06-25T03:09:14.19Z" }, + { url = "https://files.pythonhosted.org/packages/56/62/7d3eca16ec0fa9e8c30d3ff408ebc4a0066d56b482dd76fdbd8ea67063e6/robyn-0.88.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5fed59aff389ace14f103421832329d66831b26ace6a03fe3fe6eb610e6437da", size = 1947507, upload-time = "2026-06-25T03:09:15.665Z" }, + { url = "https://files.pythonhosted.org/packages/ad/73/ddfa30e6b0f209bb8c8734461a565ffc6e793939b36e9919f6776e462091/robyn-0.88.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32020972ae2a149fba92a9c8ee4fe630d27c9cda7ee34e99bb3ac2a0add2e8c5", size = 1860242, upload-time = "2026-06-25T03:09:17.178Z" }, + { url = "https://files.pythonhosted.org/packages/cd/6a/58100fddcf239a9e6a6addad90ee85ca1b563bdb5364bbd835acdbd9b289/robyn-0.88.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e220b0438313e15c299c2233335b7167418694c2f08370805c369d5506adba05", size = 1889553, upload-time = "2026-06-25T03:09:18.792Z" }, + { url = "https://files.pythonhosted.org/packages/91/84/17f82b338179b17a816c98b2fc107317f3ed803f41bb277252bbe91af52c/robyn-0.88.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf61564c3ca82b4d3e36b4c59d3ff3323dfc7fbeea9ad65de5ab21a2501ffd5", size = 1934487, upload-time = "2026-06-25T03:09:20.319Z" }, + { url = "https://files.pythonhosted.org/packages/64/5f/de99615c6dabb6d604673fb2939e8a8ceddba155f424f7468ebbb47c8574/robyn-0.88.0-cp313-cp313-win32.whl", hash = "sha256:1d72a0d063fa439a4cb03f43e29e1f6e5f3d676beea67ea136c2dec6377fd73c", size = 1683060, upload-time = "2026-06-25T03:09:21.989Z" }, + { url = "https://files.pythonhosted.org/packages/f9/40/04fd7d414e05dce1a8ef44a01e7f3ac3c813721d869b6610d35bdb53aa26/robyn-0.88.0-cp313-cp313-win_amd64.whl", hash = "sha256:a0c4801984a220ed50467bc95297474644ab13d4175da3288d48dda11ab172d9", size = 1751455, upload-time = "2026-06-25T03:09:23.684Z" }, + { url = "https://files.pythonhosted.org/packages/9f/44/c781b31b548305ccfa5657ef7260ff3b83d607b4dcebe64238c197945c29/robyn-0.88.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8f4846f848570b3c1cda029262a3bbd1b2e6e26ff8b6e049e7db7383223e749b", size = 3378970, upload-time = "2026-06-25T03:09:25.523Z" }, + { url = "https://files.pythonhosted.org/packages/f2/9c/26d44d07069993cc02d5152f726e5888624376a7a499df2e8d022a1e0689/robyn-0.88.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:1ed30c0612b93315e4476d372be665530669d3291d40e21ce0aba1542a8d151f", size = 1818120, upload-time = "2026-06-25T03:09:27.437Z" }, + { url = "https://files.pythonhosted.org/packages/25/c8/5d8deba0b4a9331a7faec7f6037669d64a3afd9c8ecdf49081cead56c5f0/robyn-0.88.0-cp314-cp314-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:44d63f1406ed4c98540c81f508a3054b32c9cb32bb8f87af2572f87ed97a75b2", size = 1949312, upload-time = "2026-06-25T03:09:29.505Z" }, + { url = "https://files.pythonhosted.org/packages/a5/43/23d86e451e4d2e8d4146c926e0ad3c577d3ceb7bf8c9ba46a7f3f6682940/robyn-0.88.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce5799ff4ee074b310274f9da8577b1f76dbf7569ccaa64b3426f7a71ab5b2b4", size = 1936436, upload-time = "2026-06-25T03:09:31.232Z" }, + { url = "https://files.pythonhosted.org/packages/fb/2b/a69145da54824100e992e383540c1f5ce2107af05b57678985c1e9ffcca6/robyn-0.88.0-cp314-cp314-win32.whl", hash = "sha256:18636a6c281c11cd04da57f5bf736af0c8ac795e42b6eef828a03c2f7d91f178", size = 1685477, upload-time = "2026-06-25T03:09:32.872Z" }, + { url = "https://files.pythonhosted.org/packages/94/ec/c294dff747ce717fceb1458b1b4240bb57dbb04e1ce96392486da2f9bb91/robyn-0.88.0-cp314-cp314-win_amd64.whl", hash = "sha256:06f3bfdc877dbadfe37bb9ee658e72fd60751954f6079f2c884318a0cc95519e", size = 1755139, upload-time = "2026-06-25T03:09:35.018Z" }, +] + +[package.optional-dependencies] +all = [ + { name = "jinja2" }, + { name = "pydantic" }, +] + +[[package]] +name = "rustimport" +version = "1.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "toml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/95/83/090f4be41dfbfd120a5fe0ed82b1857083bafe0928e876480d72a63e8bf3/rustimport-1.3.4.tar.gz", hash = "sha256:ba80e3c28af07ba3910ad395613d01f9e421bfb59fbb1ac050e2b5d9b78b4980", size = 28817, upload-time = "2023-07-13T14:52:23.479Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/e6/376cc02c6ec2dd29de14225bd322ea742b0b864c05c62abe40208ce64ebd/rustimport-1.3.4-py3-none-any.whl", hash = "sha256:f2b931ff4e0fa931028066a7dacaae449b1a4601fe7a553c35f3dd63aba97ce0", size = 26341, upload-time = "2023-07-13T14:52:21.789Z" }, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.51" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/f1/a7a892f18d4d224e6b26f706531eafccc41e37594d37d304786969ee13cb/sqlalchemy-2.0.51.tar.gz", hash = "sha256:804dccd8a4a6242c4e30ad961e540e18a588f6527202f2d6791b01845d59fdc9", size = 9912201, upload-time = "2026-06-15T15:41:20.012Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/fe/a210d52fd1a90ecfae8a78e9d8b27e18d733d60818a8bf250ff690b75120/sqlalchemy-2.0.51-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c2056838b6685b72fdb36c99996cf862753461a62f2e84f4196371d3b2d6a07", size = 2157184, upload-time = "2026-06-15T16:08:50.374Z" }, + { url = "https://files.pythonhosted.org/packages/17/6b/2dce8369b199cb855110e056032f94a9f66dacc2237d3d39c115a86eac56/sqlalchemy-2.0.51-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:483b11bd46bf35fc14c52faf338b04300c9e6ce554bce9b11be85bfec3bc3195", size = 3284735, upload-time = "2026-06-15T16:19:46.934Z" }, + { url = "https://files.pythonhosted.org/packages/53/ff/dbc495b8a14da840faffb353857a72d4190113cac33727906fb997047f0f/sqlalchemy-2.0.51-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1bed1ee8b01da6088210aa9412023326fb98a599ba502e6118308601dcbef77f", size = 3302756, upload-time = "2026-06-15T16:26:41.336Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d5/fde8f4dddcf518ee15ab35a7c6a28acc32c8ba548d1d2aa451f96e6dbb0b/sqlalchemy-2.0.51-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:72ca54c952107ba5cd58854b67a5a6268631289d21651a1235396f3b98b47400", size = 3232055, upload-time = "2026-06-15T16:19:49.286Z" }, + { url = "https://files.pythonhosted.org/packages/67/d1/43d3a0ac955a58601c24fa23038b1c55ee3a1ec02c0f96ebb1eae2bcf614/sqlalchemy-2.0.51-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b3e693d15533a45cd5906f0589f9c35090bef6ef45bf1e8195c424aa0ae06a8d", size = 3269850, upload-time = "2026-06-15T16:26:43.017Z" }, + { url = "https://files.pythonhosted.org/packages/94/df/de669c7054cd47c4439ac34b1b2ee8b804a794791fbb10720e997a2c87c7/sqlalchemy-2.0.51-cp313-cp313-win32.whl", hash = "sha256:b93ab07b5292dbe7e6b8da89475275e7042744283921344b56105f3eeb0f828b", size = 2117721, upload-time = "2026-06-15T16:23:12.36Z" }, + { url = "https://files.pythonhosted.org/packages/d0/8a/403c51d064196bae20a0bc2476577f83a3f8dd299719a97417086b7f2ec5/sqlalchemy-2.0.51-cp313-cp313-win_amd64.whl", hash = "sha256:0f053118c30e53161857a953e4de667d90e274980dccbe5dd3829bbbeece72a5", size = 2143615, upload-time = "2026-06-15T16:23:13.906Z" }, + { url = "https://files.pythonhosted.org/packages/b1/49/a739be2e1d02a96a658eb71ab45d921c874249252358ad24a5bffdd02525/sqlalchemy-2.0.51-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6ea306caaae6bd5afd0a46050003c88f6bf33227377a49298c498c3cb88ff491", size = 2158999, upload-time = "2026-06-15T16:08:51.759Z" }, + { url = "https://files.pythonhosted.org/packages/23/6b/2e0e38cf75c8780eca78d9b2e78164f8bcfd70125e5caa588ff5cbb9c9f4/sqlalchemy-2.0.51-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c45a496d6bc05dec41dcd4c3a2b183723f47473255c159cd80b503c8f246424d", size = 3282539, upload-time = "2026-06-15T16:19:51.065Z" }, + { url = "https://files.pythonhosted.org/packages/dd/a1/e77854cb5336fd37dc3c6ae3b71de242c98caac5725120be0b526b31cbd0/sqlalchemy-2.0.51-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4004ada0aafe8ae1991b2cd1d99c6d9146126e123bd6f883c260d974aa012e54", size = 3287545, upload-time = "2026-06-15T16:26:44.735Z" }, + { url = "https://files.pythonhosted.org/packages/f6/ab/9e17272fd4dac8df3b83c4fbe52b998a1c9d89a843c8c35ff29b74ff7364/sqlalchemy-2.0.51-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0f6bcad487aee1c638d707235682fc96f741de00663619881ab235400d03289e", size = 3230929, upload-time = "2026-06-15T16:19:52.625Z" }, + { url = "https://files.pythonhosted.org/packages/02/3c/52f408ea701781caee975606beccc48845f2aee8711ac29843d612c0306c/sqlalchemy-2.0.51-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:39a76529db6305693d8d4affa58ad5b5e2e18edd62daea628b29b97930b3513d", size = 3252888, upload-time = "2026-06-15T16:26:46.454Z" }, + { url = "https://files.pythonhosted.org/packages/24/16/3efd2ee6bc4ca4693a30a1dd17a91b606cae15d517d2a4746611d9b73ce8/sqlalchemy-2.0.51-cp314-cp314-win32.whl", hash = "sha256:08a204d8b5638717c26a24df18fcf40af45a6b22e35b70b1d62f0113c2e278e8", size = 2120551, upload-time = "2026-06-15T16:23:15.629Z" }, + { url = "https://files.pythonhosted.org/packages/7b/78/55b12e70f45bccc40d9e483925c065027b3b98ea4cbbdf6f8c2546feaf6c/sqlalchemy-2.0.51-cp314-cp314-win_amd64.whl", hash = "sha256:96747bfbadb055466e5b46d572618170046b45ce5a4879167f50d70a5319a499", size = 2146318, upload-time = "2026-06-15T16:23:17.108Z" }, + { url = "https://files.pythonhosted.org/packages/21/db/a9574ed40fed418924b1b1a3e54f47ee3963053b3d3d325a0d36b41f2c08/sqlalchemy-2.0.51-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e5ea1a213be1fcd5e49d9904c3b9939211ded90bc2a64e93f4c01963474285de", size = 2178920, upload-time = "2026-06-15T15:59:56.285Z" }, + { url = "https://files.pythonhosted.org/packages/bf/90/a1bb5c7cbba76b7bc1fbd586d0a5479a7bc9c27b4a8298f22ec9423b2bb3/sqlalchemy-2.0.51-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c6b36ed71f41942bdcd2ad2522be46bfce09d5705be5640ecf19bbc7660e4b7", size = 3566534, upload-time = "2026-06-15T15:58:35.024Z" }, + { url = "https://files.pythonhosted.org/packages/15/4b/481f1fed30e0e9e8dd24aecbb49f29eb57fe7657ece5cf06ee9b84bb97d8/sqlalchemy-2.0.51-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0c2c62877097e1a0db401fba5cb4debee33265e5b2a55c4ccb489c02c53b4f72", size = 3535844, upload-time = "2026-06-15T16:02:43.973Z" }, + { url = "https://files.pythonhosted.org/packages/02/71/0aa64aeda645510af0a43f7d9ee70932f0d1dc4263aed34c50ee891d9df3/sqlalchemy-2.0.51-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0378d055e9e8cd6ce4d8dff683bdd3d7d413533c4ee51d67a2b1e0f9eacc0f23", size = 3475355, upload-time = "2026-06-15T15:58:36.592Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/6061db32316446135a3abae5f308d144ab988a34234726042da3e58b1c63/sqlalchemy-2.0.51-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6e46fc36029eff666391e0531e5387b62ce6c4f1d8e50b3fb3099eaca1b42522", size = 3486591, upload-time = "2026-06-15T16:02:45.346Z" }, + { url = "https://files.pythonhosted.org/packages/0d/c9/f14fdf71bb8957e0c7e39db69bbdf12b5c80f4ef775fdfa127bf4e0d6760/sqlalchemy-2.0.51-cp314-cp314t-win32.whl", hash = "sha256:9161cfc9efce70d1715f47d6ff40f79c6778c00d53be4fbc09d70301e4b83ba7", size = 2151313, upload-time = "2026-06-15T16:03:39.127Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c6/673e618e6f4f297e126d9b56ea2f6478708f6c1af4e3223835c22e2c3697/sqlalchemy-2.0.51-cp314-cp314t-win_amd64.whl", hash = "sha256:159bb6ba32059f57ad7375a8f50d844dd2f19d14954ecf820cd33e20debd46b2", size = 2186280, upload-time = "2026-06-15T16:03:40.569Z" }, + { url = "https://files.pythonhosted.org/packages/e2/22/dbf013a12ec759e54a34a119e9e217435b3f71b2dd5c61a7ade0a25dae87/sqlalchemy-2.0.51-py3-none-any.whl", hash = "sha256:bb024d8b621d0be75f4f44ecc7c950450026e76d66dc8f791bb5331d7fed59d5", size = 1944334, upload-time = "2026-06-15T16:09:22.418Z" }, +] + +[[package]] +name = "toml" +version = "0.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload-time = "2020-11-01T01:40:22.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, +] + +[[package]] +name = "tomli-w" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184, upload-time = "2025-01-15T12:07:24.262Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675, upload-time = "2025-01-15T12:07:22.074Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "uvloop" +version = "0.22.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250, upload-time = "2025-10-16T22:17:19.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611, upload-time = "2025-10-16T22:16:36.833Z" }, + { url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811, upload-time = "2025-10-16T22:16:38.275Z" }, + { url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562, upload-time = "2025-10-16T22:16:39.375Z" }, + { url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890, upload-time = "2025-10-16T22:16:40.547Z" }, + { url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472, upload-time = "2025-10-16T22:16:41.694Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" }, + { url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067, upload-time = "2025-10-16T22:16:44.503Z" }, + { url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423, upload-time = "2025-10-16T22:16:45.968Z" }, + { url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437, upload-time = "2025-10-16T22:16:47.451Z" }, + { url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101, upload-time = "2025-10-16T22:16:49.318Z" }, + { url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158, upload-time = "2025-10-16T22:16:50.517Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360, upload-time = "2025-10-16T22:16:52.646Z" }, + { url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790, upload-time = "2025-10-16T22:16:54.355Z" }, + { url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783, upload-time = "2025-10-16T22:16:55.906Z" }, + { url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548, upload-time = "2025-10-16T22:16:57.008Z" }, + { url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065, upload-time = "2025-10-16T22:16:58.206Z" }, + { url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384, upload-time = "2025-10-16T22:16:59.36Z" }, + { url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730, upload-time = "2025-10-16T22:17:00.744Z" }, +] + +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, +] + +[[package]] +name = "wcwidth" +version = "0.8.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/34/74/c6428f875774288bec1396f5bfcbc2d925700a4dad61727fd5f2b12f249d/wcwidth-0.8.2.tar.gz", hash = "sha256:91fbef97204b96a3d4d421609b80340b760cf33e26da123ff243d76b1fda8dda", size = 1466253, upload-time = "2026-06-29T18:11:11.601Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/96/42/3e5985a0a7e57de470b320c6d6a1a67c844f6737a587f3d44dd13d1819e7/wcwidth-0.8.2-py3-none-any.whl", hash = "sha256:d63947694a0539a1d51e01eda7caf800c291020e6cdd7e28ad7b14dd33ad4f85", size = 323166, upload-time = "2026-06-29T18:11:09.888Z" }, +] diff --git a/kontor-schema/.gitignore b/kontor-schema/.gitignore deleted file mode 100644 index 849ddff..0000000 --- a/kontor-schema/.gitignore +++ /dev/null @@ -1 +0,0 @@ -dist/ diff --git a/kontor-schema/pyproject.toml b/kontor-schema/pyproject.toml deleted file mode 100644 index e32026a..0000000 --- a/kontor-schema/pyproject.toml +++ /dev/null @@ -1,18 +0,0 @@ -[project] -name = "kontor-schema" -version = "0.2.0" -description = "Kontor Schema Library" -readme = "README.md" -authors = [ - { name = "Thomas Peetz", email = "thomas.peetz@ingenieurbuero-peetz.de" } -] -requires-python = ">=3.13" -dependencies = [ - "beautifulsoup4>=4.13.4", - "requests>=2.32.3", - "sqlalchemy>=2.0.40", -] - -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" diff --git a/kontor-schema/src/kontor_schema/__init__.py b/kontor-schema/src/kontor_schema/__init__.py deleted file mode 100644 index 2f0718b..0000000 --- a/kontor-schema/src/kontor_schema/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from enum import Enum, auto - -from .admin import User, Token, Role, AuthorizationMatrix, ModuleData, MailAccount, Mail -from .bookshelf import Article, Book, Author, BookshelfPublisher, ArticleAuthor, BookAuthor -from .comic import Comic, Artist, Publisher, Issue, StoryArc, TradePaperback, Volume, ComicWork, WorkType -from .metadata import MetaDataTable, MetaDataColumn -from .tysc import Card, CardSet, Sport, Team, FieldPosition, Rooster, Player, Vendor -from .media import MediaFile, MediaArticle, MediaVideo -from .base import Base -from .database import KontorDB, ColumnEntry diff --git a/kontor-schema/src/kontor_schema/admin.py b/kontor-schema/src/kontor_schema/admin.py deleted file mode 100644 index bbc5c14..0000000 --- a/kontor-schema/src/kontor_schema/admin.py +++ /dev/null @@ -1,82 +0,0 @@ -from datetime import datetime - -<<<<<<<< HEAD:kontor-schema/src/kontor_schema/admin.py -from sqlalchemy import Column, ForeignKey, Integer, String -from sqlalchemy.dialects.mysql import BIT -======== -from sqlalchemy import Boolean, Column, ForeignKey, Integer, String ->>>>>>>> 934ef82 (Resolve "evaluate uv"):kontor-api/src/schema/admin.py -from sqlalchemy.orm import relationship, mapped_column, Mapped - -from .base import Base, BaseMixin - - -class User(Base, BaseMixin): - __tablename__ = 'user' - first_name = Column(String(255)) - last_name = Column(String(255)) - user_name = Column(String(255), nullable=False) - email = Column(String(255)) - password = Column(String(255)) - enabled = Column(BIT(1)) - matrix = relationship("AuthorizationMatrix") - tokens = relationship("Token") - - def get_full_name(self) -> str: - full_name = "" - if self.first_name is not None: - full_name += self.first_name - if self.last_name is not None: - if len(full_name) > 0: - full_name += " " - full_name += self.last_name - return full_name - - -class Token(Base, BaseMixin): - __tablename__ = "token" - token = Column(String(255), nullable=False, unique=True) - name = Column(String(255)) - last_used_date: Mapped[datetime] = mapped_column() - enabled = Column(BIT(1)) - user_id = Column(String(255), ForeignKey("user.id"), nullable=False) - user = relationship("User", back_populates="tokens") - - -class Role(Base, BaseMixin): - __tablename__ = "role" - name = Column(String(255), nullable=False) - matrix = relationship("AuthorizationMatrix") - - -class AuthorizationMatrix(Base, BaseMixin): - __tablename__ = "authorization_matrix" - user_id = Column(String, ForeignKey("user.id"), nullable=False) - user = relationship("User", back_populates="matrix") - role_id = Column(String, ForeignKey("role.id"), nullable=False) - role = relationship("Role", back_populates="matrix") - - -class ModuleData(Base, BaseMixin): - __tablename__ = "module_data" - module_name = Column(String(255), nullable=False) - import_data = Column(BIT(1)) - - -class MailAccount(Base, BaseMixin): - __tablename__ = "mail_account" - host = Column(String(255)) - port = Column(Integer) - protocol = Column(String(255)) - user_name = Column(String(255)) - password = Column(String(255)) - start_tls = Column(BIT(1)) - - -class Mail(Base, BaseMixin): - __tablename__ = "mail" - folder: Mapped[str] = mapped_column() - subject: Mapped[str] = mapped_column() - body: Mapped[str] = mapped_column() - sent_date: Mapped[datetime] = mapped_column() - received_date: Mapped[datetime] = mapped_column() diff --git a/kontor-schema/src/kontor_schema/base.py b/kontor-schema/src/kontor_schema/base.py deleted file mode 100644 index 4a354e7..0000000 --- a/kontor-schema/src/kontor_schema/base.py +++ /dev/null @@ -1,31 +0,0 @@ -import uuid -from datetime import datetime - -from sqlalchemy import func, Column, String -from sqlalchemy.dialects.mysql import BIT -from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column - - -class Base(DeclarativeBase): - pass - - -class BaseMixin: - id = Column(String(255), primary_key=True, default=uuid.uuid4()) - # id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4()) - # created_date = Column(DateTime) - created_date: Mapped[datetime] = mapped_column(default=func.now()) - # last_modified_date = Column(DateTime) - last_modified_date: Mapped[datetime] = mapped_column(default=func.now()) - # version = Column(Integer) - version: Mapped[int] = mapped_column(default=0) - - -class BaseVideoMixin: - cloud_link = Column(String(255)) - file_name = Column(String(255)) - path = Column(String(255)) - review = Column(BIT(1)) - title = Column(String(255)) - url = Column(String(255), unique=True) - should_download = Column(BIT(1)) diff --git a/kontor-schema/src/kontor_schema/bookshelf.py b/kontor-schema/src/kontor_schema/bookshelf.py deleted file mode 100644 index 91e0ae4..0000000 --- a/kontor-schema/src/kontor_schema/bookshelf.py +++ /dev/null @@ -1,50 +0,0 @@ -from sqlalchemy import Column, ForeignKey, Integer, String -from sqlalchemy.orm import relationship - -from .base import Base, BaseMixin - - -class Article(Base, BaseMixin): - __tablename__ = 'article' - title = Column(String(length=255), unique=True) - article_authors = relationship("ArticleAuthor") - - -class Author(Base, BaseMixin): - __tablename__ = 'author' - first_name = Column(String(255)) - last_name = Column(String(255)) - article_authors = relationship("ArticleAuthor") - book_authors = relationship("BookAuthor") - - -class BookshelfPublisher(Base, BaseMixin): - __tablename__ = 'bookshelf_publisher' - name = Column(String(length=255), unique=True) - books = relationship("Book") - - -class Book(Base, BaseMixin): - __tablename__ = 'book' - isbn = Column(String(255), unique=True) - title = Column(String(255)) - year = Column(Integer, nullable=False) - publisher_id = Column(String, ForeignKey('bookshelf_publisher.id'), nullable=False) - publisher = relationship('BookshelfPublisher', back_populates="books") - book_authors = relationship("BookAuthor") - - -class ArticleAuthor(Base, BaseMixin): - __tablename__ = 'article_author' - article_id = Column(String, ForeignKey('article.id'), nullable=False) - article = relationship('Article', back_populates="article_authors") - author_id = Column(String, ForeignKey('author.id'), nullable=False) - author = relationship('Author', back_populates="article_authors") - - -class BookAuthor(Base, BaseMixin): - __tablename__ = 'book_author' - author_id = Column(String, ForeignKey('author.id'), nullable=False) - author = relationship('Author', back_populates="book_authors") - book_id = Column(String, ForeignKey('book.id'), nullable=False) - book = relationship('Book', back_populates="book_authors") diff --git a/kontor-schema/src/kontor_schema/comic.py b/kontor-schema/src/kontor_schema/comic.py deleted file mode 100644 index 1052d79..0000000 --- a/kontor-schema/src/kontor_schema/comic.py +++ /dev/null @@ -1,100 +0,0 @@ -from sqlalchemy import Column, ForeignKey, Integer, String -from sqlalchemy.dialects.mysql import BIT -from sqlalchemy.orm import relationship - -from .base import Base, BaseMixin - - -class Publisher(Base, BaseMixin): - __tablename__ = "publisher" - name = Column(String(length=255), unique=True) - comics = relationship("Comic") - - def __repr__(self): - return f'Publisher({self.id} {self.name})' - - def __str__(self): - return self.__repr__() - - -class Comic(Base, BaseMixin): - __tablename__ = 'comic' - title = Column(String(length=255), unique=True) - publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False) - publisher = relationship("Publisher", back_populates="comics") - current_order = Column(BIT(1)) - completed = Column(BIT(1)) - issues = relationship("Issue") - story_arcs = relationship("StoryArc") - trade_paperbacks = relationship("TradePaperback") - volumes = relationship("Volume") - comic_works = relationship("ComicWork") - - def __repr__(self): - return f'Comic({self.id} {self.version} {self.title} {self.publisher.name})' - - def __str__(self): - return f'{self.title}({self.id})' - - -class Volume(Base, BaseMixin): - __tablename__ = "volume" - name = Column(String(length=255), nullable=False) - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="volumes") - issues = relationship("Issue") - - -class TradePaperback(Base, BaseMixin): - __tablename__ = "trade_paperback" - name = Column(String(length=255), nullable=False) - issue_start = Column(Integer) - issue_end = Column(Integer) - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="trade_paperbacks") - - -class StoryArc(Base, BaseMixin): - __tablename__ = "story_arc" - name = Column(String(length=255), nullable=False) - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="story_arcs") - - -class Issue(Base, BaseMixin): - __tablename__ = "issue" - issue_number = Column(String(255)) - in_stock = Column(BIT(1)) - is_read = Column(BIT(1)) - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="issues") - volume_id = Column(String, ForeignKey("volume.id"), nullable=True) - volume = relationship("Volume", back_populates="issues") - - -class Artist(Base, BaseMixin): - __tablename__ = "artist" - name = Column(String(length=255), nullable=False) - comic_works = relationship("ComicWork") - - -class WorkType(Base, BaseMixin): - __tablename__ = "worktype" - name = Column(String(length=255), nullable=False, unique=True) - comic_works = relationship("ComicWork") - - def __repr__(self): - return f'Worktype({self.id} {self.version} {self.name} {len(self.comic_works)})' - - def __str__(self): - return f'{self.name}({self.id})' - - -class ComicWork(Base, BaseMixin): - __tablename__ = "comic_work" - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="comic_works") - artist_id = Column(String, ForeignKey("artist.id"), nullable=False) - artist = relationship("Artist", back_populates="comic_works") - work_type_id = Column(String, ForeignKey("worktype.id"), nullable=False) - work_type = relationship("WorkType", back_populates="comic_works") diff --git a/kontor-schema/src/kontor_schema/database.py b/kontor-schema/src/kontor_schema/database.py deleted file mode 100644 index 54d3596..0000000 --- a/kontor-schema/src/kontor_schema/database.py +++ /dev/null @@ -1,396 +0,0 @@ -import json -import uuid -from datetime import datetime -from enum import Enum, auto -from logging import Logger -from pathlib import Path - -from sqlalchemy import Engine, select -from sqlalchemy.exc import IntegrityError -from sqlalchemy.orm import sessionmaker - -from .tysc import Card, CardSet, Rooster, Team, FieldPosition, Player, Vendor, Sport -from .comic import Issue, TradePaperback, StoryArc, Volume, ComicWork, Artist, Comic, Publisher, WorkType -from .bookshelf import ArticleAuthor, BookAuthor, BookshelfPublisher, Article, Book, Author -from .admin import Mail, MailAccount, ModuleData, Role, User, Token, AuthorizationMatrix -from .metadata import MetaDataTable, MetaDataColumn -from .media import MediaVideo, MediaArticle, MediaFile, MediaActor, MediaActorFile - - -class ColumnEntry(Enum): - COLUMN_NAME = 'column' - COLUMN_LABEL = 'label' - COLUMN_ORDER = 'order' - COLUMN_REF_COLUMN = 'ref_column' - COLUMN_TYPE = 'type' - COLUMN_WIDGET = 'widget' - - -class StatusType(Enum): - UNKNOWN = auto() - FILE_NAME = auto() - FILE_ID = auto() - DUPLICATE = auto() - CLOUD_LINK = auto() - CLOUD_LINK_ID = auto() - - -class ExportType(Enum): - JSON = "JSON" - YAML = "YAML" - SQLITE = "SQLite" - - -class KontorDB: - - def __init__(self, db_engine: Engine, log: Logger): - self.engine = db_engine - self.registry = {} - self.init_registry() - self.log = log - - def init_registry(self): - self.registry[Card.__tablename__] = Card - self.registry[CardSet.__tablename__] = CardSet - self.registry[Rooster.__tablename__] = Rooster - self.registry[Team.__tablename__] = Team - self.registry[FieldPosition.__tablename__] = FieldPosition - self.registry[Player.__tablename__] = Player - self.registry[Vendor.__tablename__] = Vendor - self.registry[Sport.__tablename__] = Sport - self.registry[Issue.__tablename__] = Issue - self.registry[TradePaperback.__tablename__] = TradePaperback - self.registry[StoryArc.__tablename__] = StoryArc - self.registry[Volume.__tablename__] = Volume - self.registry[ComicWork.__tablename__] = ComicWork - self.registry[Artist.__tablename__] = Artist - self.registry[Comic.__tablename__] = Comic - self.registry[Publisher.__tablename__] = Publisher - self.registry[WorkType.__tablename__] = WorkType - self.registry[ArticleAuthor.__tablename__] = ArticleAuthor - self.registry[BookAuthor.__tablename__] = BookAuthor - self.registry[BookshelfPublisher.__tablename__] = BookshelfPublisher - self.registry[Article.__tablename__] = Article - self.registry[Book.__tablename__] = Book - self.registry[Author.__tablename__] = Author - self.registry[MediaFile.__tablename__] = MediaFile - self.registry[MediaActor.__tablename__] = MediaActor - self.registry[MediaActorFile.__tablename__] = MediaActorFile - self.registry[MediaArticle.__tablename__] = MediaArticle - self.registry[MediaVideo.__tablename__] = MediaVideo - self.registry[MetaDataColumn.__tablename__] = MetaDataColumn - self.registry[MetaDataTable.__tablename__] = MetaDataTable - self.registry[AuthorizationMatrix.__tablename__] = AuthorizationMatrix - self.registry[Token.__tablename__] = Token - self.registry[User.__tablename__] = User - self.registry[Role.__tablename__] = Role - self.registry[ModuleData.__tablename__] = ModuleData - self.registry[MailAccount.__tablename__] = MailAccount - self.registry[Mail.__tablename__] = Mail - - def get_table_names(self) -> list: - result = [] - __session__ = sessionmaker(self.engine) - with __session__() as session: - tables = session.scalars(select(MetaDataTable)).all() - result = [table.table_name for table in tables] - return result - - def get_table_by_name(self, table_name: str) -> dict: - result = {} - __session__ = sessionmaker(self.engine) - _filter = {'table_name': table_name} - with __session__() as session: - table = session.query(MetaDataTable).filter_by(**_filter).one() - result['id'] = table.id - result['table_name'] = table.table_name - return result - - def get_column_meta_data(self, table_name: str, view_only=True) -> dict: - meta_data = {} - order = 0 - __session__ = sessionmaker(self.engine) - columns = list() - table_info = self.get_table_by_name(table_name) - _filters = {'table_id': table_info['id']} - if view_only: - _filters['is_shown'] = True - with __session__() as session: - columns = session.query(MetaDataColumn).filter_by(**_filters).all() - for column in columns: - # self.log.info("get_column_meta_data: %s %s %d", column.column_name, column.column_label, column.column_order) - meta_data[order] = { - ColumnEntry.COLUMN_NAME: column.column_name, - ColumnEntry.COLUMN_LABEL: column.column_label, - ColumnEntry.COLUMN_ORDER: column.column_order, - ColumnEntry.COLUMN_REF_COLUMN: column.ref_column, - ColumnEntry.COLUMN_TYPE: column.column_type - } - order += 1 - return meta_data - - def get_columns(self, table_name: str) -> dict: - columns = {} - __session__ = sessionmaker(self.engine) - table_info = self.get_table_by_name(table_name) - _filters = {'table_id': table_info['id']} - with __session__() as session: - for column in session.query(MetaDataColumn).filter_by(**_filters).all(): - columns[column.column_name] = { - ColumnEntry.COLUMN_ORDER: column.column_order, - ColumnEntry.COLUMN_TYPE: column.column_type - } - return columns - - def get_filters(self, table_name: str) -> dict: - _filter_map = {} - __session__ = sessionmaker(self.engine) - table_info = self.get_table_by_name(table_name) - _filters = {'table_id': table_info['id'], 'show_filter': True} - with __session__() as session: - for column in session.query(MetaDataColumn).filter_by(**_filters).all(): - _filter_map[column.column_name] = { - ColumnEntry.COLUMN_LABEL: column.filter_label, - ColumnEntry.COLUMN_WIDGET: None - } - return _filter_map - - def data(self, table_name: str, columns: dict, filters: dict) -> list: - data = [] - __session__ = sessionmaker(self.engine) - table = self.registry[table_name] - with __session__() as session: - entries = [] - if len(filters) == 0: - entries = session.scalars(select(table)).all() - else: - entries = session.scalars(select(table).filter_by(**filters)).all() - for entry in entries: - # self.log.info("data: %s", entry) - row = [] - for order in columns.keys(): - column_name = columns[order][ColumnEntry.COLUMN_NAME] - ref_column = columns[order][ColumnEntry.COLUMN_REF_COLUMN] - if str(column_name).endswith("_id"): - ref_table = column_name[:-3] - ref = getattr(entry, ref_table) - value = getattr(ref, ref_column) - row.append(value) - else: - row.append(getattr(entry, column_name)) - data.append(row) - # self.log.info("data: %s", data) - return data - - def export_db(self, export_type: ExportType, export_file_name: str) -> dict: - results = {} - db = {} - export_table_list = self.get_table_names() - for table in export_table_list: - columns = self.get_column_meta_data(table, view_only=False) - if table in self.registry: - model = self.registry[table] - else: - self.log.info(f"table {table} is not registered") - continue - __session__ = sessionmaker(self.engine) - with __session__() as session: - rows = session.query(model).all() - entries = [] - for row in rows: - # print(row) - entry = {} - for order in columns: - # print(columns[order]) - column_name = columns[order][ColumnEntry.COLUMN_NAME] - # print(f"get value {column_name} from {row} of table {table}") - try: - value = getattr(row, column_name) - if isinstance(value, datetime): - entry[column_name] = str(value) - else: - entry[column_name] = value - except AttributeError: - pass - entries.append(entry) - db[table] = entries - results[table] = len(entries) - match export_type: - case ExportType.JSON: - json_dump = json.dumps(db, indent=4) - with open(export_file_name, "w") as dump_file: - dump_file.write(json_dump) - case ExportType.YAML: - pass - case ExportType.SQLITE: - pass - self.log.info(f"{len(results)} tables exported") - return results - - def import_db(self, import_file_name: str) -> dict: - result = {} - import_file = Path(import_file_name) - if not import_file.exists(): - self.log.info(f"File {import_file_name} does not exist. Do nothing.") - return result - match import_file.suffix: - case '.json': - print("read json file") - with open(import_file_name, 'r') as json_file: - json_load = json.load(json_file) - for table in json_load: - self.log.info(f"{table}: {len(json_load[table])}") - result[table] = self.import_table(table, json_load[table]) - case '.yml': - print("read yaml file") - case '.yaml': - print("read yaml file") - case '.db': - print("read sqlite file") - return result - - def import_table(self, table_name: str, items:list) -> dict: - result = {} - updated = [] - added = [] - remaining = [] - existing_ids = self.get_ids(table_name) - self.log.info(f"found {len(existing_ids)} existing ids for table {table_name}") - for item in items: - current_id = item['id'] - # print(f"import item: {item}") - found_item = None - __session__ = sessionmaker(self.engine) - with __session__() as session: - found_item = session.get(self.registry[table_name], current_id) - # print(f"found item: {found_item}") - if found_item is not None: - changed = self.update_entry(table_name, current_id, item) - updated.append(item) - if changed: - self.log.info(f"{current_id} has changed") - updated.append(item) - existing_ids.remove(current_id) - else: - try: - self.add_entry(table_name, item) - added.append(item) - except IntegrityError as error: - self.log.info(f"Could not add item, due to: {error.detail}") - if len(existing_ids) > 0: - print(f"remaining items: {existing_ids}") - remaining.extend(existing_ids) - result['updated'] = updated - result['added'] = added - result['remaining'] = remaining - return result - - def get_ids(self, table_name: str) -> list: - existing_ids = [] - __session__ = sessionmaker(self.engine) - with __session__() as session: - items = session.query(self.registry[table_name]).all() - for item in items: - existing_ids.append(getattr(item, 'id')) - return existing_ids - - def add_entry(self, table_name: str, update_item: dict): - self.log.debug(f"add entry to table {table_name} with {update_item}") - __session__ = sessionmaker(self.engine) - with __session__() as session: - add_item = self.registry[table_name]() - for key in update_item.keys(): - update_value = update_item[key] - setattr(add_item, key, update_value) - session.add(add_item) - session.commit() - - def update_entry(self, table_name, current_id, update_item: dict) -> bool: - # self.log.info("update entry to table %s", table_name) - __session__ = sessionmaker(self.engine) - with __session__() as session: - existing_item = session.query(self.registry[table_name]).get(current_id) - changed = False - for key in update_item.keys(): - update_value = update_item[key] - existing_value = getattr(existing_item, key) - if type(existing_value) is not type(update_value): - existing_value = str(existing_value) - if existing_value != update_value: - self.log.info(f"{key} has changed: {existing_value} != {update_value}") - setattr(existing_item, key, update_value) - session.commit() - changed = True - self.log.info(f"update {key} with {update_value}") - return changed - - def add_link(self, link: str) -> dict: - result = {} - __session__ = sessionmaker(self.engine) - with __session__() as session: - media_file = MediaFile() - media_file.id = str(uuid.uuid4()) - media_file.created_date = datetime.now() - media_file.last_modified_date = datetime.now() - media_file.version = 0 - media_file.url = link - media_file.review = 1 - media_file.should_download = 1 - try: - session.add(media_file) - session.commit() - result['added'] = {'url': media_file.url, 'title': media_file.title, 'review': media_file.review, 'download': media_file.should_download} - except IntegrityError as error: - session.rollback() - result['error'] = error.orig - return result - - def update_titles(self) -> dict: - update_list = {} - __session__ = sessionmaker(self.engine) - _filter = { 'review': True} - with __session__() as session: - links = session.query(MediaFile).filter_by(**_filter).all() - for link in links: - url = link.url - if url is None: - continue - link.update_title() - session.commit() - update_list[link.id] = link.title - return update_list - - def get_download_list(self) -> list: - download_list = [] - __session__ = sessionmaker(self.engine) - _filter = { 'should_download': True} - with __session__() as session: - links = session.query(MediaFile).filter_by(**_filter).all() - for link in links: - url = link.url - if url is None: - continue - download_list.append(link.id) - return download_list - - def download_file(self, entry_id: str, download_dir = "/data/media", dl_tool = "yt-dlp") -> str: - __session__ = sessionmaker(self.engine) - with __session__() as session: - link = session.query(MediaFile).get(entry_id) - link.download_file(download_dir, dl_tool) - session.commit() - file_name = link.file_name - return file_name - - def delete_entries(self): - for (table_name, table) in self.registry.items(): - # self.log.info("delete entries from table %s", table_name) - __session__ = sessionmaker(self.engine) - with __session__() as session: - items = session.query(table).all() - for item in items: - session.delete(item) - session.commit() - - def check_files(self): - pass diff --git a/kontor-schema/src/kontor_schema/media.py b/kontor-schema/src/kontor_schema/media.py deleted file mode 100644 index a22be99..0000000 --- a/kontor-schema/src/kontor_schema/media.py +++ /dev/null @@ -1,93 +0,0 @@ -import re -import subprocess -from datetime import datetime -from pathlib import Path - -import requests -from bs4 import BeautifulSoup -from sqlalchemy import Column, String, ForeignKey -from sqlalchemy.dialects.mysql import BIT -from sqlalchemy.orm import relationship - -from .base import Base, BaseMixin, BaseVideoMixin - - -class MediaFile(Base, BaseMixin, BaseVideoMixin): - __tablename__ = 'media_file' - media_actor_files = relationship("MediaActorFile") - - def __repr__(self): - return f'MediaFile({self.id} {self.title} {self.title})' - - def __str__(self): - return f'{self.title}({self.id})' - - def update_title(self) -> None: - print(f"update title for {self.url}") - try: - r = requests.get(self.url) - soup = BeautifulSoup(r.content, "html.parser") - title = soup.title.string - self.title = title - self.review = 0 - except: - self.title = None - self.review = 1 - self.last_modified_date = datetime.now() - - def download_file(self, download_dir: str, dl_tool: str): - print(f"download file for {self.url} to {download_dir}") - result = subprocess.run([dl_tool, self.url], cwd=download_dir, capture_output=True, text=True) - if result.returncode == 0: - output = result.stdout - output = re.sub(' +', ' ', output) - lines_list = output.splitlines() - file_name = self.__parse_output__(lines_list) - if file_name is None: - self.review = True - self.should_download = True - self.file_name = None - else: - download_file = Path(file_name) - self.should_download = False - self.file_name = download_file.name - self.cloud_link = str(download_file.absolute()) - self.last_modified_date = datetime.now() - - def __parse_output__(self, lines_list): - self.file_name = None - for line in lines_list: - if 'has already been downloaded' in line: - end_len = len(' has already been downloaded') - self.file_name = line[11:-end_len] - if 'Destination' in line: - line_len = len(line) - start_len = len('[download] Destination: ') - file_len = line_len - start_len - self.file_name = line[-file_len:] - return self.file_name - - -class MediaActor(Base, BaseMixin): - __tablename__ = 'media_actor' - name = Column(String(255)) - media_actor_files = relationship("MediaActorFile") - - -class MediaActorFile(Base, BaseMixin): - __tablename__ = 'media_actor_file' - media_actor_id = Column(String(255), ForeignKey("media_actor.id"), nullable=False) - media_actor = relationship("MediaActor", back_populates="media_actor_files") - media_file_id = Column(String(255), ForeignKey("media_file.id"), nullable=False) - media_file = relationship("MediaFile", back_populates="media_actor_files") - - -class MediaArticle(Base, BaseMixin): - __tablename__ = 'media_article' - review = Column(BIT(1)) - title = Column(String(255)) - url = Column(String(255), unique=True) - - -class MediaVideo(Base, BaseMixin, BaseVideoMixin): - __tablename__ = 'media_video' diff --git a/kontor-schema/src/kontor_schema/metadata.py b/kontor-schema/src/kontor_schema/metadata.py deleted file mode 100644 index 950cebe..0000000 --- a/kontor-schema/src/kontor_schema/metadata.py +++ /dev/null @@ -1,42 +0,0 @@ -from sqlalchemy import Column, String, ForeignKey, Integer -from sqlalchemy.dialects.mysql import BIT -from sqlalchemy.orm import relationship - -from .base import Base, BaseMixin - - -class MetaDataTable(Base, BaseMixin): - __tablename__ = 'meta_data_table' - table_name = Column(String(255), unique=True) - table_columns = relationship("MetaDataColumn") - - def __repr__(self): - return f'MetaDataTable({self.id} {self.table_name})' - - def __str__(self): - return f'{self.table_name}({self.id})' - - -class MetaDataColumn(Base, BaseMixin): - __tablename__ = 'meta_data_column' - column_name = Column(String(255), nullable=False) - column_sync_name = Column(String(255)) - column_type = Column(String(255)) - column_modifier = Column(String(255), nullable=True) - column_order = Column(Integer) - table_id = Column(String, ForeignKey('meta_data_table.id')) - table = relationship("MetaDataTable", back_populates="table_columns") - column_label = Column(String(255)) - filter_label = Column(String(255)) - is_shown = Column(BIT(1)) - show_filter = Column(BIT(1)) - ref_column = Column(String, nullable=True) - - def __repr__(self): - if self.column_name is None: - return f'MetaDataColumn({self.id} {self.table.table_name}.__)' - else: - return f'MetaDataColumn({self.id} {self.table.table_name}.{self.column_name})' - - def __str__(self): - return f'{self.column_name}({self.id})' diff --git a/kontor-schema/src/kontor_schema/tysc.py b/kontor-schema/src/kontor_schema/tysc.py deleted file mode 100644 index 32c88f1..0000000 --- a/kontor-schema/src/kontor_schema/tysc.py +++ /dev/null @@ -1,100 +0,0 @@ -from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint -from sqlalchemy.dialects.mysql import BIT -from sqlalchemy.orm import relationship - -from .base import Base, BaseMixin - - -class Sport(Base, BaseMixin): - __tablename__ = "sport" - __table_args__ = ( - UniqueConstraint("name"), - ) - name = Column(String(255), nullable=False, index=True, unique=True) - teams = relationship("Team") - positions = relationship("FieldPosition") - - -class Team(Base, BaseMixin): - __tablename__ = "team" - name = Column(String(255), nullable=False, index=True, unique=True) - short_name = Column(String(255), nullable=False, ) - sport_id = Column(String, ForeignKey("sport.id"), nullable=False) - sport = relationship("Sport", back_populates="teams") - roosters = relationship("Rooster") - - -class FieldPosition(Base, BaseMixin): - __tablename__ = "field_position" - __table_args__ = ( - UniqueConstraint("name", "sport_id"), - UniqueConstraint("short_name", "sport_id"), - ) - name = Column(String(255), nullable=False, index=True) - short_name = Column(String(255), nullable=False) - sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True) - sport = relationship("Sport", back_populates="positions") - roosters = relationship("Rooster") - - -class Player(Base, BaseMixin): - __tablename__ = "player" - __table_args__ = ( - UniqueConstraint("first_name", "last_name"), - ) - first_name = Column(String(255), nullable=False, index=True) - last_name = Column(String(255), nullable=False, index=True) - roosters = relationship("Rooster") - - def get_full_name(self) -> str: - return f"{self.last_name}, {self.first_name}" - - -class Rooster(Base, BaseMixin): - __tablename__ = "rooster" - __table_args__ = ( - UniqueConstraint("year", "team_id", "player_id", "position_id"), - ) - year = Column(Integer) - team_id = Column(String, ForeignKey("team.id"), nullable=False, index=True) - team = relationship("Team", back_populates="roosters") - player_id = Column(String, ForeignKey("player.id"), nullable=False, index=True) - player = relationship("Player", back_populates="roosters") - position_id = Column(String, ForeignKey("field_position.id"), nullable=False, index=True) - position = relationship("FieldPosition", back_populates="roosters") - cards = relationship("Card") - - -class Vendor(Base, BaseMixin): - __tablename__ = "vendor" - name = Column(String(255), nullable=False, unique=True, index=True) - card_sets = relationship("CardSet") - cards = relationship("Card") - - -class CardSet(Base, BaseMixin): - __tablename__ = "card_set" - __table_args__ = ( - UniqueConstraint("name", "vendor_id"), - ) - name = Column(String(255), index=True) - parallel_set = Column(BIT(1)) - insert_set = Column(BIT(1)) - vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False, index=True) - vendor = relationship("Vendor", back_populates="card_sets") - cards = relationship("Card") - - -class Card(Base, BaseMixin): - __tablename__ = "card" - __table_args__ = ( - UniqueConstraint("card_number", "year", "vendor_id", "card_set_id"), - ) - card_number = Column(Integer, index=True) - year = Column(Integer, index=True) - card_set_id = Column(String, ForeignKey("card_set.id"), nullable=False) - card_set = relationship("CardSet", back_populates="cards") - rooster_id = Column(String, ForeignKey("rooster.id"), nullable=False) - rooster = relationship("Rooster", back_populates="cards") - vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False) - vendor = relationship("Vendor", back_populates="cards") diff --git a/kontor-schema/uv.lock b/kontor-schema/uv.lock deleted file mode 100644 index 984f615..0000000 --- a/kontor-schema/uv.lock +++ /dev/null @@ -1,161 +0,0 @@ -version = 1 -revision = 2 -requires-python = ">=3.13" - -[[package]] -name = "beautifulsoup4" -version = "4.13.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "soupsieve" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067, upload_time = "2025-04-15T17:05:13.836Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload_time = "2025-04-15T17:05:12.221Z" }, -] - -[[package]] -name = "certifi" -version = "2025.1.31" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577, upload_time = "2025-01-31T02:16:47.166Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393, upload_time = "2025-01-31T02:16:45.015Z" }, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188, upload_time = "2024-12-24T18:12:35.43Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698, upload_time = "2024-12-24T18:11:05.834Z" }, - { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162, upload_time = "2024-12-24T18:11:07.064Z" }, - { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263, upload_time = "2024-12-24T18:11:08.374Z" }, - { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966, upload_time = "2024-12-24T18:11:09.831Z" }, - { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992, upload_time = "2024-12-24T18:11:12.03Z" }, - { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162, upload_time = "2024-12-24T18:11:13.372Z" }, - { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972, upload_time = "2024-12-24T18:11:14.628Z" }, - { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095, upload_time = "2024-12-24T18:11:17.672Z" }, - { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668, upload_time = "2024-12-24T18:11:18.989Z" }, - { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073, upload_time = "2024-12-24T18:11:21.507Z" }, - { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732, upload_time = "2024-12-24T18:11:22.774Z" }, - { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391, upload_time = "2024-12-24T18:11:24.139Z" }, - { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702, upload_time = "2024-12-24T18:11:26.535Z" }, - { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767, upload_time = "2024-12-24T18:12:32.852Z" }, -] - -[[package]] -name = "greenlet" -version = "3.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/9c/666d8c71b18d0189cf801c0e0b31c4bfc609ac823883286045b1f3ae8994/greenlet-3.2.0.tar.gz", hash = "sha256:1d2d43bd711a43db8d9b9187500e6432ddb4fafe112d082ffabca8660a9e01a7", size = 183685, upload_time = "2025-04-15T16:21:26.141Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c9/43/c0b655d4d7eae19282b028bcec449e5c80626ad0d8d0ca3703f9b1c29258/greenlet-3.2.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:b86a3ccc865ae601f446af042707b749eebc297928ea7bd0c5f60c56525850be", size = 269131, upload_time = "2025-04-15T16:19:19.469Z" }, - { url = "https://files.pythonhosted.org/packages/7c/7d/c8f51c373c7f7ac0f73d04a6fd77ab34f6f643cb41a0d186d05ba96708e7/greenlet-3.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:144283ad88ed77f3ebd74710dd419b55dd15d18704b0ae05935766a93f5671c5", size = 637323, upload_time = "2025-04-15T16:49:02.677Z" }, - { url = "https://files.pythonhosted.org/packages/89/65/c3ee41b2e56586737d6e124b250583695628ffa6b324855b3a1267a8d1d9/greenlet-3.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5be69cd50994b8465c3ad1467f9e63001f76e53a89440ad4440d1b6d52591280", size = 651430, upload_time = "2025-04-15T16:50:43.445Z" }, - { url = "https://files.pythonhosted.org/packages/f0/07/33bd7a3dcde1db7259371d026ce76be1eb653d2d892334fc79a500b3c5ee/greenlet-3.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:47aeadd1e8fbdef8fdceb8fb4edc0cbb398a57568d56fd68f2bc00d0d809e6b6", size = 645798, upload_time = "2025-04-15T16:55:03.795Z" }, - { url = "https://files.pythonhosted.org/packages/35/5b/33c221a6a867030b0b770513a1b78f6c30e04294131dafdc8da78906bbe6/greenlet-3.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18adc14ab154ca6e53eecc9dc50ff17aeb7ba70b7e14779b26e16d71efa90038", size = 648271, upload_time = "2025-04-15T16:22:42.458Z" }, - { url = "https://files.pythonhosted.org/packages/4d/dd/d6452248fa6093504e3b7525dc2bdc4e55a4296ec6ee74ba241a51d852e2/greenlet-3.2.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8622b33d8694ec373ad55050c3d4e49818132b44852158442e1931bb02af336", size = 606779, upload_time = "2025-04-15T16:22:41.417Z" }, - { url = "https://files.pythonhosted.org/packages/9d/24/160f04d2589bcb15b8661dcd1763437b22e01643626899a4139bf98f02af/greenlet-3.2.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:e8ac9a2c20fbff3d0b853e9ef705cdedb70d9276af977d1ec1cde86a87a4c821", size = 1117968, upload_time = "2025-04-15T16:52:53.627Z" }, - { url = "https://files.pythonhosted.org/packages/6c/ff/c6e3f3a5168fef5209cfd9498b2b5dd77a0bf29dfc686a03dcc614cf4432/greenlet-3.2.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:cd37273dc7ca1d5da149b58c8b3ce0711181672ba1b09969663905a765affe21", size = 1145510, upload_time = "2025-04-15T16:23:01.873Z" }, - { url = "https://files.pythonhosted.org/packages/dc/62/5215e374819052e542b5bde06bd7d4a171454b6938c96a2384f21cb94279/greenlet-3.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8a8940a8d301828acd8b9f3f85db23069a692ff2933358861b19936e29946b95", size = 296004, upload_time = "2025-04-15T16:55:46.007Z" }, - { url = "https://files.pythonhosted.org/packages/62/6d/dc9c909cba5cbf4b0833fce69912927a8ca74791c23c47b9fd4f28092108/greenlet-3.2.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee59db626760f1ca8da697a086454210d36a19f7abecc9922a2374c04b47735b", size = 629900, upload_time = "2025-04-15T16:49:04.099Z" }, - { url = "https://files.pythonhosted.org/packages/5e/a9/f3f304fbbbd604858ff3df303d7fa1d8f7f9e45a6ef74481aaf03aaac021/greenlet-3.2.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7154b13ef87a8b62fc05419f12d75532d7783586ad016c57b5de8a1c6feeb517", size = 635270, upload_time = "2025-04-15T16:50:44.769Z" }, - { url = "https://files.pythonhosted.org/packages/34/92/4b7b4e2e23ecc723cceef9fe3898e78c8e14e106cc7ba2f276a66161da3e/greenlet-3.2.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:199453d64b02d0c9d139e36d29681efd0e407ed8e2c0bf89d88878d6a787c28f", size = 632534, upload_time = "2025-04-15T16:55:05.203Z" }, - { url = "https://files.pythonhosted.org/packages/da/7f/91f0ecbe72c9d789fb7f400b39da9d1e87fcc2cf8746a9636479ba79ab01/greenlet-3.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0010e928e1901d36625f21d008618273f9dda26b516dbdecf873937d39c9dff0", size = 628826, upload_time = "2025-04-15T16:22:44.545Z" }, - { url = "https://files.pythonhosted.org/packages/9f/59/e449a44ce52b13751f55376d85adc155dd311608f6d2aa5b6bd2c8d15486/greenlet-3.2.0-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6005f7a86de836a1dc4b8d824a2339cdd5a1ca7cb1af55ea92575401f9952f4c", size = 593697, upload_time = "2025-04-15T16:22:43.796Z" }, - { url = "https://files.pythonhosted.org/packages/bb/09/cca3392927c5c990b7a8ede64ccd0712808438d6490d63ce6b8704d6df5f/greenlet-3.2.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:17fd241c0d50bacb7ce8ff77a30f94a2d0ca69434ba2e0187cf95a5414aeb7e1", size = 1105762, upload_time = "2025-04-15T16:52:55.245Z" }, - { url = "https://files.pythonhosted.org/packages/4d/b9/3d201f819afc3b7a8cd7ebe645f1a17799603e2d62c968154518f79f4881/greenlet-3.2.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:7b17a26abc6a1890bf77d5d6b71c0999705386b00060d15c10b8182679ff2790", size = 1125173, upload_time = "2025-04-15T16:23:03.009Z" }, - { url = "https://files.pythonhosted.org/packages/80/7b/773a30602234597fc2882091f8e1d1a38ea0b4419d99ca7ed82c827e2c3a/greenlet-3.2.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:397b6bbda06f8fe895893d96218cd6f6d855a6701dc45012ebe12262423cec8b", size = 269908, upload_time = "2025-04-15T16:20:33.58Z" }, -] - -[[package]] -name = "idna" -version = "3.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload_time = "2024-09-15T18:07:39.745Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload_time = "2024-09-15T18:07:37.964Z" }, -] - -[[package]] -name = "kontor-schema" -version = "0.2.0" -source = { editable = "." } -dependencies = [ - { name = "beautifulsoup4" }, - { name = "requests" }, - { name = "sqlalchemy" }, -] - -[package.metadata] -requires-dist = [ - { name = "beautifulsoup4", specifier = ">=4.13.4" }, - { name = "requests", specifier = ">=2.32.3" }, - { name = "sqlalchemy", specifier = ">=2.0.40" }, -] - -[[package]] -name = "requests" -version = "2.32.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload_time = "2024-05-29T15:37:49.536Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload_time = "2024-05-29T15:37:47.027Z" }, -] - -[[package]] -name = "soupsieve" -version = "2.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418, upload_time = "2025-04-20T18:50:08.518Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload_time = "2025-04-20T18:50:07.196Z" }, -] - -[[package]] -name = "sqlalchemy" -version = "2.0.40" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/68/c3/3f2bfa5e4dcd9938405fe2fab5b6ab94a9248a4f9536ea2fd497da20525f/sqlalchemy-2.0.40.tar.gz", hash = "sha256:d827099289c64589418ebbcaead0145cd19f4e3e8a93919a0100247af245fa00", size = 9664299, upload_time = "2025-03-27T17:52:31.876Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/18/4e3a86cc0232377bc48c373a9ba6a1b3fb79ba32dbb4eda0b357f5a2c59d/sqlalchemy-2.0.40-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:915866fd50dd868fdcc18d61d8258db1bf9ed7fbd6dfec960ba43365952f3b01", size = 2107887, upload_time = "2025-03-27T18:40:05.461Z" }, - { url = "https://files.pythonhosted.org/packages/cb/60/9fa692b1d2ffc4cbd5f47753731fd332afed30137115d862d6e9a1e962c7/sqlalchemy-2.0.40-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a4c5a2905a9ccdc67a8963e24abd2f7afcd4348829412483695c59e0af9a705", size = 2098367, upload_time = "2025-03-27T18:40:07.182Z" }, - { url = "https://files.pythonhosted.org/packages/4c/9f/84b78357ca641714a439eb3fbbddb17297dacfa05d951dbf24f28d7b5c08/sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55028d7a3ebdf7ace492fab9895cbc5270153f75442a0472d8516e03159ab364", size = 3184806, upload_time = "2025-03-27T18:51:29.356Z" }, - { url = "https://files.pythonhosted.org/packages/4b/7d/e06164161b6bfce04c01bfa01518a20cccbd4100d5c951e5a7422189191a/sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cfedff6878b0e0d1d0a50666a817ecd85051d12d56b43d9d425455e608b5ba0", size = 3198131, upload_time = "2025-03-27T18:50:31.616Z" }, - { url = "https://files.pythonhosted.org/packages/6d/51/354af20da42d7ec7b5c9de99edafbb7663a1d75686d1999ceb2c15811302/sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb19e30fdae77d357ce92192a3504579abe48a66877f476880238a962e5b96db", size = 3131364, upload_time = "2025-03-27T18:51:31.336Z" }, - { url = "https://files.pythonhosted.org/packages/7a/2f/48a41ff4e6e10549d83fcc551ab85c268bde7c03cf77afb36303c6594d11/sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:16d325ea898f74b26ffcd1cf8c593b0beed8714f0317df2bed0d8d1de05a8f26", size = 3159482, upload_time = "2025-03-27T18:50:33.201Z" }, - { url = "https://files.pythonhosted.org/packages/33/ac/e5e0a807163652a35be878c0ad5cfd8b1d29605edcadfb5df3c512cdf9f3/sqlalchemy-2.0.40-cp313-cp313-win32.whl", hash = "sha256:a669cbe5be3c63f75bcbee0b266779706f1a54bcb1000f302685b87d1b8c1500", size = 2080704, upload_time = "2025-03-27T18:46:00.193Z" }, - { url = "https://files.pythonhosted.org/packages/1c/cb/f38c61f7f2fd4d10494c1c135ff6a6ddb63508d0b47bccccd93670637309/sqlalchemy-2.0.40-cp313-cp313-win_amd64.whl", hash = "sha256:641ee2e0834812d657862f3a7de95e0048bdcb6c55496f39c6fa3d435f6ac6ad", size = 2104564, upload_time = "2025-03-27T18:46:01.442Z" }, - { url = "https://files.pythonhosted.org/packages/d1/7c/5fc8e802e7506fe8b55a03a2e1dab156eae205c91bee46305755e086d2e2/sqlalchemy-2.0.40-py3-none-any.whl", hash = "sha256:32587e2e1e359276957e6fe5dad089758bc042a971a8a09ae8ecf7a8fe23d07a", size = 1903894, upload_time = "2025-03-27T18:40:43.796Z" }, -] - -[[package]] -name = "typing-extensions" -version = "4.13.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload_time = "2025-04-10T14:19:05.416Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload_time = "2025-04-10T14:19:03.967Z" }, -] - -[[package]] -name = "urllib3" -version = "2.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload_time = "2025-04-10T15:23:39.232Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload_time = "2025-04-10T15:23:37.377Z" }, -] diff --git a/kontor-scripts/Makefile b/kontor-scripts/Makefile deleted file mode 100644 index e66d08d..0000000 --- a/kontor-scripts/Makefile +++ /dev/null @@ -1,15 +0,0 @@ - -clean: - find . -name '*.py[co]' -delete - -test: - python -m pytest \ - -v \ - --cov=kontor \ - --cov-report=term \ - --cov-report=html:coverage-report \ - tests/ - -docker: clean - docker build -t kontor:latest . - diff --git a/kontor-scripts/add_actors.py b/kontor-scripts/add_actors.py deleted file mode 100644 index 04194cf..0000000 --- a/kontor-scripts/add_actors.py +++ /dev/null @@ -1,369 +0,0 @@ -""" -add actors -""" -import logging.config -import requests -import re -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter - -from bs4 import BeautifulSoup - -parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('--verbose', '-v', action='count', default=0) -args = parser.parse_args() - -def get_logger(level: int) -> logging.Logger: - logging.config.dictConfig({ - 'version': 1, - 'disable_existing_loggers': False, - 'formatters': { - 'simple': { - 'format': '[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s', - 'datefmt': '%Y-%m-%d %H:%M:%S', - }, - }, - 'handlers': { - 'console': { - 'class': logging.StreamHandler, - 'level': logging.DEBUG, - 'formatter': 'simple', - 'stream': 'ext://sys.stdout' - }, - }, - 'loggers': { - 'urllib3.connectionpool': { - 'level': 'WARNING', - 'propagate': False, - }, - 'root': { - 'level': 'DEBUG', - 'handlers': ['console'], - }, - }, - }) - logger = logging.getLogger(__file__) - if level is not None: - match level: - case 0: - logger.setLevel(logging.WARNING) - case 1: - logger.setLevel(logging.INFO) - case 2: - logger.setLevel(logging.DEBUG) - case _: - logger.setLevel(logging.CRITICAL) - return logger - - -if __name__ == '__main__': - log = get_logger(args.verbose) - log.warning('kontor.add_actors started') - log.debug('get all actors') - response = requests.get("http://127.0.0.1:8800/api/media/actors") - data = response.json() - actors = {} - for item in data: - actor = {} - actor['id'] = item['id'] - actor['name'] = item['name'] - actor['url'] = item['url'] - actors[item['url']] = actor - log.debug(f'all actors: {actors}') - - new_actor_list = [ - { 'name': 'Herschel Savage', 'url': 'https://ge.xhamster.com/pornstars/herschel-savage'}, - { 'name': 'Janey Robbins', 'url': 'https://ge.xhamster.com/pornstars/janey-robbins'}, - { 'name': 'Kimberly Carson', 'url': 'https://ge.xhamster.com/pornstars/kimberly-carson'}, - { 'name': 'Paul Thomas', 'url': 'https://ge.xhamster.com/pornstars/paul-thomas'}, - { 'name': 'Shauna Grant', 'url': 'https://ge.xhamster.com/pornstars/shauna-grant'}, - { 'name': 'Tara Aire', 'url': 'https://ge.xhamster.com/pornstars/tara-aire'}, - { 'name': 'Kari Milla', 'url': 'https://ge.xhamster.com/pornstars/kari-milla'}, - { 'name': 'Drago Gvozdik', 'url': 'https://ge.xhamster.com/pornstars/drago-gvozdik'}, - { 'name': 'Cheyne Collins', 'url': 'https://ge.xhamster.com/pornstars/cheyne-collins'}, - { 'name': 'Christian XXX', 'url': 'https://ge.xhamster.com/pornstars/christian-xxx'}, - { 'name': 'Derrick Pierce', 'url': 'https://ge.xhamster.com/pornstars/derrick-pierce'}, - { 'name': 'Holly Halston', 'url': 'https://ge.xhamster.com/pornstars/holly-halston'}, - { 'name': 'Holly West', 'url': 'https://ge.xhamster.com/pornstars/holly-west'}, - { 'name': 'Jarod Diamond', 'url': 'https://ge.xhamster.com/pornstars/jarod-diamond'}, - { 'name': 'Kristina Cross', 'url': 'https://ge.xhamster.com/pornstars/kristina-cross'}, - { 'name': 'Lee Stone', 'url': 'https://ge.xhamster.com/pornstars/lee-stone'}, - { 'name': 'Monica Mayhem', 'url': 'https://ge.xhamster.com/pornstars/monica-mayhem'}, - { 'name': 'Sienna West', 'url': 'https://ge.xhamster.com/pornstars/sienna-west'}, - { 'name': 'Aria Carson', 'url': 'https://ge.xhamster.com/pornstars/aria-carson'}, - { 'name': 'Britney Amber', 'url': 'https://ge.xhamster.com/pornstars/britney-amber'}, - { 'name': 'Kit Mercer', 'url': 'https://ge.xhamster.com/pornstars/kit-mercer'}, - { 'name': 'Riley Reyes', 'url': 'https://ge.xhamster.com/pornstars/riley-reyes'}, - { 'name': 'Ryan Keely', 'url': 'https://ge.xhamster.com/pornstars/ryan-keely'}, - { 'name': 'Alexandra Diamond', 'url': 'https://ge.xhamster.com/pornstars/alexandra-diamond'}, - { 'name': 'Amanda Twice', 'url': 'https://ge.xhamster.com/pornstars/amanda-twice'}, - { 'name': 'Choky Ice', 'url': 'https://ge.xhamster.com/pornstars/choky-ice'}, - { 'name': 'Cindy Cox', 'url': 'https://ge.xhamster.com/pornstars/cindy-cox'}, - { 'name': 'Kelly White', 'url': 'https://ge.xhamster.com/pornstars/kelly-white'}, - { 'name': 'Mike Foster', 'url': 'https://ge.xhamster.com/pornstars/mike-foster'}, - { 'name': 'Susie Sorrento', 'url': 'https://ge.xhamster.com/pornstars/susie-sorrento'}, - { 'name': 'Lara Sanchez', 'url': 'https://ge.xhamster.com/pornstars/lara-sanchez'}, - { 'name': 'Alicia Williams', 'url': 'https://ge.xhamster.com/pornstars/alicia-williams'}, - { 'name': 'Dirty Tina', 'url': 'https://ge.xhamster.com/pornstars/dirty-tina'}, - { 'name': 'Andrew Andretti', 'url': 'https://ge.xhamster.com/pornstars/andrew-andretti'}, - { 'name': 'Dick Nasty', 'url': 'https://ge.xhamster.com/pornstars/dick-nasty'}, - { 'name': 'Vicky Vette', 'url': 'https://ge.xhamster.com/pornstars/vicky-vette'}, - { 'name': 'Alex Gonz', 'url': 'https://ge.xhamster.com/pornstars/alex-gonz'}, - { 'name': 'Audrey Hollander', 'url': 'https://ge.xhamster.com/pornstars/audrey-hollander'}, - { 'name': 'Desiree Diamond', 'url': 'https://ge.xhamster.com/pornstars/desiree-diamond'}, - { 'name': 'Lexi Bardot', 'url': 'https://ge.xhamster.com/pornstars/lexi-bardot'}, - { 'name': 'Adam Ocelot', 'url': 'https://ge.xhamster.com/pornstars/adam-ocelot'}, - { 'name': 'Scarlett Hampton', 'url': 'https://ge.xhamster.com/pornstars/scarlett-hampton'}, - { 'name': 'Laetitia', 'url': 'https://ge.xhamster.com/pornstars/laetitia'}, - { 'name': 'Raffaela Anderson', 'url': 'https://ge.xhamster.com/pornstars/raffaela-anderson'}, - { 'name': 'Michael Swayze', 'url': 'https://ge.xhamster.com/pornstars/michael-swayze'}, - { 'name': 'Winter Jade', 'url': 'https://ge.xhamster.com/pornstars/winter-jade'}, - { 'name': 'Celine Noiret', 'url': 'https://ge.xhamster.com/pornstars/celine-noiret'}, - { 'name': 'Aurora Snow', 'url': 'https://ge.xhamster.com/pornstars/aurora-snow'}, - { 'name': 'Bree Brooks', 'url': 'https://ge.xhamster.com/pornstars/bree-brooks'}, - { 'name': 'Flick Shagwell', 'url': 'https://ge.xhamster.com/pornstars/flick-shagwell'}, - { 'name': 'Noname Jane', 'url': 'https://ge.xhamster.com/pornstars/noname-jane'}, - { 'name': 'Alex Magni', 'url': 'https://ge.xhamster.com/pornstars/alex-magni'}, - { 'name': 'Maeva Dream', 'url': 'https://ge.xhamster.com/pornstars/maeva-dream'}, - { 'name': 'Squirty Alice', 'url': 'https://ge.xhamster.com/pornstars/squirty-alice'}, - { 'name': 'Mandy Rhea', 'url': 'https://ge.xhamster.com/pornstars/mandy-rhea'}, - { 'name': 'Alessia Donati', 'url': 'https://ge.xhamster.com/pornstars/alessia-donati'}, - { 'name': 'Pierre DJ', 'url': 'https://ge.xhamster.com/pornstars/pierre-dj'}, - { 'name': 'Veronica Belli', 'url': 'https://ge.xhamster.com/pornstars/veronica-belli'}, - { 'name': 'Christiana Cinn', 'url': 'https://ge.xhamster.com/pornstars/christiana-cinn'}, - { 'name': 'Jasmine Jae', 'url': 'https://ge.xhamster.com/pornstars/jasmine-jae'}, - { 'name': 'Jay Smooth', 'url': 'https://ge.xhamster.com/pornstars/jay-smooth'}, - { 'name': 'Natalie Knight', 'url': 'https://ge.xhamster.com/pornstars/natalie-knight'}, - { 'name': 'Joshua Lewis', 'url': 'https://ge.xhamster.com/pornstars/joshua-lewis'}, - { 'name': 'Lauren Phillips', 'url': 'https://ge.xhamster.com/pornstars/lauren-phillips'}, - { 'name': 'Matt Cash', 'url': 'https://ge.xhamster.com/pornstars/matt-cash'}, - { 'name': 'Nickey Huntsman', 'url': 'https://ge.xhamster.com/pornstars/nickey-huntsman'}, - { 'name': 'Jade Sin', 'url': 'https://ge.xhamster.com/pornstars/jade-sin'}, - { 'name': 'Wein Lewis', 'url': 'https://ge.xhamster.com/pornstars/wein-lewis'}, - { 'name': 'Megan Murkovski', 'url': 'https://ge.xhamster.com/pornstars/megan-murkovski'}, - { 'name': 'Tara Wild', 'url': 'https://ge.xhamster.com/pornstars/tara-wild'}, - { 'name': 'Lana Roy', 'url': 'https://ge.xhamster.com/pornstars/lana-roy'}, - { 'name': 'Nick Moreno', 'url': 'https://ge.xhamster.com/pornstars/nick-moreno'}, - { 'name': 'Brad Armstrong', 'url': 'https://ge.xhamster.com/pornstars/brad-armstrong'}, - { 'name': 'Kaylani Lei', 'url': 'https://ge.xhamster.com/pornstars/kaylani-lei'}, - { 'name': 'Deborah Wells', 'url': 'https://ge.xhamster.com/pornstars/deborah-wells'}, - { 'name': 'Judith Ramirez', 'url': 'https://ge.xhamster.com/pornstars/judith-ramirez'}, - { 'name': 'Richard Langin', 'url': 'https://ge.xhamster.com/pornstars/richard-langin'}, - { 'name': 'Simona Valli', 'url': 'https://ge.xhamster.com/pornstars/simona-valli'}, - { 'name': 'Mandy Dee', 'url': 'https://ge.xhamster.com/pornstars/mandy-dee'}, - { 'name': 'Allison Wyte', 'url': 'https://ge.xhamster.com/pornstars/allison-wyte'}, - { 'name': 'Ben English', 'url': 'https://ge.xhamster.com/pornstars/ben-english'}, - { 'name': 'Chuck Martino', 'url': 'https://ge.xhamster.com/pornstars/chuck-martino'}, - { 'name': 'Erika Kole', 'url': 'https://ge.xhamster.com/pornstars/erika-kole'}, - { 'name': 'Katie Morgan', 'url': 'https://ge.xhamster.com/pornstars/katie-morgan'}, - { 'name': 'Misty Parks', 'url': 'https://ge.xhamster.com/pornstars/misty-parks'}, - { 'name': 'Mr. Pete', 'url': 'https://ge.xhamster.com/pornstars/mr-pete'}, - { 'name': 'Candie Luciani', 'url': 'https://ge.xhamster.com/pornstars/candie-luciani'}, - { 'name': 'Clara Mia', 'url': 'https://ge.xhamster.com/pornstars/clara-mia'}, - { 'name': 'Tommy Cabrio', 'url': 'https://ge.xhamster.com/pornstars/tommy-cabrio'}, - { 'name': 'Nathan Bronson', 'url': 'https://ge.xhamster.com/pornstars/nathan-bronson'}, - { 'name': 'Octavia Red', 'url': 'https://ge.xhamster.com/pornstars/octavia-red'}, - { 'name': 'Big George', 'url': 'https://ge.xhamster.com/pornstars/big-george'}, - { 'name': 'Cassy Young', 'url': 'https://ge.xhamster.com/pornstars/cassy-young'}, - { 'name': 'Egon Kowalski', 'url': 'https://ge.xhamster.com/pornstars/egon-kowalski'}, - { 'name': 'Mark Aurel', 'url': 'https://ge.xhamster.com/pornstars/mark-aurel'}, - { 'name': 'Samy Fox', 'url': 'https://ge.xhamster.com/pornstars/samy-fox'}, - { 'name': 'Valeria Jones', 'url': 'https://ge.xhamster.com/pornstars/valeria-jones'}, - { 'name': 'Dieter Von Stein', 'url': 'https://ge.xhamster.com/pornstars/dieter-von-stein'}, - { 'name': 'Donna Bell', 'url': 'https://ge.xhamster.com/pornstars/donna-bell'}, - { 'name': 'Molly Jane', 'url': 'https://ge.xhamster.com/pornstars/molly-jane'}, - { 'name': 'Mark Zane', 'url': 'https://ge.xhamster.com/pornstars/mark-zane'}, - { 'name': 'Titus Steel', 'url': 'https://ge.xhamster.com/pornstars/titus-steel'}, - { 'name': 'Mackenzie Mace', 'url': 'https://ge.xhamster.com/pornstars/mackenzie-mace'}, - { 'name': 'Christina Lang', 'url': 'https://ge.xhamster.com/pornstars/christina-lang'}, - { 'name': 'Jens Modena', 'url': 'https://ge.xhamster.com/pornstars/jens-modena'}, - { 'name': 'Karma Rosenberg', 'url': 'https://ge.xhamster.com/pornstars/karma-rosenberg'}, - { 'name': 'Dani Jensen', 'url': 'https://ge.xhamster.com/pornstars/dani-jensen'}, - { 'name': 'Crystal Ray', 'url': 'https://ge.xhamster.com/pornstars/crystal-ray'}, - { 'name': 'Andrea Szabo', 'url': 'https://ge.xhamster.com/pornstars/andrea-szabo'}, - { 'name': 'Desiree Barclay', 'url': 'https://ge.xhamster.com/pornstars/desiree-barclay'}, - { 'name': 'Jada Stevens', 'url': 'https://ge.xhamster.com/pornstars/jada-stevens'}, - { 'name': 'Syren Demer', 'url': 'https://ge.xhamster.com/pornstars/syren-demer'}, - { 'name': 'Ara Mix', 'url': 'https://ge.xhamster.com/pornstars/ara-mix'}, - { 'name': 'Redneck John', 'url': 'https://ge.xhamster.com/pornstars/redneck-john'}, - { 'name': 'Allysin Chaynes', 'url': 'https://ge.xhamster.com/pornstars/allysin-chaynes'}, - { 'name': 'Aspen Brock', 'url': 'https://ge.xhamster.com/pornstars/aspen-brock'}, - { 'name': 'Kaylynn', 'url': 'https://ge.xhamster.com/pornstars/kaylynn'}, - { 'name': 'Monica Cameron', 'url': 'https://ge.xhamster.com/pornstars/monica-cameron'}, - { 'name': 'Sheila Rossi', 'url': 'https://ge.xhamster.com/pornstars/sheila-rossi'}, - { 'name': 'Alex Ginger', 'url': 'https://ge.xhamster.com/pornstars/alex-ginger'}, - { 'name': 'Ally Style', 'url': 'https://ge.xhamster.com/pornstars/ally-style'}, - { 'name': 'Paola Mike', 'url': 'https://ge.xhamster.com/pornstars/paola-mike'}, - { 'name': 'Jeanette Littledove', 'url': 'https://ge.xhamster.com/pornstars/jeanette-littledove'}, - { 'name': 'Melissa Melendez', 'url': 'https://ge.xhamster.com/pornstars/melissa-melendez'}, - { 'name': 'Peter North', 'url': 'https://ge.xhamster.com/pornstars/peter-north'}, - { 'name': 'Siobhan Hunter', 'url': 'https://ge.xhamster.com/pornstars/siobhan-hunter'}, - { 'name': 'Tami White', 'url': 'https://ge.xhamster.com/pornstars/tami-white'}, - { 'name': 'Tracey Adams', 'url': 'https://ge.xhamster.com/pornstars/tracey-adams'}, - { 'name': 'Ashley Haze', 'url': 'https://ge.xhamster.com/pornstars/ashley-haze'}, - { 'name': 'Cailey Taylor', 'url': 'https://ge.xhamster.com/pornstars/cailey-taylor'}, - { 'name': 'Eve Laurence', 'url': 'https://ge.xhamster.com/pornstars/eve-laurence'}, - { 'name': 'Naudia Nyce', 'url': 'https://ge.xhamster.com/pornstars/naudia-nyce'}, - { 'name': 'Candy Apples', 'url': 'https://ge.xhamster.com/pornstars/candy-apples'}, - { 'name': 'Kate Rich', 'url': 'https://ge.xhamster.com/pornstars/kate-rich'}, - { 'name': 'Aniko Kaposi', 'url': 'https://ge.xhamster.com/pornstars/aniko-kaposi'}, - { 'name': 'Beatrice Poggi', 'url': 'https://ge.xhamster.com/pornstars/beatrice-poggi'}, - { 'name': 'Erika Bella', 'url': 'https://ge.xhamster.com/pornstars/erika-bella'}, - { 'name': 'Nikita Gross', 'url': 'https://ge.xhamster.com/pornstars/nikita-gross'}, - { 'name': 'Ursula Moore', 'url': 'https://ge.xhamster.com/pornstars/ursula-moore'}, - { 'name': 'Caty Kiss', 'url': 'https://ge.xhamster.com/pornstars/caty-kiss'}, - { 'name': 'Light Fairy', 'url': 'https://ge.xhamster.com/pornstars/light-fairy'}, - { 'name': 'Flame', 'url': 'https://ge.xhamster.com/pornstars/flame'}, - { 'name': 'Tiffany Tatum', 'url': 'https://ge.xhamster.com/pornstars/tiffany-tatum'}, - { 'name': 'Alyson Sykes', 'url': 'https://ge.xhamster.com/pornstars/alyson-sykes'}, - { 'name': 'Jenifer Stone', 'url': 'https://ge.xhamster.com/pornstars/jenifer-stone'}, - { 'name': 'Lucy Love', 'url': 'https://ge.xhamster.com/pornstars/lucy-love'}, - { 'name': 'Thomas Stone', 'url': 'https://ge.xhamster.com/pornstars/thomas-stone'}, - { 'name': 'Nikki Babe', 'url': 'https://ge.xhamster.com/pornstars/nikki-babe'}, - { 'name': 'Tyra Misoux', 'url': 'https://ge.xhamster.com/pornstars/tyra-misoux'}, - { 'name': 'Kenzie Reeves', 'url': 'https://ge.xhamster.com/pornstars/kenzie-reeves'}, - { 'name': 'Anissa Kate', 'url': 'https://ge.xhamster.com/pornstars/anissa-kate'}, - { 'name': 'Anna Polina', 'url': 'https://ge.xhamster.com/pornstars/anna-polina'}, - { 'name': 'Kimber Delice', 'url': 'https://ge.xhamster.com/pornstars/kimber-delice'}, - { 'name': 'Lucy Heart', 'url': 'https://ge.xhamster.com/pornstars/lucy-heart'}, - { 'name': 'John Strong', 'url': 'https://ge.xhamster.com/pornstars/john-strong'}, - { 'name': 'Markus Dupree', 'url': 'https://ge.xhamster.com/pornstars/markus-dupree'}, - { 'name': 'Mick Blue', 'url': 'https://ge.xhamster.com/pornstars/mick-blue'}, - { 'name': 'Natasha Nice', 'url': 'https://ge.xhamster.com/pornstars/natasha-nice'}, - { 'name': 'Lena Reif', 'url': 'https://ge.xhamster.com/pornstars/lena-reif'}, - { 'name': 'Sonia Paganini', 'url': 'https://ge.xhamster.com/pornstars/sonia-paganini'}, - { 'name': 'Demi Hawks', 'url': 'https://ge.xhamster.com/pornstars/demi-hawks'}, - { 'name': 'Juan El Caballo Loco', 'url': 'https://ge.xhamster.com/pornstars/juan-el-caballo-loco'}, - { 'name': 'Mike Mancini', 'url': 'https://ge.xhamster.com/pornstars/mike-mancini'}, - { 'name': 'Millie Morgan', 'url': 'https://ge.xhamster.com/pornstars/millie-morgan'}, - { 'name': 'Richard Allan', 'url': 'https://ge.xhamster.com/pornstars/richard-allan'}, - { 'name': 'Damon Dice', 'url': 'https://ge.xhamster.com/pornstars/damon-dice'}, - { 'name': 'Sera Ryder', 'url': 'https://ge.xhamster.com/pornstars/sera-ryder'}, - { 'name': 'Zoltan Kaabai', 'url': 'https://ge.xhamster.com/pornstars/zoltan-kabai'}, - { 'name': 'Cathy Heaven', 'url': 'https://ge.xhamster.com/pornstars/cathy-heaven'}, - { 'name': 'Coco Lovelock', 'url': 'https://ge.xhamster.com/pornstars/coco-lovelock'}, - { 'name': 'Percy Sires', 'url': 'https://ge.xhamster.com/pornstars/percy-sires'}, - { 'name': 'Meridian', 'url': 'https://ge.xhamster.com/pornstars/meridian'}, - { 'name': 'Pascal St. James', 'url': 'https://ge.xhamster.com/pornstars/pascal-st-james'}, - { 'name': 'Red Fox', 'url': 'https://ge.xhamster.com/pornstars/red-fox'}, - { 'name': 'Tony Art', 'url': 'https://ge.xhamster.com/pornstars/tony-art'}, - { 'name': 'Addison Lee', 'url': 'https://ge.xhamster.com/pornstars/addison-lee'}, - { 'name': 'Daria Glover', 'url': 'https://ge.xhamster.com/pornstars/daria-glover'}, - { 'name': 'Mandy Bright', 'url': 'https://ge.xhamster.com/pornstars/mandy-bright'}, - { 'name': 'Antonia Sainz', 'url': 'https://ge.xhamster.com/pornstars/antonia-sainz'}, - { 'name': 'Nicole Love', 'url': 'https://ge.xhamster.com/pornstars/nicole-love'}, - { 'name': 'Sarah Kay', 'url': 'https://ge.xhamster.com/pornstars/sarah-kay'}, - { 'name': 'Judith Kostner', 'url': 'https://ge.xhamster.com/pornstars/judith-kostner'}, - { 'name': 'Maria Bellucci', 'url': 'https://ge.xhamster.com/pornstars/maria-bellucci'}, - { 'name': 'Melissa Monet', 'url': 'https://ge.xhamster.com/pornstars/melissa-monet'}, - { 'name': 'Stephanie Cane', 'url': 'https://ge.xhamster.com/pornstars/stephanie-cane'}, - { 'name': 'Will Steiger', 'url': 'https://ge.xhamster.com/pornstars/will-steiger'}, - { 'name': 'Katty West', 'url': 'https://ge.xhamster.com/pornstars/katty-west'}, - { 'name': 'Jean Pallett', 'url': 'https://ge.xhamster.com/pornstars/jean-pallett'}, - { 'name': 'Conny Dachs', 'url': 'https://ge.xhamster.com/pornstars/conny-dachs'}, - { 'name': 'Juicy Leyla', 'url': 'https://ge.xhamster.com/pornstars/juicy-leyla'}, - { 'name': 'Mandy Mystery', 'url': 'https://ge.xhamster.com/pornstars/mandy-mystery'}, - { 'name': 'Jack Vegas', 'url': 'https://ge.xhamster.com/pornstars/jack-vegas'}, - { 'name': 'Jessica Ryan', 'url': 'https://ge.xhamster.com/pornstars/jessica-ryan'}, - { 'name': 'Nathan Bronson', 'url': 'https://ge.xhamster.com/pornstars/nathan-bronson'}, - { 'name': 'Lexi Lore', 'url': 'https://ge.xhamster.com/pornstars/lexi-lore'}, - { 'name': 'Molly Little', 'url': 'https://ge.xhamster.com/pornstars/molly-little'}, - { 'name': 'Dolly Leigh', 'url': 'https://ge.xhamster.com/pornstars/dolly-leigh'}, - { 'name': 'Marcus London', 'url': 'https://ge.xhamster.com/pornstars/marcus-london'}, - { 'name': 'Kendra Sunderland', 'url': 'https://ge.xhamster.com/pornstars/kendra-sunderland'}, - { 'name': 'Manuel Ferrara', 'url': 'https://ge.xhamster.com/pornstars/manuel-ferrara'}, - { 'name': 'Kelly Trump', 'url': 'https://ge.xhamster.com/pornstars/kelly-trump'}, - { 'name': 'Angelica Heaven', 'url': 'https://ge.xhamster.com/pornstars/angelica-heaven'}, - { 'name': 'Luna Lynx', 'url': 'https://ge.xhamster.com/pornstars/luna-lynx'}, - { 'name': 'Princess Lili', 'url': 'https://ge.xhamster.com/pornstars/princess-lili'}, - { 'name': 'Alexa Wild', 'url': 'https://ge.xhamster.com/pornstars/alexa-wild'}, - { 'name': 'Jessyka Swan', 'url': 'https://ge.xhamster.com/pornstars/jessyka-swan'}, - { 'name': 'Nikky Thorne', 'url': 'https://ge.xhamster.com/pornstars/nikky-thorne'}, - { 'name': 'Tristan Summers', 'url': 'https://ge.xhamster.com/pornstars/tristan-summers'}, - { 'name': 'Rhaya Shyne', 'url': 'https://ge.xhamster.com/pornstars/rhaya-shyne'}, - { 'name': 'Desiree West', 'url': 'https://ge.xhamster.com/pornstars/desiree-west'}, - { 'name': 'Joan Devlon', 'url': 'https://ge.xhamster.com/pornstars/joan-devlon'}, - { 'name': 'Jodi Thorpe', 'url': 'https://ge.xhamster.com/pornstars/jodi-thorpe'}, - { 'name': 'Laurien Dominique', 'url': 'https://ge.xhamster.com/pornstars/laurien-dominique'}, - { 'name': 'Paul Scharf', 'url': 'https://ge.xhamster.com/pornstars/paul-scharf'}, - { 'name': 'Ray Wells', 'url': 'https://ge.xhamster.com/pornstars/ray-wells'}, - { 'name': 'Sandy Carey', 'url': 'https://ge.xhamster.com/pornstars/sandy-carey'}, - { 'name': 'Spender Travis', 'url': 'https://ge.xhamster.com/pornstars/spender-travis'}, - { 'name': 'Starlyn Simone', 'url': 'https://ge.xhamster.com/pornstars/starlyn-simone'}, - { 'name': 'Uschi Digard', 'url': 'https://ge.xhamster.com/pornstars/uschi-digard'}, - { 'name': 'Katarina Muti', 'url': 'https://ge.xhamster.com/pornstars/katarina-muti'}, - { 'name': 'Julia Power', 'url': 'https://ge.xhamster.com/pornstars/julia-power'}, - { 'name': 'Salma De Nora', 'url': 'https://ge.xhamster.com/pornstars/salma-de-nora'}, - { 'name': 'Valeria Jones', 'url': 'https://ge.xhamster.com/pornstars/valeria-jones'}, - { 'name': 'Brandy Canyon', 'url': 'https://ge.xhamster.com/pornstars/brandy-canyon'}, - { 'name': 'Marie Berger', 'url': 'https://ge.xhamster.com/pornstars/marie-berger'}, - { 'name': 'Luna Rishi', 'url': 'https://ge.xhamster.com/pornstars/luna-rishi'}, - { 'name': 'Colleen Brennan', 'url': 'https://ge.xhamster.com/pornstars/colleen-brennan'}, - { 'name': 'Roxanne Brewer', 'url': 'https://ge.xhamster.com/pornstars/roxanne-brewer'}, - { 'name': 'Elle Denay', 'url': 'https://ge.xhamster.com/pornstars/elle-denay'}, - { 'name': 'Juan Largo', 'url': 'https://ge.xhamster.com/pornstars/juan-largo'}, - { 'name': 'Codey Steele', 'url': 'https://ge.xhamster.com/pornstars/codey-steele'}, - { 'name': 'Laney Grey', 'url': 'https://ge.xhamster.com/pornstars/laney-grey'}, - { 'name': 'Stirling Cooper', 'url': 'https://ge.xhamster.com/pornstars/stirling-cooper'}, - { 'name': 'Lana Smalls', 'url': 'https://ge.xhamster.com/pornstars/lana-smalls'}, - { 'name': 'Alex Sanders', 'url':'https://ge.xhamster.com/pornstars/alex-sanders'}, - { 'name': 'Felecia Danay', 'url':'https://ge.xhamster.com/pornstars/felecia-danay'}, - { 'name': 'Lita Chase', 'url':'https://ge.xhamster.com/pornstars/lita-chase'}, - { 'name': 'Mark Ashley', 'url':'https://ge.xhamster.com/pornstars/mark-ashley'}, - { 'name': 'Phyllisha Anne', 'url':'https://ge.xhamster.com/pornstars/phyllisha-anne'}, - { 'name': 'Ryan Conner', 'url':'https://ge.xhamster.com/pornstars/ryan-conner'}, - { 'name': 'Tanya Danielle', 'url':'https://ge.xhamster.com/pornstars/tanya-danielle'}, - { 'name': 'Jessica Moore', 'url':'https://ge.xhamster.com/pornstars/jessica-moore'}, - { 'name': 'Mike Angelo', 'url':'https://ge.xhamster.com/pornstars/mike-angelo'}, - { 'name': 'Morgan Moon', 'url':'https://ge.xhamster.com/pornstars/morgan-moon'}, - { 'name': 'Tyler Steel', 'url':'https://ge.xhamster.com/pornstars/tyler-steel'}, - { 'name': 'Abella Danger', 'url':'https://ge.xhamster.com/pornstars/abella-danger'}, - { 'name': 'Alex Jett', 'url':'https://ge.xhamster.com/pornstars/alex-jett'}, - { 'name': 'Alyson Queen', 'url':'https://ge.xhamster.com/pornstars/alyson-queen'}, - { 'name': 'Antynia Rouge', 'url':'https://ge.xhamster.com/pornstars/antynia-rouge'}, - { 'name': 'Bea Dumas', 'url':'https://ge.xhamster.com/pornstars/bea-dumas'}, - { 'name': 'Callie Black', 'url':'https://ge.xhamster.com/pornstars/callie-black'}, - { 'name': 'Caroline Cage', 'url':'https://ge.xhamster.com/pornstars/caroline-cage'}, - { 'name': 'Cindy Dollar', 'url':'https://ge.xhamster.com/pornstars/cindy-dollar'}, - { 'name': 'Crystal Frost', 'url':'https://ge.xhamster.com/pornstars/crystal-frost'}, - { 'name': 'Fanny Steel', 'url':'https://ge.xhamster.com/pornstars/fanny-steel'}, - { 'name': 'Gia Derza', 'url':'https://ge.xhamster.com/pornstars/gia-derza'}, - { 'name': 'Horst Baron', 'url':'https://ge.xhamster.com/pornstars/horst-baron'}, - { 'name': 'Jasmine Rouge', 'url':'https://ge.xhamster.com/pornstars/jasmine-rouge'}, - { 'name': 'Jean-Pierre Armand', 'url':'https://ge.xhamster.com/pornstars/jean-pierre-armand'}, - { 'name': 'Jessa Rhodes', 'url':'https://ge.xhamster.com/pornstars/jessa-rhodes'}, - { 'name': 'Leonie Saint', 'url':'https://ge.xhamster.com/pornstars/leonie-saint'}, - { 'name': 'Linda Ray', 'url':'https://ge.xhamster.com/pornstars/linda-ray'}, - { 'name': 'Luca Ferrero', 'url':'https://ge.xhamster.com/pornstars/luca-ferrero'}, - { 'name': 'Paris Pink', 'url':'https://ge.xhamster.com/pornstars/paris-pink'}, - { 'name': 'Pavlina Stejskalova', 'url':'https://ge.xhamster.com/pornstars/pavlina-stejskalova'}, - { 'name': 'Phoenix Marie', 'url':'https://ge.xhamster.com/pornstars/phoenix-marie'}, - { 'name': 'Ricky Spanish', 'url':'https://ge.xhamster.com/pornstars/ricky-spanish'}, - { 'name': 'Rumika Powers', 'url':'https://ge.xhamster.com/pornstars/rumika-powers'}, - { 'name': 'Sara Blonde', 'url':'https://ge.xhamster.com/pornstars/sara-blonde'}, - { 'name': 'Sean Lawless', 'url':'https://ge.xhamster.com/pornstars/sean-lawless'}, - { 'name': 'Seth Gamble', 'url':'https://ge.xhamster.com/pornstars/seth-gamble'}, - { 'name': 'Siri Dahl', 'url':'https://ge.xhamster.com/pornstars/siri-dahl'}, - { 'name': 'Stephie Staar', 'url':'https://ge.xhamster.com/pornstars/stephie-staar'}, - { 'name': 'Steve Holmes', 'url':'https://ge.xhamster.com/pornstars/steve-holmes'}, - { 'name': 'Suzette Dale', 'url':'https://ge.xhamster.com/pornstars/suzette-dale'}, - { 'name': 'Uncle George', 'url':'https://ge.xhamster.com/pornstars/uncle-george'}, - { 'name': 'Winnie', 'url':'https://ge.xhamster.com/pornstars/winnie'}, - { 'name': 'Zenza Raggi', 'url':'https://ge.xhamster.com/pornstars/zenza-raggi'}, - { 'name': 'Zorah White', 'url':'https://ge.xhamster.com/pornstars/zorah-white'}, - { 'name': 'Marilyn Jess', 'url':'https://ge.xhamster.com/pornstars/marilyn-jess'}, - { 'name': 'Alexis Capri', 'url':'https://ge.xhamster.com/pornstars/alexis-capri'}, - ] - - - for new_actor in new_actor_list: - if new_actor['url'] in actors: - log.warning(f"Actor {new_actor['url']} already persisted") - continue - actor_response = requests.post(f"http://127.0.0.1:8800/api/media/actors", json=new_actor) - log.warning(f"add status: {actor_response.status_code}") - if actor_response.status_code == 201: - log.warning(f"add Actor {new_actor['url']} to existing actor list") - actors[new_actor['url']] = new_actor - actor_data = actor_response.json() - log.warning(f"Actor {actor_data} persisted") - log.warning('kontor.add_actors finished') diff --git a/kontor-scripts/add_link.py b/kontor-scripts/add_link.py index 34c654a..d5c2747 100644 --- a/kontor-scripts/add_link.py +++ b/kontor-scripts/add_link.py @@ -1,61 +1,77 @@ """ read file with URLs and store in DB """ + +import json import logging.config +from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser +from pathlib import Path + import requests import yaml -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter -from pathlib import Path from platformdirs import PlatformDirs -from proton import Message, Event +from proton import Event, Message from proton.handlers import MessagingHandler from proton.reactor import Container parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('-u', '--url', help='link') -parser.add_argument('--video', help='store Url as VideoFile', action="store_true") +parser.add_argument("-u", "--url", help="link") +parser.add_argument("--video", help="store Url as VideoFile", action="store_true") parser.add_argument("--api", help="use Kontor API", action="store_true") -parser.add_argument('--config', '-c', default='kontor-docker') -parser.add_argument('--verbose', '-v', action='count', default=0) +parser.add_argument("--config", "-c", default="kontor-docker") +parser.add_argument("--verbose", "-v", action="count", default=0) +parser.add_argument("--server", "-s", default="127.0.0.1") args = parser.parse_args() + def get_logger(level: int, config: str): + """ + create Logger with configuration from config file + """ dirs = PlatformDirs(config) - logging_config = Path(dirs.user_config_dir, 'logging-config.yaml') - with open(logging_config, 'rt') as f: - configDict = yaml.safe_load(f.read()) - logging.config.dictConfig(configDict) - logger = logging.getLogger('development') + logging_config = Path(dirs.user_config_dir, "logging-config.yaml") + with open(logging_config, "rt", encoding="UTF-8") as f: + config_dict = yaml.safe_load(f.read()) + logging.config.dictConfig(config_dict) + log = logging.getLogger("development") if level is not None: match level: case 0: - logger.setLevel(logging.INFO) + log.setLevel(logging.INFO) case 1: - logger.setLevel(logging.DEBUG) + log.setLevel(logging.DEBUG) case _: - logger.setLevel(logging.CRITICAL) - return logger + log.setLevel(logging.CRITICAL) + return log + class AddLinkMessage(MessagingHandler): - def __init__(self, server, url, log): + """ + Create message for queue add_link_file + """ + + def __init__(self, server, message, log): super(AddLinkMessage, self).__init__() log.info("create AddLinkMessage") self.server = server - self.address = "add_link_file" - self.url = url + self.address = "media.link.add" + self.message = message self.log = log - def on_start(self, event: Event): + def on_start(self, event): self.log.info("Connection...") conn = event.container.connect(self.server, user="artemis", password="artemis") event.container.create_sender(conn, self.address) - def on_connection_error(self, event: Event) -> None: + def on_connection_error(self, event) -> None: self.log.info(f"error: {event}") - def on_sendable(self, event: Event): + def on_sendable(self, event): self.log.info("send message") - event.sender.send(Message(body=self.url, address=self.address, content_type="text/json")) + json_content = json.dumps(self.message) + event.sender.send( + Message(body=json_content, address=self.address, content_type="text/json") + ) event.connection.close() event.sender.close() @@ -63,19 +79,20 @@ class AddLinkMessage(MessagingHandler): self.log.info(f"accepted: {event}") -if __name__ == '__main__': +if __name__ == "__main__": logger = get_logger(args.verbose, args.config) - logger.info('kontor.add_link started') + logger.info("kontor.add_link started") link: str = args.url data = {"url": link} + server_url: str = f"amqp://{args.server}:5672" if args.api: if args.video: request: str = "http://127.0.0.1:8800/api/video/files" else: request: str = "http://127.0.0.1:8800/api/media/files" - response = requests.post(request, json=data) - logger.info(f"Status: {response.status_code}") + response = requests.post(request, json=data, timeout=5) + logger.info("Status: %s", response.status_code) data = response.json() else: - Container(AddLinkMessage("amqp://127.0.0.1:5672", data, logger)).run() - logger.info('kontor.add_link finished') + Container(AddLinkMessage(server=server_url, message=data, log=logger)).run() + logger.info("kontor.add_link finished") diff --git a/kontor-scripts/add_link_stomp.py b/kontor-scripts/add_link_stomp.py new file mode 100644 index 0000000..f74b69d --- /dev/null +++ b/kontor-scripts/add_link_stomp.py @@ -0,0 +1,38 @@ +""" +read file with URLs and store in DB +""" + +from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser + +import msgspec +import stomp + +from log import get_logger + +parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) +parser.add_argument("-u", "--url", help="link") +parser.add_argument("--config", "-c", default="kontor-docker") +parser.add_argument("--verbose", "-v", action="count", default=0) +parser.add_argument("--server", "-s", default="127.0.0.1") +parser.add_argument("--port", "-p", default="61616") +parser.add_argument("--destination", "-d", default="media.link") +args = parser.parse_args() + + +class Link(msgspec.Struct): + url: str + + +if __name__ == "__main__": + logger = get_logger(args.verbose, args.config) + logger.info("kontor.add_link_stomp started") + + server_url = [(args.server, args.port)] + conn = stomp.Connection(host_and_ports=server_url) + conn.connect(username="artemis", passcode="artemis", wait=True) + + link: Link = Link(url=args.url) + json_bytes = msgspec.json.encode(link) + conn.send(body=json_bytes.decode(), destination=args.destination) + + logger.info("kontor.add_link finished") diff --git a/kontor-scripts/add_links.py b/kontor-scripts/add_links.py index 43a906e..77d416c 100644 --- a/kontor-scripts/add_links.py +++ b/kontor-scripts/add_links.py @@ -1,128 +1,126 @@ """ read file with links and store it in DB """ + from datetime import datetime -import logging.config +import logging import re -from typing import Dict, List +from typing import Dict, List, Optional import uuid from bs4 import BeautifulSoup import requests -import yaml from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter from pathlib import Path -from platformdirs import PlatformDirs -from pathlib import Path -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker, Session -from db.models.base import Base -import os - -from db.models.media import MediaActor, MediaActorFile, MediaFile +from api import Server, get_api_config +from log import get_logger +from kontor_model.db.models.media import MediaActor, MediaActorFile, MediaFile parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('--file', '-f', help='file with links', default='~/.sync/media/list.txt') -parser.add_argument('--video', help='store Url as VideoFile', action="store_true") -parser.add_argument('--config', '-c', default='kontor-docker') -parser.add_argument('--verbose', '-v', action='count', default=0) -parser.add_argument('--limit', '-l', type=int, help='maximum number of links to check') -parser.add_argument('--dry-run', '-m', help='excute script without storing', action="store_true") +parser.add_argument( + "--file", "-f", help="file with links", default="~/.sync/media/list.txt" +) +parser.add_argument("--video", help="store Url as VideoFile", action="store_true") +parser.add_argument("--config", "-c", default="kontor-api") +parser.add_argument("--server", "-s") +parser.add_argument("--verbose", "-v", action="count", default=0) +parser.add_argument("--limit", "-l", type=int, help="maximum number of links to check") +parser.add_argument( + "--dry-run", "-m", help="excute script without storing", action="store_true" +) args = parser.parse_args() -DB_USER: str = os.getenv("DB_USER", "kontor") -DB_PASSWORD: str = os.getenv("DB_PASSWORD", "kontor") -DB_SERVER: str = os.getenv("DB_SERVER", "127.0.0.1") -DB_PORT: int = int(os.getenv("DB_PORT", 5432)) -DB_DBNAME: str = os.getenv("DB_DBNAME", "kontor") -DATABASE_URL: str = f"postgresql://{DB_USER}:{DB_PASSWORD}@{DB_SERVER}:{DB_PORT}/{DB_DBNAME}" - -def get_logger(level, config: str): - dirs = PlatformDirs(config) - logging_config = Path(dirs.user_config_dir, 'logging-config.yaml') - with open(logging_config, 'rt') as f: - log_config = yaml.safe_load(f.read()) - logging.config.dictConfig(log_config) - logger = logging.getLogger('development') - if level is not None: - match level: - case 0: - logger.setLevel(logging.CRITICAL) - case 1: - logger.setLevel(logging.INFO) - case 2: - logger.setLevel(logging.DEBUG) - case _: - logger.setLevel(logging.INFO) - return logger - -def get_session() -> Session: - engine = create_engine(DATABASE_URL) - Base.metadata.create_all(bind=engine, checkfirst=True) - SessionLocal = sessionmaker(bind=engine) - return SessionLocal() def load_data(filename: str, log) -> List[str]: - links: List[str] = [] + """ + Read list of links from file. + """ + link_list: List[str] = [] log.debug("load_data") import_file = Path(filename) if not import_file.exists(): log.info(f"File {filename} does not exist. Do nothing.") raise FileNotFoundError() log.info("read txt file") - with open(filename, 'r') as txt_file: + with open(filename, "r", encoding="utf-8") as txt_file: while line := txt_file.readline(): # log.info(line.rstrip()) - links.append(line.rstrip()) - return links + link_list.append(line.rstrip()) + return link_list + def get_actors_mapping(actor_list: List[MediaActor]) -> Dict[str, MediaActor]: + """ + Create dictionary with actor links as key and MediaActor objects as values. + """ mapping: Dict[str, MediaActor] = {} for actor in actor_list: - mapping[str(actor.url)] = actor + if isinstance(actor, dict): + url: str = actor["url"] + else: + url: str = str(actor.url) + mapping[url] = actor return mapping + def get_actornames_mapping(actor_list: List[MediaActor]) -> Dict[str, MediaActor]: + """ + Create dictionary with actor names as key and MediaActor objects as values. + """ mapping: Dict[str, MediaActor] = {} for actor in actor_list: - mapping[str(actor.name)] = actor + if isinstance(actor, dict): + name: str = actor["name"] + else: + name: str = str(actor.name) + mapping[name] = actor return mapping -def get_meta_info(media_file: MediaFile, log) -> List[str]: + +def get_meta_info(media_file_obj: MediaFile, log) -> List[str]: + """ + Get meta info for MediaFile from link. + """ actor_links: List[str] = [] try: - r = requests.get(media_file.url) + r = requests.get(media_file_obj.url, timeout=5) soup = BeautifulSoup(r.content, "html.parser") - error404 = soup.css.select_one('.error404-title') + error404 = soup.css.select_one(".error404-title") if error404 and error404.get_text() == "Video nicht gefunden": log.warning(f"{error404.get_text()}") - media_file.url = None - media_file.review = False + media_file_obj.url = None + media_file_obj.review = False return actor_links - title_tag = soup.find('title') + title_tag = soup.find("title") if title_tag: - media_file.title = title_tag.get_text() - media_file.review = False - anchors = soup.find_all('a', attrs={'href': re.compile("^https://.*pornstars/.*")}) + media_file_obj.title = title_tag.get_text() + media_file_obj.review = False + anchors = soup.find_all( + "a", attrs={"href": re.compile("^https://.*pornstars/.*")} + ) for anchor in anchors: - link_url = str(anchor.get("href")) # type: ignore - if link_url.endswith('all/countries'): + link_url = str(anchor.get("href")) # type: ignore + if link_url.endswith("all/countries"): continue if link_url in actor_links: continue actor_links.append(link_url) except Exception as error: log.info(f"something went wrong: {error}") - media_file.title = None - media_file.review = True - log.info(f"update MediaFile with MetaInfos to {repr(media_file)}") + media_file_obj.title = None + media_file_obj.review = True + log.info(f"update MediaFile with MetaInfos to {repr(media_file_obj)}") log.info(f"links({len(actor_links)}): {actor_links}") return actor_links -def get_actor_name(actor_url: str, log: logging.Logger) -> str | None: + +def get_actor_name(actor_link: str, log: logging.Logger) -> str | None: + """ + Get actor name from link url. + """ try: - r = requests.get(actor_url) + r = requests.get(actor_link, timeout=5) soup = BeautifulSoup(r.content, "html.parser") - titles = soup.find_all('h1') + titles = soup.find_all("h1") for title in titles: log.info(f"title: {title.get_text()}") return title.get_text() @@ -131,86 +129,107 @@ def get_actor_name(actor_url: str, log: logging.Logger) -> str | None: return None -if __name__ == '__main__': - logger = get_logger(args.verbose, "kontor") - logger.info('kontor.add_links started') +if __name__ == "__main__": + logger = get_logger(args.verbose, args.config) + logger.info("kontor.add_links started") if args.limit: - logger.warning(f"check the first {args.limit} links") - session = get_session() + logger.warning("check the first %s links", args.limit) + APICONFIG = get_api_config(logger, args.config) + server_list: List[Server] = [] + server: Optional[Server] = None + if args.server: + server = APICONFIG.get_server(args.server) + if not server: + server = APICONFIG.server[0] + else: + server = APICONFIG.server[0] links_index = 1 - with session as db: - links = load_data(args.file, logger) - for link in links: - logger.debug(f"process {link}") - media_files = db.query(MediaFile).filter(MediaFile.url == link).all() - media_actors = db.query(MediaActor).all() - actor_mapping = get_actors_mapping(media_actors) - actorname_mapping = get_actornames_mapping(media_actors) - if len(media_files) == 0: - logger.info(f"MediaFile for link {link} not found") - media_file = MediaFile() - media_file.id = str(uuid.uuid4()) - media_file.created_date = datetime.now() - media_file.last_modified_date = datetime.now() - media_file.version = 0 - media_file.url = link - media_file.review = True - media_file.should_download = True - media_file.path = None - media_file.cloud_link = None - media_file.file_name = None - actor_urls: List[str] = get_meta_info(media_file, logger) - if not args.dry_run: - db.add(media_file) - db.commit() - db.refresh(media_file) - for actor_url in actor_urls: - if actor_url in actor_mapping: - media_actor: MediaActor = actor_mapping[actor_url] - # logger.info(f"create mapping for {repr(media_actor)}") - media_actor_file = MediaActorFile() - media_actor_file.id = str(uuid.uuid4()) - media_actor_file.created_date = datetime.now() - media_actor_file.last_modified_date = datetime.now() - media_actor_file.version = 0 - media_actor_file.media_file_id = media_file.id - media_actor_file.media_actor_id = media_actor.id - logger.info(f"create mapping with {media_actor_file}") - if not args.dry_run: - db.add(media_actor_file) - db.commit() - else: - media_actor: MediaActor = None # type: ignore - actor_name = get_actor_name(actor_url, logger) - if actor_name in actorname_mapping: - media_actor = actorname_mapping[actor_name] - else: - media_actor = MediaActor() - media_actor.id = str(uuid.uuid4()) - media_actor.created_date = datetime.now() - media_actor.last_modified_date = datetime.now() - media_actor.version = 0 - media_actor.name = get_actor_name(actor_url, logger) - media_actor.url = actor_url - logger.info(f"update MediaActor with {repr(media_actor)}") - if not args.dry_run: - db.add(media_actor) - db.commit() - media_actor_file = MediaActorFile() - media_actor_file.id = str(uuid.uuid4()) - media_actor_file.created_date = datetime.now() - media_actor_file.last_modified_date = datetime.now() - media_actor_file.version = 0 - media_actor_file.media_file_id = media_file.id - media_actor_file.media_actor_id = media_actor.id - logger.info(f"create mapping with {media_actor_file}") - if not args.dry_run: - db.add(media_actor_file) - db.commit() + links = load_data(args.file, logger) + all_media_files = server.request(logger, table="media_file") + media_actors: List[MediaActor] = server.request(log=logger, table="media_actor") + actor_mapping = get_actors_mapping(media_actors) + actorname_mapping = get_actornames_mapping(media_actors) + for link in links: + logger.info("process %s", link) + media_files = [ + media_file for media_file in all_media_files if media_file["url"] == link + ] + if len(media_files) == 0: + logger.info("MediaFile for link %s not found", link) + media_file = MediaFile() + media_file.id = str(uuid.uuid4()) + media_file.created_date = datetime.now() + media_file.last_modified_date = datetime.now() + media_file.version = 0 + media_file.url = link + media_file.review = True + media_file.should_download = True + media_file.path = None + media_file.cloud_link = None + media_file.file_name = None + actor_urls: List[str] = get_meta_info(media_file, logger) + if not args.dry_run: + logger.info("add MediaFile %s", media_file) + server.create(logger, "media_file", media_file.export_dict()) else: - for media_file in media_files: - logger.debug(f"MediaFile with {media_file.id} is found") - links_index += 1 - if args.limit and args.limit < links_index: - break - logger.info('kontor.add_link finished') + logger.info("not adding MediaFile %s", media_file) + for actor_url in actor_urls: + if actor_url in actor_mapping: + media_actor: Optional[MediaActor] = actor_mapping[actor_url] + # logger.info(f"create mapping for {repr(media_actor)}") + media_actor_file = MediaActorFile() + media_actor_file.id = str(uuid.uuid4()) + media_actor_file.created_date = datetime.now() + media_actor_file.last_modified_date = datetime.now() + media_actor_file.version = 0 + media_actor_file.media_file_id = media_file.id + media_actor_file.media_actor_id = media_actor.id + logger.info("create mapping with %s", media_actor_file) + if not args.dry_run: + logger.info("add MediaFile Actor mapping %s", media_actor_file) + server.create( + logger, "media_actor_file", media_actor_file.export_dict() + ) + else: + logger.info( + "not adding MediaFile Actor mapping %s", media_actor_file + ) + else: + actor_name = get_actor_name(actor_url, logger) + if actor_name in actorname_mapping: + media_actor = actorname_mapping[actor_name] + else: + media_actor = MediaActor() + media_actor.id = str(uuid.uuid4()) + media_actor.created_date = datetime.now() + media_actor.last_modified_date = datetime.now() + media_actor.version = 0 + media_actor.name = get_actor_name(actor_url, logger) + media_actor.url = actor_url + logger.info("update MediaActor with %s", repr(media_actor)) + if not args.dry_run: + logger.info("Update MediaActor %s", media_actor) + server.create( + logger, "media_actor", media_actor.export_dict() + ) + else: + logger.info("not updating MediaActor %s", media_actor) + media_actor_file = MediaActorFile() + media_actor_file.id = str(uuid.uuid4()) + media_actor_file.created_date = datetime.now() + media_actor_file.last_modified_date = datetime.now() + media_actor_file.version = 0 + media_actor_file.media_file_id = media_file.id + media_actor_file.media_actor_id = media_actor.id + logger.info("create mapping with %s", media_actor_file) + if not args.dry_run: + logger.info("Add MediaFile Actor mapping") + else: + logger.info("not adding MediaFile Actor mapping") + else: + for media_file in media_files: + logger.info("MediaFile with %s is found", media_file["id"]) + links_index += 1 + if args.limit and args.limit < links_index: + break + logger.info("kontor.add_link finished") diff --git a/kontor-scripts/api.py b/kontor-scripts/api.py new file mode 100644 index 0000000..7234be6 --- /dev/null +++ b/kontor-scripts/api.py @@ -0,0 +1,244 @@ +from dataclasses import dataclass +from enum import Enum, auto +from logging import Logger +from pathlib import Path +from typing import Dict, List, Optional +from uuid import UUID + +from platformdirs import PlatformDirs +import requests +import yaml + + +MAPPING: Dict[str, str] = { + "sport": "api/tysc/sports", + "player": "api/tysc/players", + "team": "api/tysc/teams", + "field_position": "api/tysc/positions", + "rooster": "api/tysc/roosters", + "vendor": "api/tysc/vendors", + "card_set": "api/tysc/cardsets", + "card": "api/tysc/cards", + "artist": "api/comics/artists", + "publisher": "api/comics/publishers", + "worktype": "api/comics/worktypes", + "comic": "api/comics/comics", + "volume": "api/comics/volumes", + "story_arc": "api/comics/storyarcs", + "issue": "api/comics/issues", + "comic_work": "api/comics/comicworks", + "issue_work": "api/comics/issueworks", + "article": "api/bookshelf/articles", + "bookshelf_publisher": "api/bookshelf/publishers", + "book": "api/bookshelf/books", + "author": "api/bookshelf/authors", + "article_author": "api/bookshelf/articleauthors", + "book_author": "api/bookshelf/bookauthors", + "media_article": "api/media/articles", + "media_video": "api/media/videos", + "media_lofi": "api/media/lofi", + "media_file": "api/media/files", + "media_actor": "api/media/actors", + "media_actor_file": "api/media/actorfiles", + "profile": "api/user/profiles", + "permission": "api/user/permissions", + "assignment": "api/user/assignments", + "token": "api/user/tokens", + "mail_account": "api/admin/mailaccounts", +} + + +class OptionType(Enum): + """ + OptionType defines the type of param for REST API call. + The type PARAM indicates a query parameter. + The type ID indicates the option is an idntifier as part of the path. + """ + + PARAM = auto() + ID = auto() + URL = auto() + + +class Option: + """ + Option is an utility class to simplify options for the REST API call. + The type defines how to handle the value. + """ + + def __init__(self, option_type: OptionType, value: str) -> None: + self.type: Optional[OptionType] = option_type + self.value: Optional[str] = value + + def __str__(self) -> str: + if self.type is OptionType.PARAM: + return f"?{self.value}" + else: + return f"/{self.value}" + + +class CredentialsValidationException(Exception): + """ + Raised when login failed or token is outdated. + """ + + +class EndPointNotAvailableException(Exception): + """ + Raised when calling an not existing endpoint. + """ + + +@dataclass +class Login: + """ + Dataclass to store login information. + """ + + email: str + password: str + + +@dataclass +class Server: + """ + Dataclass to represent a Kontor-API instance. + """ + + name: str + url: str + token: str + token_type: str + email: str + password: str + timeout: int + + def login(self, log: Logger, refresh_token: bool = False): + """ + get token from server by calling login endpoint. + """ + log.debug("call login and retrieve token") + if not self.token: + self.__get_token__(log=log) + if refresh_token: + self.__get_token__(log=log) + + def __get_token__(self, log: Logger): + log.info("Call login first") + login_url = f"{self.url}/login" + login_data = {} + login_data["email"] = self.email + login_data["password"] = self.password + response = requests.post(login_url, json=login_data, timeout=self.timeout) + status = response.status_code + log.info(f"Status: {status}") + if status != 200: + log.fatal("authentication failed") + return + data = response.json() + log.debug(f"got data: {data}") + token = data["access_token"] + token_type = data["token_type"] + self.token = str(token) + self.token_type = str(token_type) + + def request(self, log: Logger, table: str, param: Optional[Option] = None): + """ + Requests data from Kontor-API instance by given table and optional parameters. + """ + if not param: + url: str = f"{self.url}/{MAPPING[table]}" + else: + url: str = f"{self.url}/{MAPPING[table]}{str(param)}" + headers: Dict[str, str] = {"Authorization": f"Bearer {self.token}"} + response = requests.get(url, headers=headers, timeout=self.timeout) + log.debug(f"Status: {response.status_code}") + if response.status_code == 401: + self.login(log, refresh_token=True) + headers: Dict[str, str] = {"Authorization": f"Bearer {self.token}"} + response = requests.get(url, headers=headers, timeout=self.timeout) + if response.status_code == 404: + raise EndPointNotAvailableException + data = response.json() + return data + + def update(self, log: Logger, table: str, item_id: UUID, file_info: dict): + """ + Updates data to the Kontor-API instance. + """ + url: str = f"{self.url}/{MAPPING[table]}/{item_id}" + headers: Dict[str, str] = {"Authorization": f"Bearer {self.token}"} + update = requests.put( + url, headers=headers, json=file_info, timeout=self.timeout + ) + log.info(f"Status: {update.status_code}") + if update.status_code == 404: + raise EndPointNotAvailableException + data = update.json() + return data + + def create(self, log: Logger, table: str, new_item: dict): + """ + Create item in Kontor-API instance. + """ + url: str = f"{self.url}/{MAPPING[table]}" + headers: Dict[str, str] = {"Authorization": f"Bearer {self.token}"} + create = requests.post( + url, headers=headers, json=new_item, timeout=self.timeout + ) + log.info(f"Status: {create.status_code}") + if create.status_code == 404: + raise EndPointNotAvailableException + if create.status_code == 409: + log.fatal("Create Exception %s", create.json()) + data = create.json() + return data + + def delete(self, log: Logger, table: str, item_id: str): + """ + Delete item in Kontor-API instance. + """ + url: str = f"{self.url}/{MAPPING[table]}/{item_id}" + headers: Dict[str, str] = {"Authorization": f"Bearer {self.token}"} + delete = requests.delete(url, headers=headers, timeout=self.timeout) + log.info(f"Status: {delete.status_code}") + + +@dataclass +class ApiConfig: + """ + Dataclass to define required contents of configuration file. + """ + + server: List[Server] + + def get_server(self, server_name: str) -> Optional[Server]: + """ + Return server instance by given name or None. + """ + found_server = None + for server in self.server: + if server.name == server_name: + found_server = server + return found_server + + +def get_api_config(log: Logger, config: str) -> ApiConfig: + """ + Load configuration from file. + """ + dirs = PlatformDirs(config) + api_config = Path(dirs.user_config_dir, "api.yaml") + with open(api_config, "rt", encoding="utf-8") as f: + api_data = yaml.safe_load(f.read()) + servers = [Server(**server) for server in api_data["server"]] + api_config_data = ApiConfig(server=servers) + log.debug(api_config_data) + if not api_data: + log.fatal("API configuration is missing") + return api_config_data + for server in api_config_data.server: + server.login(log) + with open(api_config, "w", encoding="utf-8") as f: + yaml.dump(api_data, f) + return api_config_data diff --git a/kontor-scripts/check_kontor.py b/kontor-scripts/check_kontor.py index e75a543..9cf4d07 100644 --- a/kontor-scripts/check_kontor.py +++ b/kontor-scripts/check_kontor.py @@ -1,183 +1,155 @@ """ Checks the database kontor """ -from enum import Enum, auto -import json -import mariadb -import requests -from pathlib import Path -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter -from config import get_logger, get_database_cursors +from logging import Logger +from pathlib import Path +import sys +from typing import Any, Dict, List, Optional +from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter +from urllib.parse import urlparse +from simple_term_menu import TerminalMenu + +from api import Server, get_api_config +from log import get_logger parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('--verbose', '-v', action='count', default=0) -parser.add_argument('--config', '-c', default='kontor') -parser.add_argument('--file', '-f') -parser.add_argument('--dir', '-d') -parser.add_argument('--dry-run', '-m', action='store_true') -parser.add_argument('--reset-cloud-link', '-r', action='store_true') +parser.add_argument("--verbose", "-v", action="count", default=0) +parser.add_argument("--config", "-c", default="kontor-api") +parser.add_argument("--dir", "-d", default="/data/media") +parser.add_argument("--add-dir", "-a", action="append") +parser.add_argument("--dry-run", "-m", action="store_true") +parser.add_argument("--server", "-s") args = parser.parse_args() -class StatusType(Enum): - UNKNOWN = auto() - FILE_NAME = auto() - FILE_ID = auto() - DUPLICATE = auto() - CLOUD_LINK = auto() - CLOUD_LINK_ID = auto() -class FileStatus: - id: str | None = None - status_type: StatusType = StatusType.UNKNOWN - - def get_response(self, response: dict): - self.status_type = StatusType.FILE_NAME - self.id = response['id'] +def create_item_id_mapping(log: Logger, data_list: List[dict]) -> Dict[str, dict]: + """ + create dictionary with id as key and dictionary as value. + """ + item_id_mapping: Dict[str, dict] = {} + for data_item in data_list: + log.debug(data_item) + item_id_mapping[data_item["id"]] = data_item + return item_id_mapping -def get_status_of_file(found_file: Path, cursor, log) -> FileStatus: - status = FileStatus() - try: - cursor.execute(f'SELECT id, cloud_link FROM media_file WHERE file_name="{found_file.name}"') - rows = cursor.fetchall() - if len(rows) == 1: - status.status_type = StatusType.FILE_NAME - status.id = rows[0][0] - except mariadb.Error as error: - log.debug(f'select failed with {error}') - try: - cursor.execute(f'SELECT id FROM media_file WHERE id="{found_file.stem}"') - rows = cursor.fetchall() - if len(rows) == 1: - status.status_type = StatusType.FILE_ID - status.id = rows[0][0] - if len(rows) > 1: - status.status_type = StatusType.DUPLICATE - for row in rows: - log.info(f"found {row[0]} with {found_file}") - except mariadb.Error as error: - log.debug(f'select failed with {error}') - try: - cursor.execute(f'SELECT id FROM media_file WHERE cloud_link LIKE "%{found_file.stem}%"') - rows = cursor.fetchall() - if len(rows) == 1: - status.id = rows[0][0] - if rows[0][0] == found_file.stem: - status.status_type = StatusType.CLOUD_LINK_ID - else: - status.status_type = StatusType.CLOUD_LINK - except mariadb.Error as error: - log.debug(f'select failed with {error}') - response = requests.get(f"http://127.0.0.1:8800/media/files/{found_file.stem}") - log.debug(f"Status: {response.status_code}") - if response.status_code == 200: - status.status_type = StatusType.FILE_ID - status.id = response.json()['id'] - return status +def remove_file(log: Logger, item_data: Dict[str, Any], media_dirs: List[str]): + """ + Delete file from path in dictionary. + """ + log.debug(item_data) + cloud_link = item_data["cloud_link"] + for file_dir in media_dirs: + log.info("look in %s", file_dir) + file_name = Path(cloud_link).name + if len(file_name) < 5: + log.info("file_name too short, skip deleting") + break + media_file = Path(file_dir, file_name) + if media_file.exists(): + log.info("File to remove %s", media_file.absolute()) + media_file.unlink(missing_ok=True) + break + else: + log.info("File not found %s", media_file.absolute()) -def rename_files_to_id(media_dir, dry_run, conn, log): - media_path = Path(media_dir) - cursor = conn.cursor() - for file in media_path.iterdir(): - log.debug('found file: {}'.format(file.name)) - status: FileStatus = get_status_of_file(file, cursor, log) - file_id = status.id - if not file_id: - log.info(f"ID of file {file.name} is unknown") + +def check_duplicate_links(log: Logger, server: Optional[Server], media_dirs: List[str]): + """ + Check if there are MediaFile URLs which only differ in hostname. + """ + if server is None: + log.info("no server selected") + return + data = server.request(log=log, table="media_file") + mapping = create_item_id_mapping(log=log, data_list=data) + visited_link_path: Dict[str, str] = {} + duplicate_link_paths: Dict[str, List[str]] = {} + for item in data: + link = item["url"] + if len(link) == 0: continue - new_file_path = file.with_name(f"{file_id}{file.suffix}") - match status.status_type: - case StatusType.FILE_NAME: - log.info(f'status of {file.name} is file_name') - rename_file(file, new_file_path, dry_run, log) - update_cloud_link(file_id, new_file_path, conn, dry_run, log) - case StatusType.FILE_ID: - log.info(f'status of {file.name} is file_id') - update_cloud_link(file_id, new_file_path, conn, dry_run, log) - case StatusType.CLOUD_LINK: - log.info(f'status of {file.name} is cloud_link') - rename_file(file, new_file_path, dry_run, log) - update_cloud_link(file_id, new_file_path, conn, dry_run, log) - case StatusType.CLOUD_LINK_ID: - log.debug(f'status of {file.name} is cloud_link_id') - update_cloud_link(file_id, new_file_path, conn, dry_run, log) - case StatusType.DUPLICATE: - log.info(f'status of {file.name} is duplicate') - case StatusType.UNKNOWN: - log.info(f'status of {file.name} is unknown') + file_id = item["id"] + parsed_url = urlparse(link) + link_path = parsed_url.path + if link_path in visited_link_path: + log.debug("duplicate url path found: %s", link_path) + if link_path in duplicate_link_paths: + duplicate_link_paths[link_path].append(file_id) + else: + duplicate_link_paths[link_path] = [] + duplicate_link_paths[link_path].append(visited_link_path[link_path]) + duplicate_link_paths[link_path].append(file_id) + else: + visited_link_path[link_path] = file_id + log.info("found %s duplicate links", len(duplicate_link_paths.keys())) + for _, value in duplicate_link_paths.items(): + choices = [mapping[value[0]]["url"], mapping[value[1]]["url"], "Abbruch"] + menu = TerminalMenu( + choices, title="Choose an link to delete:", multi_select=False + ) + menu_choice = menu.show() + if isinstance(menu_choice, int): + if menu_choice == 2: + break + index: int = int(menu_choice) + server.delete(log=log, table="media_file", item_id=value[index]) + remove_file(log, mapping[value[index]], media_dirs) + else: + print("selection canceled") -def rename_file(current_file, new_file_path, dry_run, log): - if dry_run: - log.info('rename file {} to {}'.format(current_file.name, new_file_path.name)) + +def check_media_dirs(log: Logger, server: Optional[Server], media_dirs: List[str]): + """ + Check if contents of directories match MediaFiles. + """ + if server is None: + log.info("no server selected") + return + local_files = collect_files(media_dirs) + data = server.request(log=log, table="media_file") + for item in data: + file_name = Path(item["cloud_link"]).name + if file_name in local_files: + log.debug("File %s found", file_name) + local_files.remove(file_name) + + +def collect_files(media_dirs: List[str]) -> List[str]: + """ + Collect file names from given directories. + """ + collected_files: List[str] = [] + for media_dir in media_dirs: + file_dir = Path(media_dir) + if file_dir.is_dir(): + for entry in file_dir.iterdir(): + if entry.is_file(): + collected_files.append(entry.name) + return collected_files + + +if __name__ == "__main__": + logger = get_logger(args.verbose, args.config) + logger.info("kontor.check_kontor started") + APICONFIG = get_api_config(logger, args.config) + first_server: Optional[Server] = APICONFIG.get_server(args.server) + if not first_server: + sys.exit(2) + dirs: List[str] = args.add_dir + if dirs is None: + dirs = [args.dir] else: - current_file.rename(Path(new_file_path)) - -def update_cloud_link(file_id, file_path, conn, dry_run, log): - cursor = conn.cursor() - log.debug(f'update entry {file_id} with {file_path.absolute()}') - if dry_run: - log.debug(f'UPDATE media_file: cloud_link={file_path.absolute()}') - else: - cursor.execute('UPDATE media_file SET cloud_link="{}" WHERE id="{}"'.format(file_path.absolute(), file_id)) - conn.commit() - -def reset_cloud_link(conn, dry_run, log): - cursor = conn.cursor() - if dry_run: - log.info('UPDATE media_file SET cloud_link=""') - else: - cursor.execute('UPDATE media_file SET cloud_link="" WHERE id is NOT NULL') - conn.commit() - -def check_file_with_db(data_file: Path, m_conn, log): - log.info(f"read json file: {data_file}") - cursor = m_conn.cursor() - with open(data_file, 'r') as json_file: - json_load = json.load(json_file) - for table in json_load: - log.info(f"{table}: {len(json_load[table])}") - items = json_load[table] - for item in items: - item_id = item['id'] - select_statement = f"SELECT * FROM {table} WHERE id='{item_id}'" - cursor.execute(select_statement) - rows = cursor.fetchall() - count = len(rows) - log.info(f"{count} entries found for {item_id}") - if count == 0: - log.info(f"entry for {item_id} not found") - if count == 1: - log.info(f"check entry {item_id}") - #log.info(f"entry {rows[0]}") - columns = [] - values = [] - for (key, value) in item.items(): - columns.append(key) - values.append(value) - for index, _ in enumerate(columns): - log.info(f"compare {values[index]} with {rows[0][index]}") - - - -if __name__ == '__main__': - log = get_logger(args.verbose, args.config) - log.info("kontor.check_kontor started") - _, m_conn = get_database_cursors(log, args.config) - if args.dir: - log.info("kontor.check_kontor.rename_files_to_id") - rename_files_to_id(args.dir, args.dry_run, m_conn, log) - if args.file: - data_file = Path(args.file) - if data_file.exists(): - log.info("kontor.check_kontor.check_file_with_db") - check_file_with_db(data_file, m_conn, log) - #logger.info("kontor.check_kontor.update_cloud_link_with_found_files") - #update_cloud_link_with_found_files(data_dir, mariadb_conn, args.dry_run) - #logger.info("kontor.check_kontor.get_ids_from_column_cloud_link") - #get_ids_from_column_cloud_link(link_list, mariadb_cursor) - #logger.info('found {} ids in column cloud_link'.format(len(link_list))) - #logger.info("kontor.check_kontor.checking_ids_from_cloud_link") - #checking_ids_from_cloud_link(link_list, mariadb_cursor) - log.info("kontor.check_kontor finished") - + dirs.insert(0, args.dir) + logger.info(dirs) + logger.info("kontor.check_kontor.check_duplicate_links") + check_duplicate_links(logger, first_server, dirs) + logger.info("kontor.check_kontor.check_media_dirs") + check_media_dirs(logger, first_server, dirs) + # logger.info("kontor.check_kontor.get_ids_from_column_cloud_link") + # get_ids_from_column_cloud_link(link_list, mariadb_cursor) + # logger.info('found {} ids in column cloud_link'.format(len(link_list))) + # logger.info("kontor.check_kontor.checking_ids_from_cloud_link") + # checking_ids_from_cloud_link(link_list, mariadb_cursor) + logger.info("kontor.check_kontor finished") diff --git a/kontor-scripts/copy_to_mariadb.py b/kontor-scripts/copy_to_mariadb.py deleted file mode 100644 index 059936a..0000000 --- a/kontor-scripts/copy_to_mariadb.py +++ /dev/null @@ -1,52 +0,0 @@ -""" -copy data from SQLite to MariaDB -""" -import sqlite3 -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter - -from config import get_logger, get_database_cursors, get_meta_data, get_scripts - -parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('--recreate-db', action='store_true') -parser.add_argument('--verbose', '-v', action='count', default=0) -args = parser.parse_args() - - -def copy_data(mariadb_conn, sqlite_conn, table_scripts): - mariadb_cursor = mariadb_conn.cursor() - sqlite_cursor = sqlite_conn.cursor() - # logger.info(table_scripts) - for table_id in scripts: - select_statement = scripts[table_id]['select_sqlite'] - # logger.info(select_statement) - insert_statement = scripts[table_id]['insert_mariadb'] - mariadb_cursor.execute("SET FOREIGN_KEY_CHECKS = 0") - mariadb_cursor.execute(scripts[table_id]['truncate_mariadb']) - try: - sqlite_cursor.execute(select_statement) - rows = sqlite_cursor.fetchall() - for row in rows: - try: - mariadb_cursor.execute(insert_statement, row) - except sqlite3.Error as error: - logger.info('insert failed with %s\n%s\n%s', error, insert_statement, row) - mariadb_conn.commit() - mariadb_cursor.execute(scripts[table_id]['count']) - (number_of_rows,) = mariadb_cursor.fetchone() - row = sqlite_cursor.execute(scripts[table_id]['count']).fetchone() - logger.info('%s contains %d : %d entries', scripts[table_id]['name'], number_of_rows, row[0]) - except sqlite3.Error as error: - logger.info('select failed with %s', error) - - -if __name__ == '__main__': - logger = get_logger(args.verbose) - logger.info('kontor.copy_to_sqlite started') - s_conn, m_conn = get_database_cursors(logger) - meta_data_tables = get_meta_data(m_conn) - # logger.info(meta_data_tables) - scripts = get_scripts(meta_data_tables, logger) - copy_data(m_conn, s_conn, scripts) - s_conn.close() - m_conn.close() - logger.info('kontor.copy_to_sqlite finished') diff --git a/kontor-scripts/copy_to_sqlite.py b/kontor-scripts/copy_to_sqlite.py deleted file mode 100644 index 3455cb4..0000000 --- a/kontor-scripts/copy_to_sqlite.py +++ /dev/null @@ -1,51 +0,0 @@ -""" -copy data from MariaDB to SQLite -""" -import sqlite3 -import mariadb -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter -from config import get_database_cursors, create_tables, get_logger, get_meta_data, get_scripts - -parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('--recreate-db', action='store_true') -parser.add_argument('--verbose', '-v', action='count', default=0) -args = parser.parse_args() - - -def copy_data(mariadb_conn, sqlite_conn, table_scripts): - mariadb_cursor = mariadb_conn.cursor() - sqlite_cursor = sqlite_conn.cursor() - # logger.info(table_scripts) - for table_id in table_scripts: - select_statement = scripts[table_id]['select_mariadb'] - # logger.info(select_statement) - insert_statement = scripts[table_id]['insert_sqlite'] - try: - mariadb_cursor.execute(select_statement) - rows = mariadb_cursor.fetchall() - for row in rows: - try: - sqlite_cursor.execute(insert_statement, row) - except sqlite3.Error as error: - logger.info('insert failed with %s\n%s\n%s', error, insert_statement, row) - sqlite_conn.commit() - mariadb_cursor.execute(scripts[table_id]['count']) - (number_of_rows,) = mariadb_cursor.fetchone() - row = sqlite_cursor.execute(scripts[table_id]['count']).fetchone() - logger.info('%s contains %d : %d entries', scripts[table_id]['name'], number_of_rows, row[0]) - except mariadb.Error as error: - logger.info('select failed with %s', error) - - -if __name__ == '__main__': - logger = get_logger(args.verbose) - logger.info('kontor.copy_to_sqlite started') - s_conn, m_conn = get_database_cursors(logger) - meta_data_tables = get_meta_data(m_conn) - # logger.info(meta_data_tables) - scripts = get_scripts(meta_data_tables, logger) - create_tables(s_conn, logger, args.recreate_db, scripts) - copy_data(m_conn, s_conn, scripts) - s_conn.close() - m_conn.close() - logger.info('kontor.copy_to_sqlite finished') diff --git a/kontor-scripts/db/models/__init__.py b/kontor-scripts/db/models/__init__.py deleted file mode 100644 index 05911d7..0000000 --- a/kontor-scripts/db/models/__init__.py +++ /dev/null @@ -1,84 +0,0 @@ -from typing import Any, Dict -from db.models.admin import ( - Assignment, - Token, - Profile, - Permission, - MailAccount, - Mail, -) -from db.models.bookshelf import ( - ArticleAuthor, - BookAuthor, - BookshelfPublisher, - Article, - Book, - Author, -) -from db.models.comic import ( - Issue, - StoryArc, - TradePaperback, - Volume, - ComicWork, - IssueWork, - Artist, - Comic, - Publisher, - WorkType, -) -from db.models.media import ( - MediaFile, - MediaActor, - MediaActorFile, - MediaArticle, - MediaVideo, -) -from db.models.tysc import ( - Card, - CardSet, - Rooster, - Team, - FieldPosition, - Player, - Vendor, - Sport, -) - -registry: Dict[str, Any] = { - Sport.__tablename__: Sport, - Player.__tablename__: Player, - Team.__tablename__: Team, - FieldPosition.__tablename__: FieldPosition, - Rooster.__tablename__: Rooster, - Vendor.__tablename__: Vendor, - CardSet.__tablename__: CardSet, - Card.__tablename__: Card, - Artist.__tablename__: Artist, - Publisher.__tablename__: Publisher, - WorkType.__tablename__: WorkType, - Comic.__tablename__: Comic, - Volume.__tablename__: Volume, - StoryArc.__tablename__: StoryArc, - Issue.__tablename__: Issue, - TradePaperback.__tablename__: TradePaperback, - ComicWork.__tablename__: ComicWork, - IssueWork.__tablename__: IssueWork, - Article.__tablename__: Article, - BookshelfPublisher.__tablename__: BookshelfPublisher, - Book.__tablename__: Book, - Author.__tablename__: Author, - ArticleAuthor.__tablename__: ArticleAuthor, - BookAuthor.__tablename__: BookAuthor, - MediaArticle.__tablename__: MediaArticle, - MediaVideo.__tablename__: MediaVideo, - MediaFile.__tablename__: MediaFile, - MediaActor.__tablename__: MediaActor, - MediaActorFile.__tablename__: MediaActorFile, - Profile.__tablename__: Profile, - Permission.__tablename__: Permission, - Assignment.__tablename__: Assignment, - Token.__tablename__: Token, - MailAccount.__tablename__: MailAccount, - Mail.__tablename__: Mail -} diff --git a/kontor-scripts/db/models/admin.py b/kontor-scripts/db/models/admin.py deleted file mode 100644 index 6acfa58..0000000 --- a/kontor-scripts/db/models/admin.py +++ /dev/null @@ -1,205 +0,0 @@ -from datetime import datetime -from typing import Any, Dict - -from sqlalchemy import Column, ForeignKey, Integer, String, Boolean -from sqlalchemy.orm import relationship, mapped_column, Mapped - -from db.models.base import Base, BaseMixin - - -class Profile(Base, BaseMixin): - __tablename__ = 'profile' - first_name = Column(String) - last_name = Column(String) - user_name = Column(String, nullable=False) - email = Column(String) - password = Column(String) - enabled = Column(Boolean) - assignments = relationship("Assignment") - tokens = relationship("Token") - - def get_full_name(self) -> str: - full_name: str = "" - if self.first_name is not None: - full_name += str(self.first_name) - if self.last_name is not None: - if len(full_name) > 0: - full_name += " " - full_name += str(self.last_name) - return full_name - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.first_name = import_data['first_name'] - self.last_name = import_data['last_name'] - self.user_name = import_data['user_name'] - self.email = import_data['email'] - self.password = import_data['password'] - self.enabled = import_data['enabled'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['first_name'] = self.first_name - item['last_name'] = self.last_name - item['user_name'] = self.user_name - item['email'] = self.email - item['password'] = self.password - item['enabled'] = self.enabled - return item - - -class Token(Base, BaseMixin): - __tablename__ = "token" - token = Column(String, nullable=False, unique=True) - name = Column(String) - last_used_date: Mapped[datetime] = mapped_column() - enabled = Column(Boolean) - profile_id = Column(String, ForeignKey("profile.id"), nullable=False) - profile = relationship("Profile", back_populates="tokens") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.token = import_data['token'] - self.name = import_data['name'] - self.last_used_date = import_data['last_used_date'] - self.enabled = import_data['enabled'] - self.profile_id = import_data['profile_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['token'] = self.token - item['name'] = self.name - item['last_used_date'] = self.last_used_date - item['enabled'] = self.enabled - item['profile_id'] = self.profile_id - return item - - -class Permission(Base, BaseMixin): - __tablename__ = "permission" - name = Column(String, nullable=False) - assignments = relationship("Assignment") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['name'] = self.name - return item - -class Assignment(Base, BaseMixin): - __tablename__ = "assignment" - profile_id = Column(String, ForeignKey("profile.id"), nullable=False) - profile = relationship("Profile", back_populates="assignments") - permission_id = Column(String, ForeignKey("permission.id"), nullable=False) - permission = relationship("Permission", back_populates="assignments") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.profile_id = import_data['profile_id'] - self.permission_id = import_data['permission_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['profile_id'] = self.profile_id - item['permission_id'] = self.permission_id - return item - - -class MailAccount(Base, BaseMixin): - __tablename__ = "mail_account" - host = Column(String) - port = Column(Integer) - protocol = Column(String) - user_name = Column(String) - password = Column(String) - start_tls = Column(Boolean) - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.host = import_data['host'] - self.port = import_data['port'] - self.protocol = import_data['protocol'] - self.user_name = import_data['user_name'] - self.password = import_data['password'] - self.start_tls = import_data['start_tls'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['host'] = self.host - item['port'] = self.port - item['protocol'] = self.protocol - item['user_name'] = self.user_name - item['password'] = self.password - item['start_tls'] = self.start_tls - return item - - -class Mail(Base, BaseMixin): - __tablename__ = "mail" - folder: Mapped[str] = mapped_column() - subject: Mapped[str] = mapped_column() - body: Mapped[str] = mapped_column() - sent_date: Mapped[datetime] = mapped_column() - received_date: Mapped[datetime] = mapped_column() - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.folder = import_data['folder'] - self.subject = import_data['subject'] - self.body = import_data['body'] - self.sent_date = import_data['sent_date'] - self.received_date = import_data['received_date'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['folder'] = self.folder - item['subject'] = self.subject - item['body'] = self.body - item['sent_date'] = str(self.sent_date) - item['received_date'] = str(self.received_date) - return item diff --git a/kontor-scripts/db/models/bookshelf.py b/kontor-scripts/db/models/bookshelf.py deleted file mode 100644 index 83a00db..0000000 --- a/kontor-scripts/db/models/bookshelf.py +++ /dev/null @@ -1,159 +0,0 @@ -from typing import Any, AnyStr, Dict -from sqlalchemy import Column, ForeignKey, Integer, String -from sqlalchemy.orm import relationship - -from db.models.base import Base, BaseMixin - - -class Article(Base, BaseMixin): - __tablename__ = 'article' - title = Column(String, unique=True) - article_authors = relationship("ArticleAuthor") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.title = import_data['title'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['title'] = self.title - return item - - -class Author(Base, BaseMixin): - __tablename__ = 'author' - first_name = Column(String) - last_name = Column(String) - article_authors = relationship("ArticleAuthor") - book_authors = relationship("BookAuthor") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.first_name = import_data['first_name'] - self.last_name = import_data['last_name'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['first_name'] = self.first_name - item['last_name'] = self.last_name - return item - - -class BookshelfPublisher(Base, BaseMixin): - __tablename__ = 'bookshelf_publisher' - name = Column(String, unique=True) - books = relationship("Book") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['name'] = self.name - return item - - -class Book(Base, BaseMixin): - __tablename__ = 'book' - isbn = Column(String, unique=True) - title = Column(String) - year = Column(Integer, nullable=False) - publisher_id = Column(String, ForeignKey('bookshelf_publisher.id'), nullable=False) - publisher = relationship('BookshelfPublisher', back_populates="books") - book_authors = relationship("BookAuthor") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.isbn = import_data['isbn'] - self.title = import_data['title'] - self.year = import_data['year'] - self.publisher_id = import_data['publisher_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['isbn'] = self.isbn - item['title'] = self.title - item['year'] = self.year - item['publisher_id'] = self.publisher_id - return item - - -class ArticleAuthor(Base, BaseMixin): - __tablename__ = 'article_author' - article_id = Column(String, ForeignKey('article.id'), nullable=False) - article = relationship('Article', back_populates="article_authors") - author_id = Column(String, ForeignKey('author.id'), nullable=False) - author = relationship('Author', back_populates="article_authors") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.article_id = import_data['article_id'] - self.author_id = import_data['author_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['article_id'] = self.article_id - item['author_id'] = self.author_id - return item - - -class BookAuthor(Base, BaseMixin): - __tablename__ = 'book_author' - author_id = Column(String, ForeignKey('author.id'), nullable=False) - author = relationship('Author', back_populates="book_authors") - book_id = Column(String, ForeignKey('book.id'), nullable=False) - book = relationship('Book', back_populates="book_authors") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.author_id = import_data['author_id'] - self.book_id = import_data['book_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['author_id'] = self.author_id - item['book_id'] = self.book_id - return item diff --git a/kontor-scripts/db/models/comic.py b/kontor-scripts/db/models/comic.py deleted file mode 100644 index afa1059..0000000 --- a/kontor-scripts/db/models/comic.py +++ /dev/null @@ -1,352 +0,0 @@ -import uuid -from datetime import datetime -from typing import AnyStr, Dict, List, Optional, Any -from sqlalchemy import Column, ForeignKey, Integer, String, Boolean, func -from sqlalchemy.orm import relationship, Mapped, mapped_column - -from db.models.base import Base, BaseMixin - - -class Publisher(Base): - __tablename__ = "publisher" - id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4) - created_date: Mapped[datetime] = mapped_column(default=func.now()) - last_modified_date: Mapped[datetime] = mapped_column(default=func.now()) - version: Mapped[int] = mapped_column(default=0) - name = Column(String, unique=True) - weblink = Column(String, nullable=True) - parent_publisher_id: Mapped[Optional[str]] = mapped_column(ForeignKey('publisher.id')) - parent_publisher: Mapped[Optional['Publisher']] = relationship("Publisher", back_populates="imprints", remote_side=[id]) - imprints: Mapped[List['Publisher']] = relationship('Publisher', back_populates="parent_publisher") - comics = relationship("Comic") - - def __repr__(self): - return f'Publisher({self.id} {self.name})' - - def __str__(self): - return self.__repr__() - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - self.parent_publisher_id = import_data['parent_publisher_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = { - 'id': self.id, - 'created_date': str(self.created_date), - 'last_modified_date': str(self.last_modified_date), - 'version': self.version, - 'name': self.name, - 'weblink': self.weblink, - 'parent_publisher_id': self.parent_publisher_id - } - return item - - -class Comic(Base, BaseMixin): - __tablename__ = 'comic' - title = Column(String, unique=True) - publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False) - publisher = relationship("Publisher", back_populates="comics") - current_order = Column(Boolean) - completed = Column(Boolean) - weblink = Column(String, nullable=True) - issues = relationship("Issue") - story_arcs = relationship("StoryArc") - trade_paperbacks = relationship("TradePaperback") - volumes = relationship("Volume") - comic_works = relationship("ComicWork") - - def __repr__(self): - return f'Comic({self.id} {self.version} {self.title} {self.publisher.name})' - - def __str__(self): - return f'{self.title}({self.id})' - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.title = import_data['title'] - self.publisher_id = import_data['publisher_id'] - self.current_order = import_data['current_order'] - self.completed = import_data['completed'] - if 'weblink' in import_data: - self.weblink = import_data['weblink'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = { - 'id': self.id, - 'created_date': str(self.created_date), - 'last_modified_date': str(self.last_modified_date), - 'version': self.version, - 'title': self.title, - 'publisher_id': self.publisher_id, - 'current_order': self.current_order, - 'completed': self.completed, - 'weblink': self.weblink - } - return item - - -class Volume(Base, BaseMixin): - __tablename__ = "volume" - name = Column(String, nullable=False) - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="volumes") - story_arcs = relationship("StoryArc") - issues = relationship("Issue") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - self.comic_id = import_data['comic_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['name'] = self.name - item['comic_id'] = self.comic_id - return item - -class TradePaperback(Base, BaseMixin): - __tablename__ = "trade_paperback" - name = Column(String, nullable=False) - issue_start = Column(Integer) - issue_end = Column(Integer) - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="trade_paperbacks") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - self.issue_start = import_data['issue_start'] - self.issue_end = import_data['issue_end'] - self.comic_id = import_data['comic_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['name'] = self.name - item['issue_start'] = self.issue_start - item['issue_end'] = self.issue_end - item['comic_id'] = self.comic_id - return item - - -class StoryArc(Base, BaseMixin): - __tablename__ = "story_arc" - name = Column(String, nullable=False) - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="story_arcs") - volume_id = Column(String, ForeignKey("volume.id"), nullable=True) - volume = relationship("Volume", back_populates="story_arcs") - issues = relationship("Issue") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - self.comic_id = import_data['comic_id'] - self.volume_id = import_data['volume_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = { - 'id': self.id, - 'created_date': str(self.created_date), - 'last_modified_date': str(self.last_modified_date), - 'version': self.version, - 'name': self.name, - 'comic_id': self.comic_id, - 'volume_id': self.volume_id - } - return item - - -class Issue(Base, BaseMixin): - __tablename__ = "issue" - issue_number = Column(String) - title = Column(String, nullable=True) - published_on: Mapped[datetime] = mapped_column(nullable=True) - in_stock = Column(Boolean) - is_read = Column(Boolean) - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="issues") - volume_id = Column(String, ForeignKey("volume.id"), nullable=True) - volume = relationship("Volume", back_populates="issues") - story_arc_id = Column(String, ForeignKey("story_arc.id"), nullable=True) - story_arc = relationship("StoryArc", back_populates="issues") - issue_works = relationship("IssueWork") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.issue_number = import_data['issue_number'] - self.title = import_data['title'] - if import_data['published_on'] == 'None': - self.published_on = None # type: ignore - else: - self.published_on = import_data['published_on'] - self.in_stock = import_data['in_stock'] - self.is_read = import_data['is_read'] - self.comic_id = import_data['comic_id'] - self.volume_id = import_data['volume_id'] - self.story_arc_id = import_data['story_arc_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = { - 'id': self.id, - 'created_date': str(self.created_date), - 'last_modified_date': str(self.last_modified_date), - 'version': self.version, - 'issue_number': self.issue_number, - 'title': self.title, - 'published_on': str(self.published_on), - 'in_stock': self.in_stock, - 'is_read': self.is_read, - 'comic_id': self.comic_id, - 'volume_id': self.volume_id, - 'story_arc_id': self.story_arc_id - } - return item - - -class Artist(Base, BaseMixin): - __tablename__ = "artist" - name = Column(String, nullable=False) - weblink = Column(String, nullable=True) - comic_works = relationship("ComicWork") - issue_works = relationship("IssueWork") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - if 'weblink' in import_data: - self.weblink = import_data['weblink'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = { - 'id': self.id, - 'created_date': str(self.created_date), - 'last_modified_date': str(self.last_modified_date), - 'version': self.version, - 'name': self.name, - 'weblink': self.weblink - } - return item - - -class WorkType(Base, BaseMixin): - __tablename__ = "worktype" - name = Column(String, nullable=False, unique=True) - comic_works = relationship("ComicWork") - issue_works = relationship("IssueWork") - - def __repr__(self): - return f'Worktype({self.id} {self.version} {self.name} {len(self.comic_works)})' - - def __str__(self): - return f'{self.name}({self.id})' - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = { - 'id': self.id, - 'created_date': str(self.created_date), - 'last_modified_date': str(self.last_modified_date), - 'version': self.version, - 'name': self.name - } - return item - - -class ComicWork(Base, BaseMixin): - __tablename__ = "comic_work" - comic_id = Column(String, ForeignKey("comic.id"), nullable=False) - comic = relationship("Comic", back_populates="comic_works") - artist_id = Column(String, ForeignKey("artist.id"), nullable=False) - artist = relationship("Artist", back_populates="comic_works") - work_type_id = Column(String, ForeignKey("worktype.id"), nullable=False) - work_type = relationship("WorkType", back_populates="comic_works") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.comic_id = import_data['comic_id'] - self.artist_id = import_data['artist_id'] - self.work_type_id = import_data['work_type_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = { - 'id': self.id, - 'created_date': str(self.created_date), - 'last_modified_date': str(self.last_modified_date), - 'version': self.version, - 'comic_id': self.comic_id, - 'artist_id': self.artist_id, - 'work_type_id': self.work_type_id - } - return item - - -class IssueWork(Base, BaseMixin): - __tablename__ = "issue_work" - issue_id = Column(String, ForeignKey("issue.id"), nullable=False) - issue = relationship("Issue", back_populates="issue_works") - artist_id = Column(String, ForeignKey("artist.id"), nullable=False) - artist = relationship("Artist", back_populates="issue_works") - work_type_id = Column(String, ForeignKey("worktype.id"), nullable=False) - work_type = relationship("WorkType", back_populates="issue_works") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.issue_id = import_data['issue_id'] - self.artist_id = import_data['artist_id'] - self.work_type_id = import_data['work_type_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = { - 'id': self.id, - 'created_date': str(self.created_date), - 'last_modified_date': str(self.last_modified_date), - 'version': self.version, - 'issue_id': self.issue_id, - 'artist_id': self.artist_id, - 'work_type_id': self.work_type_id - } - return item diff --git a/kontor-scripts/db/models/database.py b/kontor-scripts/db/models/database.py deleted file mode 100644 index 5eb9dbb..0000000 --- a/kontor-scripts/db/models/database.py +++ /dev/null @@ -1,66 +0,0 @@ -from enum import Enum, auto -from logging import Logger -from typing import Any - -from sqlalchemy import select -from sqlalchemy.orm import sessionmaker - -from db.models import registry - - -class ColumnEntry(Enum): - COLUMN_NAME = 'column' - COLUMN_LABEL = 'label' - COLUMN_ORDER = 'order' - COLUMN_REF_COLUMN = 'ref_column' - COLUMN_TYPE = 'type' - COLUMN_WIDGET = 'widget' - - -class StatusType(Enum): - UNKNOWN = auto() - FILE_NAME = auto() - FILE_ID = auto() - DUPLICATE = auto() - CLOUD_LINK = auto() - CLOUD_LINK_ID = auto() - - -class ExportType(Enum): - JSON = "JSON" - YAML = "YAML" - SQLITE = "SQLite" - - -class KontorDB: - - def __init__(self, db_engine: Any, log: Logger): - self.engine = db_engine - self.log = log - - def data(self, table_name: str, columns: dict, filters: dict) -> list: - data = [] - __session__ = sessionmaker(self.engine) - table = registry[table_name] - with __session__() as session: - entries = [] - if len(filters) == 0: - entries = session.scalars(select(table)).all() - else: - entries = session.scalars(select(table).filter_by(**filters)).all() - for entry in entries: - # self.log.info("data: %s", entry) - row = [] - for order in columns.keys(): - column_name = columns[order][ColumnEntry.COLUMN_NAME] - ref_column = columns[order][ColumnEntry.COLUMN_REF_COLUMN] - if str(column_name).endswith("_id"): - ref_table = column_name[:-3] - ref = getattr(entry, ref_table) - value = getattr(ref, ref_column) - row.append(value) - else: - row.append(getattr(entry, column_name)) - data.append(row) - # self.log.info("data: %s", data) - return data diff --git a/kontor-scripts/db/models/media.py b/kontor-scripts/db/models/media.py deleted file mode 100644 index 436df4b..0000000 --- a/kontor-scripts/db/models/media.py +++ /dev/null @@ -1,224 +0,0 @@ -import re -import subprocess -from datetime import datetime -from pathlib import Path -from typing import Any, Dict -import requests -from bs4 import BeautifulSoup -from sqlalchemy import Boolean, Column, String, ForeignKey -from sqlalchemy.orm import relationship - -from db.models.base import Base, BaseMixin, BaseVideoMixin - - -class MediaFile(Base, BaseMixin, BaseVideoMixin): - __tablename__ = 'media_file' - media_actor_files = relationship("MediaActorFile") - - def __repr__(self): - return f'MediaFile(\n\tID: {self.id}\n\tTitle: {self.title}\n\tURL: {self.url}\n\tReview: {self.review}\n\tDownload: {self.should_download}\n\tPath: {self.path}\n\tCloudlink: {self.cloud_link})' - - def __str__(self): - return f'{self.title}({self.id})' - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.cloud_link = import_data['cloud_link'] - self.file_name = import_data['file_name'] - self.path = import_data['path'] - self.review = import_data['review'] - self.title = import_data['title'] - self.url = import_data['url'] - self.should_download = import_data['should_download'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['cloud_link'] = self.cloud_link - item['file_name'] = self.file_name - item['path'] = self.path - item['review'] = self.review - item['title'] = self.title - item['url'] = self.url - item['should_download'] = self.should_download - return item - - def update_title(self) -> None: - print(f"update title for {self.url}") - try: - r = requests.get(self.url) - soup = BeautifulSoup(r.content, "html.parser") - title_tag = soup.find('title') - if title_tag: - self.title = title_tag.get_text() - self.review = False - except: - self.title = None - self.review = True - self.last_modified_date = datetime.now() - - def download_file(self, download_dir: str, dl_tool: str): - print(f"download file for {self.url} to {download_dir}") - result = subprocess.run([dl_tool, self.url], cwd=download_dir, capture_output=True, text=True) - if result.returncode == 0: - output = result.stdout - output = re.sub(' +', ' ', output) - lines_list = output.splitlines() - file_name = self.__parse_output__(lines_list) - if file_name is None: - self.review = True - self.should_download = True - self.file_name = None - else: - download_file = Path(file_name) - self.should_download = False - self.file_name = download_file.name - self.cloud_link = str(download_file.absolute()) - self.last_modified_date = datetime.now() - - def __parse_output__(self, lines_list): - self.file_name = None - for line in lines_list: - if 'has already been downloaded' in line: - end_len = len(' has already been downloaded') - self.file_name = line[11:-end_len] - if 'Destination' in line: - line_len = len(line) - start_len = len('[download] Destination: ') - file_len = line_len - start_len - self.file_name = line[-file_len:] - return self.file_name - - -class MediaActor(Base, BaseMixin): - __tablename__ = 'media_actor' - name = Column(String) - url = Column(String, unique=True) - media_actor_files = relationship("MediaActorFile") - - def __repr__(self): - return f'MediaActor(\n\tID: {self.id}\n\tName: {self.name}\n\tURL: {self.url})' - - def __str__(self): - return f'{self.name}({self.id})' - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - self.url = import_data['url'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['name'] = self.name - item['url'] = self.url - return item - - -class MediaActorFile(Base, BaseMixin): - __tablename__ = 'media_actor_file' - media_actor_id = Column(String, ForeignKey("media_actor.id"), nullable=False) - media_actor = relationship("MediaActor", back_populates="media_actor_files") - media_file_id = Column(String, ForeignKey("media_file.id"), nullable=True) - media_file = relationship("MediaFile", back_populates="media_actor_files") - - def __repr__(self): - return f'MediaActorFile(\n\tID: {self.id}\n\tMediaActor: {self.media_actor_id}\n\tMediaFile: {self.media_file_id})' - - def __str__(self): - return f'{self.id}: MediaActor: {self.media_actor_id} - MediaFile: {self.media_file_id}' - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.media_actor_id = import_data['media_actor_id'] - self.media_file_id = import_data['media_file_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['media_actor_id'] = self.media_actor_id - item['media_file_id'] = self.media_file_id - return item - -class MediaArticle(Base, BaseMixin): - __tablename__ = 'media_article' - review = Column(Boolean) - title = Column(String) - url = Column(String, unique=True) - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.review = import_data['review'] - self.title = import_data['title'] - self.url = import_data['url'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['review'] = self.review - item['title'] = self.title - item['url'] = self.url - return item - - -class MediaVideo(Base, BaseMixin): - __tablename__ = 'media_video' - cloud_link = Column(String) - file_name = Column(String) - path = Column(String) - review = Column(Boolean) - title = Column(String) - url = Column(String, unique=True) - should_download = Column(Boolean) - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.cloud_link = import_data['cloud_link'] - self.file_name = import_data['file_name'] - self.path = import_data['path'] - self.review = import_data['review'] - self.title = import_data['title'] - self.url = import_data['url'] - self.should_download = import_data['should_download'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['cloud_link'] = self.cloud_link - item['file_name'] = self.file_name - item['path'] = self.path - item['review'] = self.review - item['title'] = self.title - item['url'] = self.url - item['should_download'] = self.should_download - return item diff --git a/kontor-scripts/db/models/tysc.py b/kontor-scripts/db/models/tysc.py deleted file mode 100644 index d937173..0000000 --- a/kontor-scripts/db/models/tysc.py +++ /dev/null @@ -1,259 +0,0 @@ -from typing import Dict, Any -from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Boolean -from sqlalchemy.orm import relationship - -from db.models.base import Base, BaseMixin - - -class Sport(Base, BaseMixin): - __tablename__ = "sport" - __table_args__ = ( - UniqueConstraint("name"), - ) - name = Column(String, nullable=False, index=True, unique=True) - teams = relationship("Team") - positions = relationship("FieldPosition") - - def __repr__(self): - return f"Sport(id={self.id}, name={self.name}, created_date={self.created_date})" - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['name'] = self.name - return item - -class Team(Base, BaseMixin): - __tablename__ = "team" - name = Column(String, nullable=False, index=True, unique=True) - short_name = Column(String, nullable=False, ) - sport_id = Column(String, ForeignKey("sport.id"), nullable=False) - sport = relationship("Sport", back_populates="teams") - roosters = relationship("Rooster") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - self.short_name = import_data['short_name'] - self.sport_id = import_data['sport_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['name'] = self.name - item['short_name'] = self.short_name - item['sport_id'] = self.sport_id - return item - -class FieldPosition(Base, BaseMixin): - __tablename__ = "field_position" - __table_args__ = ( - UniqueConstraint("name", "sport_id"), - UniqueConstraint("short_name", "sport_id"), - ) - name = Column(String, nullable=False, index=True) - short_name = Column(String, nullable=False) - sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True) - sport = relationship("Sport", back_populates="positions") - roosters = relationship("Rooster") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - self.short_name = import_data['short_name'] - self.sport_id = import_data['sport_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['name'] = self.name - item['short_name'] = self.short_name - item['sport_id'] = self.sport_id - return item - - -class Player(Base, BaseMixin): - __tablename__ = "player" - __table_args__ = ( - UniqueConstraint("first_name", "last_name"), - ) - first_name = Column(String, nullable=False, index=True) - last_name = Column(String, nullable=False, index=True) - roosters = relationship("Rooster") - - def get_full_name(self) -> str: - return f"{self.last_name}, {self.first_name}" - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.first_name = import_data['first_name'] - self.last_name = import_data['last_name'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['first_name'] = self.first_name - item['last_name'] = self.last_name - return item - - -class Rooster(Base, BaseMixin): - __tablename__ = "rooster" - __table_args__ = ( - UniqueConstraint("year", "team_id", "player_id", "position_id"), - ) - year = Column(Integer) - team_id = Column(String, ForeignKey("team.id"), nullable=False, index=True) - team = relationship("Team", back_populates="roosters") - player_id = Column(String, ForeignKey("player.id"), nullable=False, index=True) - player = relationship("Player", back_populates="roosters") - position_id = Column(String, ForeignKey("field_position.id"), nullable=False, index=True) - position = relationship("FieldPosition", back_populates="roosters") - cards = relationship("Card") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.year = import_data['year'] - self.team_id = import_data['team_id'] - self.player_id = import_data['player_id'] - self.position_id = import_data['position_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['year'] = self.year - item['team_id'] = self.team_id - item['player_id'] = self.player_id - item['position_id'] = self.position_id - return item - - -class Vendor(Base, BaseMixin): - __tablename__ = "vendor" - name = Column(String, nullable=False, unique=True, index=True) - card_sets = relationship("CardSet") - cards = relationship("Card") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['name'] = self.name - return item - - -class CardSet(Base, BaseMixin): - __tablename__ = "card_set" - __table_args__ = ( - UniqueConstraint("name", "vendor_id"), - ) - name = Column(String, index=True) - parallel_set = Column(Boolean) - insert_set = Column(Boolean) - vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False, index=True) - vendor = relationship("Vendor", back_populates="card_sets") - cards = relationship("Card") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.name = import_data['name'] - self.parallel_set = import_data['parallel_set'] - self.insert_set = import_data['insert_set'] - self.vendor_id = import_data['vendor_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['name'] = self.name - item['parallel_set'] = self.parallel_set - item['insert_set'] = self.insert_set - item['vendor_id'] = self.vendor_id - return item - - -class Card(Base, BaseMixin): - __tablename__ = "card" - __table_args__ = ( - UniqueConstraint("card_number", "year", "vendor_id", "card_set_id"), - ) - card_number = Column(Integer, index=True) - year = Column(Integer, index=True) - card_set_id = Column(String, ForeignKey("card_set.id"), nullable=False) - card_set = relationship("CardSet", back_populates="cards") - rooster_id = Column(String, ForeignKey("rooster.id"), nullable=False) - rooster = relationship("Rooster", back_populates="cards") - vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False) - vendor = relationship("Vendor", back_populates="cards") - - def import_dict(self, import_data: Dict[str, Any]): - self.id = import_data['id'] - self.created_date = import_data['created_date'] - self.last_modified_date = import_data['last_modified_date'] - self.version = import_data['version'] - self.card_number = import_data['card_number'] - self.year = import_data['year'] - self.card_set_id = import_data['card_set_id'] - self.rooster_id = import_data['rooster_id'] - self.vendor_id = import_data['vendor_id'] - - def export_dict(self) -> Dict[str, Any]: - item: Dict[str, Any] = {} - item['id'] = self.id - item['created_date'] = str(self.created_date) - item['last_modified_date'] = str(self.last_modified_date) - item['version'] = self.version - item['card_number'] = self.card_number - item['year'] = self.year - item['card_set_id'] = self.card_set_id - item['rooster_id'] = self.rooster_id - item['vendor_id'] = self.vendor_id - return item diff --git a/kontor-scripts/db_structure.py b/kontor-scripts/db_structure.py deleted file mode 100644 index 947ab4a..0000000 --- a/kontor-scripts/db_structure.py +++ /dev/null @@ -1,67 +0,0 @@ -""" -Prints the database kontor structure -""" -import mariadb -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter -from config import get_database_cursors, get_logger - -parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('--verbose', '-v', action='count', default=0) -args = parser.parse_args() - - -def show_tables(cur, log): - """ - Retrieves the list of tables from the database - :param cur: - :param log: - :return: - """ - log.info('get list of tables') - table_list = [] - cur.execute("SHOW TABLES") - for (tablename,) in cur.fetchall(): - table_list.append(tablename) - return table_list - - -def get_field_info(cur): - """ - Retrieves the field info associated with a cursor - :param cur: - :return: - """ - field_info = mariadb.fieldinfo() - field_info_text_list = [] - for column in cur.description: - column_name = column[0] - column_type = field_info.type(column) - column_flags = field_info.flag(column) - field_info_text_list.append(f"{column_name}: {column_type} {column_flags}") - return field_info_text_list - - -def get_table_field_info(cur, tablename): - """ - Retrieves the field info associated with a table - :param cur: - :param tablename: - :return: - """ - cur.execute(f"SELECT * FROM {tablename} LIMIT 1") - field_info = get_field_info(cur) - return field_info - - -if __name__ == '__main__': - logger = get_logger(args.verbose) - logger.info("kontor.db_structure started") - _, mariadb_conn = get_database_cursors(logger) - tables = show_tables(mariadb_conn.cursor(), logger) - for table in tables: - field_info_text = get_table_field_info(mariadb_conn.cursor(), table) - print(f"Columns in table {table}:") - print("\n".join(field_info_text)) - print("\n") - mariadb_conn.close() - logger.info("kontor.db_structure finished") diff --git a/kontor-scripts/download.py b/kontor-scripts/download.py index 7ee338c..9101288 100644 --- a/kontor-scripts/download.py +++ b/kontor-scripts/download.py @@ -2,26 +2,23 @@ download files with URLs from DB """ -import os import re import subprocess +import sys from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser from datetime import datetime from enum import Enum, auto from pathlib import Path -import sys -from typing import Any, Dict +from logging import Logger +from typing import Any, Dict, Optional from uuid import UUID -from platformdirs import PlatformDirs -import requests -import yaml - -from config import get_api_config, get_logger +from api import Option, OptionType, Server, get_api_config +from log import get_logger parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) parser.add_argument("--verbose", "-v", action="count", default=0) -parser.add_argument("--config", "-c", default="kontor-docker") +parser.add_argument("--config", "-c", default="kontor-api") parser.add_argument("--dir", "-d", default="/data/media") parser.add_argument("--limit", "-l", type=int, help="maximum number of links to check") parser.add_argument("--tool", "-t", default="yt-dlp") @@ -30,6 +27,10 @@ args = parser.parse_args() class FileStatus(Enum): + """ + Status of video file. + """ + DOWNLOADED = auto() RENAMED = auto() UNKNOWN = auto() @@ -40,7 +41,10 @@ def download_file( file_info: dict, download_dir: str = "/data/media", dl_tool: str = "yt-dlp", -) -> dict: +) -> Dict[str, Any]: + """ + Download file from url. + """ print(f"download file for {url} to {download_dir}") result = subprocess.run( [dl_tool, url], cwd=download_dir, capture_output=True, text=True @@ -50,7 +54,7 @@ def download_file( output = re.sub(" +", " ", output) lines_list = output.splitlines() file_name = __parse_output__(lines_list) - log.info(f"found file: {file_name}") + logger.info("found file: %s", file_name) if file_name is None or not file_name.strip(): file_info["review"] = True file_info["should_download"] = True @@ -65,14 +69,14 @@ def download_file( return file_info -def __parse_output__(lines_list: list[str]) -> str | None: +def __parse_output__(lines_list: list[str]) -> Optional[str]: file_name = None for line in lines_list: - log.debug(f"parse line: {line}") + logger.debug("parse line: %s", line) if "has already been downloaded" in line: end_len = len(" has already been downloaded") file_name = line[11:-end_len] - log.info(f"file_name: {file_name}") + logger.info("file_name: %s", file_name) break if "Destination" in line: line_len = len(line) @@ -85,92 +89,92 @@ def __parse_output__(lines_list: list[str]) -> str | None: return file_name -def is_file_downloaded(media_file: dict, dir: Path) -> FileStatus: +def is_file_downloaded(media_file: dict, path: Path) -> FileStatus: + """ + Check, if file is already downloaded. + """ file_name_as_title = f"{media_file['file_name']}" if not file_name_as_title: - log.info("title has not been set - start download") + logger.info("title has not been set - start download") return FileStatus.UNKNOWN - file_title = Path(dir, f"{file_name_as_title}.mp4") + file_title = Path(path, f"{file_name_as_title}.mp4") if file_title.exists(): - log.info(f"{file_name_as_title} has been downloaded") + logger.info("%s has been downloaded", file_name_as_title) media_file["should_download"] = False return FileStatus.DOWNLOADED file_name_as_id = f"{media_file['id']}" - file_with_id_as_name = Path(dir, f"{file_name_as_id}.mp4") + file_with_id_as_name = Path(path, f"{file_name_as_id}.mp4") if file_with_id_as_name.exists(): - log.info(f"{file_with_id_as_name} has been downloaded and renamed") + logger.info("%s has been downloaded and renamed", file_with_id_as_name) media_file["cloud_link"] = str(file_with_id_as_name) media_file["should_download"] = False return FileStatus.RENAMED - log.info("could not find file - start download") + logger.info("could not find file - start download") return FileStatus.UNKNOWN -def update_status(item_id: UUID, file_info: dict, api_data: Dict[str, Any]): - host = api_data["host"] - token = api_data['token'] - url: str = f"http://{host}:{port}/api/media/files/{item_id}" - headers: Dict[str, str] = {"Authorization": f"Bearer {token}"} - update = requests.put(url, headers=headers, json=file_info) - log.info(f"update status: {update.status_code}") - log.info(f"update result: {update.json()}") +def update_status(item_id: UUID, file_info: dict, api_server: Server, log: Logger): + """ + Update MediaFile + """ + update = api_server.update(log, "media_file", item_id, file_info) + log.info("update result: %s", update) def rename_file(file_info: dict): + """ + Rename file. + """ item_id = file_info["id"] file_name = file_info["file_name"] if file_name is None or not file_name.strip(): - log.info("file_name is not set, rename is not executed") + logger.info("file_name is not set, rename is not executed") file_info["review"] = True file_info["should_download"] = True return file = Path(args.dir, file_name) new_file_path = file.with_name(f"{item_id}{file.suffix}") - log.info(f"rename {file} to {new_file_path}") + logger.info("rename %s to %s", file, new_file_path) file.rename(Path(new_file_path)) file_info["cloud_link"] = str(new_file_path) if __name__ == "__main__": - log = get_logger(args.verbose, args.config) - log.info("kontor.download started") - api_data = get_api_config(log, args.config) - host = api_data["host"] - port = api_data["port"] - token = api_data['token'] - url: str = f"http://{host}:{port}/api/media/files?download=true" - headers: Dict[str, str] = {"Authorization": f"Bearer {token}"} - response = requests.get(url, headers=headers) - log.info(f"Status: {response.status_code}") - data = response.json() + logger = get_logger(args.verbose, args.config) + logger.info("kontor.download started") + APICONFIG = get_api_config(logger, args.config) + server: Server = APICONFIG.server[0] + data = server.request( + log=logger, table="media_file", param=Option(OptionType.PARAM, "download=true") + ) entries_count = len(data) - log.info(f"data: {entries_count}") + logger.info("data: %s", entries_count) mediafile_index = 1 - log.debug(f"data: {data}") + logger.debug("data: %s", data) missing_actors = {} if args.dry_run: sys.exit(0) if args.limit: - log.warning(f"check the first {args.limit} links") + logger.warning("check the first %s links", args.limit) for item in data: link = item["url"] file_id = item["id"] - log.info(f"{file_id} - {link}") + logger.info("%s - %s", file_id, link) download_status: FileStatus = is_file_downloaded(item, args.dir) match download_status: case FileStatus.DOWNLOADED: rename_file(item) - update_status(file_id, item, api_data) + update_status(file_id, item, api_server=server, log=logger) case FileStatus.RENAMED: - log.info("update status") - update_status(file_id, item, api_data) + logger.info("update status") + update_status(file_id, item, api_server=server, log=logger) case FileStatus.UNKNOWN: download_file(link, item, args.dir) rename_file(item) - log.info(f"{item}") - update_status(file_id, item, api_data) - log.warning(f"processed {mediafile_index}/{entries_count}") + logger.info(item) + update_status(file_id, item, api_server=server, log=logger) + logger.warning("processed %s/%s", mediafile_index, entries_count) if args.limit and args.limit <= mediafile_index: break mediafile_index += 1 - log.info("kontor.download finished") + logger.info("kontor.download finished") diff --git a/kontor-scripts/export.py b/kontor-scripts/export.py index b81da36..51dafc3 100644 --- a/kontor-scripts/export.py +++ b/kontor-scripts/export.py @@ -6,8 +6,8 @@ import json import os from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker -from db.models import registry -from db.models.base import Base +from kontor_model.db.models import registry +from kontor_model.db.models.base import Base from config import get_logger parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) diff --git a/kontor-scripts/find_links.py b/kontor-scripts/find_links.py index 1ef6854..0ff56da 100644 --- a/kontor-scripts/find_links.py +++ b/kontor-scripts/find_links.py @@ -2,7 +2,6 @@ download files with URLs from DB """ import logging.config -import sys from typing import Any, Dict import requests import re diff --git a/kontor-scripts/import.py b/kontor-scripts/import.py index 283d017..564a96a 100644 --- a/kontor-scripts/import.py +++ b/kontor-scripts/import.py @@ -1,29 +1,30 @@ """ import data from json file to PostgreSQL """ -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter -from datetime import datetime, date -from logging import Logger -from typing import Any, Dict, List -import os import json - +import os +from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser +from datetime import date, datetime +from logging import Logger from pathlib import Path +from typing import Any, Dict, List + import requests -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker, Session -from db.models.base import Base -from db.models import registry from psycopg2.errors import NotNullViolation +from sqlalchemy import create_engine +from sqlalchemy.orm import Session, sessionmaker + from config import get_api_config, get_logger +from kontor_model.db.models import registry +from kontor_model.db.models.base import Base parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('--verbose', '-v', action='count', default=0) +parser.add_argument("--verbose", "-v", action="count", default=0) parser.add_argument("--config", "-c", default="kontor-docker") -parser.add_argument('--dry-run', '-m', action='store_true') -parser.add_argument('--cleanup', '-d', action='store_true') -parser.add_argument('--file', '-f', default='~/data.json') +parser.add_argument("--dry-run", "-m", action="store_true") +parser.add_argument("--cleanup", "-d", action="store_true") +parser.add_argument("--file", "-f", default="~/data.json") args = parser.parse_args() DB_USER: str = os.getenv("DB_USER", "kontor") @@ -31,7 +32,9 @@ DB_PASSWORD: str = os.getenv("DB_PASSWORD", "kontor") DB_SERVER: str = os.getenv("DB_SERVER", "127.0.0.1") DB_PORT: int = int(os.getenv("DB_PORT", 5432)) DB_DBNAME: str = os.getenv("DB_DBNAME", "kontor") -DATABASE_URL: str = f"postgresql://{DB_USER}:{DB_PASSWORD}@{DB_SERVER}:{DB_PORT}/{DB_DBNAME}" +DATABASE_URL: str = ( + f"postgresql://{DB_USER}:{DB_PASSWORD}@{DB_SERVER}:{DB_PORT}/{DB_DBNAME}" +) def cleanup_database(db: Session, log, dry_run: bool): @@ -46,6 +49,7 @@ def cleanup_database(db: Session, log, dry_run: bool): db.delete(entry) db.commit() + def load_data(filename: str, log) -> Dict[str, List[Dict[str, Any]]]: log.debug("load_data") import_file = Path(filename) @@ -53,45 +57,54 @@ def load_data(filename: str, log) -> Dict[str, List[Dict[str, Any]]]: log.info(f"File {filename} does not exist. Do nothing.") raise FileNotFoundError() log.info("read json file") - with open(filename, 'r') as json_file: + with open(filename, "r") as json_file: json_load = json.load(json_file) return json_load + def get_ids(items: List[Any]) -> List[str]: result: List[str] = [] for item in items: result.append(item.id) return result -def update_item(db: Session, import_data: Dict[str, Any], item: Any, dry_run: bool, log): - for (key, value) in import_data.items(): + +def update_item( + db: Session, import_data: Dict[str, Any], item: Any, dry_run: bool, log +): + for key, value in import_data.items(): existing_value = getattr(item, str(key)) update: bool = has_changed(existing_value, value, log) - #if key == 'published_on': + # if key == 'published_on': # log.info(f"{type(value)}:{value} != {type(existing_value)}:{existing_value} : {update}") if update: log.info(f"update {key}({existing_value}) with {value}") if not dry_run: - if value == 'None': + if value == "None": setattr(item, str(key), None) else: setattr(item, str(key), value) db.add(item) db.commit() + def has_changed(existing_data: Any, import_data: str, log) -> bool: - if existing_data is None and import_data == 'None': + if existing_data is None and import_data == "None": return False if isinstance(existing_data, str): return existing_data != import_data if isinstance(existing_data, date): if len(import_data) > 19: import_date = datetime.strptime(import_data, "%Y-%m-%d %H:%M:%S.%f") - log.debug(f"{type(existing_data)}:{existing_data} == {import_date} : {existing_data != import_date}") + log.debug( + f"{type(existing_data)}:{existing_data} == {import_date} : {existing_data != import_date}" + ) return existing_data != import_date if len(import_data) > 10: import_date = datetime.strptime(import_data, "%Y-%m-%d %H:%M:%S") - log.debug(f"{type(existing_data)}:{existing_data} == {import_date} : {existing_data != import_date}") + log.debug( + f"{type(existing_data)}:{existing_data} == {import_date} : {existing_data != import_date}" + ) return existing_data != import_date return existing_data.strftime("%Y-%m-%d") != import_data return existing_data != import_data @@ -112,11 +125,12 @@ def item_import(db: Session, import_data: Dict[str, Any], dry_run: bool, log): except Exception as error: log.info(f"import failed: {error}") + def item_delete(table_name: str, item_id: str, api_data: Dict[str, Any], log: Logger): log.info(f"delete item {item_id} from {table_name}") host = api_data["host"] port = api_data["port"] - token = api_data['token'] + token = api_data["token"] url = "" match table_name: case "media_file": @@ -125,14 +139,16 @@ def item_delete(table_name: str, item_id: str, api_data: Dict[str, Any], log: Lo url = f"http://{host}:{port}/api/media/actorfiles/{item_id}" case "media_actor": url = f"http://{host}:{port}/api/media/actors/{item_id}" + case "profile": + url = f"http://{host}:{port}/api/user/profile/{item_id}" headers: Dict[str, str] = {"Authorization": f"Bearer {token}"} response = requests.delete(url, headers=headers) log.debug(f"Status: {response.status_code}") -if __name__ == '__main__': +if __name__ == "__main__": logger = get_logger(args.verbose, "kontor") - logger.info('kontor.import started') + logger.info("kontor.import started") api_data = get_api_config(logger, args.config) engine = create_engine(DATABASE_URL) Base.metadata.create_all(bind=engine, checkfirst=True) @@ -151,7 +167,7 @@ if __name__ == '__main__': logger.debug(f"found {len(existing_items)} for table {tablename}") import_items: List[Dict[str, Any]] = data[tablename] for import_item in import_items: - item_id: str = import_item['id'] + item_id: str = import_item["id"] if item_id in existing_ids: logger.debug(f"update {item_id}") existing_item = db.get(model, item_id) @@ -166,11 +182,33 @@ if __name__ == '__main__': for item_id in existing_ids: match tablename: case "media_file": - item_delete(table_name=tablename, item_id=item_id, api_data=api_data, log=logger) + item_delete( + table_name=tablename, + item_id=item_id, + api_data=api_data, + log=logger, + ) case "media_actor_file": - item_delete(table_name=tablename, item_id=item_id, api_data=api_data, log=logger) + item_delete( + table_name=tablename, + item_id=item_id, + api_data=api_data, + log=logger, + ) case "media_actor": - item_delete(table_name=tablename, item_id=item_id, api_data=api_data, log=logger) + item_delete( + table_name=tablename, + item_id=item_id, + api_data=api_data, + log=logger, + ) + case "profile": + item_delete( + table_name=tablename, + item_id=item_id, + api_data=api_data, + log=logger + ) case _: logger.info("Method to remove remaining item not implemented") - logger.info('kontor.import finished') + logger.info("kontor.import finished") diff --git a/kontor-scripts/json_to_mariadb.py b/kontor-scripts/json_to_mariadb.py deleted file mode 100644 index db3916b..0000000 --- a/kontor-scripts/json_to_mariadb.py +++ /dev/null @@ -1,58 +0,0 @@ -""" -copy data from JSON to MariaDB -""" -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter -from pathlib import Path -from config import get_logger, get_database_cursors -import mariadb -import json - -parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('--verbose', '-v', action='count', default=0) -parser.add_argument('--config', '-c', default='kontor-docker') -parser.add_argument('--file', '-f', default='~/.sync/media/data.json') -args = parser.parse_args() - -def copy_data(mariadb_conn, data_file: Path, log): - mariadb_cursor = mariadb_conn.cursor() - import_file = Path(data_file) - if not import_file.exists(): - log.info(f"File {data_file} does not exist. Do nothing.") - return - log.info("read json file") - with open(data_file, 'r') as json_file: - json_load = json.load(json_file) - for table in json_load: - log.info(f"{table}: {len(json_load[table])}") - # result[table] = import_table(table, json_load[table]) - truncate_statement = 'TRUNCATE {}'.format(table) - #log.info(f"truncate: {truncate_statement}") - mariadb_cursor.execute("SET FOREIGN_KEY_CHECKS = 0") - mariadb_cursor.execute(truncate_statement) - items = json_load[table] - for item in items: - #log.info(f"item: {item}") - values = [] - columns = [] - for (key, value) in item.items(): - columns.append(key) - values.append(value) - row = tuple(values) - log.info(f"values: {row}") - insert_statement = 'INSERT INTO {}({}) VALUES({})'.format(table, ', '.join(columns), ', '.join(['?']*len(columns))) - #log.info(f"statement: {insert_statement}") - mariadb_cursor.execute(insert_statement, row) - try: - mariadb_conn.commit() - except mariadb.Error as error: - log.info('insert failed with %s', error) - - -if __name__ == '__main__': - logger = get_logger(args.verbose, args.config) - logger.info('kontor.json_to_mariadb started') - _, m_conn = get_database_cursors(logger, args.config) - copy_data(m_conn, args.file, logger) - m_conn.close() - logger.info('kontor.json_to_mariadb finished') - diff --git a/kontor-scripts/json_to_postgres.py b/kontor-scripts/json_to_postgres.py deleted file mode 100644 index 546597c..0000000 --- a/kontor-scripts/json_to_postgres.py +++ /dev/null @@ -1,152 +0,0 @@ -""" -copy data from JSON to Postgres -""" -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter -from pathlib import Path -from typing import Dict, List - -from config import get_logger, get_database_cursors -import json -from psycopg2.sql import SQL - -parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('--verbose', '-v', action='count', default=0) -parser.add_argument('--config', '-c', default='kontor-docker') -parser.add_argument('--file', '-f', default='~/.sync/media/data.json') -args = parser.parse_args() - -def copy_data(postgres_conn, data_file: Path, log): - postgres_cursor = postgres_conn.cursor() - import_file = Path(data_file) - if not import_file.exists(): - log.info(f"File {data_file} does not exist. Do nothing.") - return - log.info("read json file") - with open(data_file, 'r') as json_file: - json_load = json.load(json_file) - postgres_cursor.execute("SET session_replication_role='replica'") - for table in json_load: - log.info(f"{table}: {len(json_load[table])}") - # result[table] = import_table(table, json_load[table]) - truncate_statement = 'TRUNCATE {} CASCADE'.format(table) - #log.info(f"truncate: {truncate_statement}") - try: - postgres_cursor.execute(truncate_statement) - except: - log.info(f"statement: {insert_statement} FAILED") - items = json_load[table] - for item in items: - #log.info(f"item: {item}") - values = [] - columns = [] - for (key, value) in item.items(): - columns.append(key) - values.append(value) - row = tuple(values) - #log.info(f"values: {row}") - insert_statement = 'INSERT INTO {}({}) VALUES({})'.format(table, ', '.join(columns), ', '.join(['%s']*len(columns))) - #log.info(f"statement: {insert_statement}") - try: - postgres_cursor.execute(SQL(insert_statement), row) - postgres_conn.commit() - except: - log.info(f'insert failed with {insert_statement}') - postgres_cursor.execute("SET session_replication_role='origin'") - - -def load_json(data_file, log) -> dict: - import_file = Path(data_file) - if not import_file.exists(): - log.info(f"File {data_file} does not exist. Do nothing.") - return - log.info("read json file") - with open(data_file, 'r') as json_file: - json_load = json.load(json_file) - return json_load - - -def insert_data(postgres_conn, data: dict, log): - postgres_cursor = postgres_conn.cursor() - log.info("insert data") - table_list = [] - table_list = ['worktype', 'artist', 'publisher', 'volume', 'comic', 'issue', 'story_arc', 'trade_paperback', 'comic_work'] - table_list.extend(['sport', 'team', 'field_position', 'vendor', 'player', 'rooster', 'card_set', 'card']) - #table_list.extend(['card']) - table_list.extend(['media_file', 'media_video', 'media_actor', 'media_article', 'media_actor_file']) - #table_list.extend(['media_actor_file']) - table_list.extend(['profile', 'permission', 'token', 'assignment']) - table_list.extend(['mail', 'mail_account', 'module_data', 'meta_data_table', 'meta_data_column']) - table_list.extend(['meta_data_table', 'meta_data_column']) - table_list.extend(['book', 'author', 'article', 'bookshelf_publisher', 'book_author', 'article_author']) - #if len(table_list) != 37: - # log.info(f"number of tables incorrect: {len(table_list)}") - # return - for table in table_list: - log.info(f"{table}: {len(data[table])}") - truncate_statement = 'DELETE FROM {}'.format(table) - log.info(f"truncate: {truncate_statement}") - try: - postgres_cursor.execute(truncate_statement) - postgres_conn.commit() - except: - log.info(f"statement: {truncate_statement} FAILED") - items = data[table] - for item in items: - # log.info(f"item: {item}") - values = [] - columns = [] - for (key, value) in item.items(): - columns.append(key) - values.append(value) - row = tuple(values) - # log.info(f"values: {row}") - insert_statement = 'INSERT INTO {}({}) VALUES({})'.format(table, ', '.join(columns), - ', '.join(['%s'] * len(columns))) - # log.info(f"statement: {insert_statement}") - try: - postgres_cursor.execute(SQL(insert_statement), row) - postgres_conn.commit() - except: - log.info(f'insert failed with {insert_statement}') - - -def parse_table_order(data: dict, log): - log.info("parse_table_order") - table_refs: Dict[str, List[str]] = {} - for table in data: - log.info(f"{table}: {len(data[table])}") - items = data[table] - table_refs[table] = [] - if len(items) == 0: - continue - item = items[0] - for key, _ in item.items(): - if key.endswith('_id'): - ref = key[0:-3] - log.info(f"table {table} has reference to {ref}") - if table in table_refs: - table_refs[table].append(ref) - else: - table_refs[table] = [ref] - log.info(f"parsed refs: {table_refs}") - table_order = [] - for table in table_refs: - if len(table_refs[table]) == 0: - log.info(f"insert {table} at beginning") - table_order.insert(0, table) - else: - log.info(f"insert {table} at end") - table_order.append(table) - log.info(f"table_list: {len(table_order)}: {table_order}") - -if __name__ == '__main__': - logger = get_logger(args.verbose, args.config) - logger.info('kontor.json_to_postgres started') - _, _, p_conn = get_database_cursors(logger, args.config) - data = load_json(args.file, logger) - #parse_table_order(data, logger) - insert_data(p_conn, data, logger) - #copy_data(p_conn, args.file, logger) - p_conn.close() - logger.info('kontor.json_to_postgres finished') - diff --git a/kontor-scripts/kontor.py b/kontor-scripts/kontor.py deleted file mode 100644 index 217e15a..0000000 --- a/kontor-scripts/kontor.py +++ /dev/null @@ -1,64 +0,0 @@ -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter -from pathlib import Path - -import logging.config -import yaml -from platformdirs import PlatformDirs -from sqlalchemy import create_engine, select -from sqlalchemy.orm import sessionmaker - -from schema import Comic, Publisher, Base - -parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('--recreate-db', action='store_true') -parser.add_argument('--verbose', '-v', action='count', default=0) -parser.add_argument('--file', '-f', default='~/data.json') -parser.add_argument('--config', '-c', default='kontor-docker') -args = parser.parse_args() - - -def get_logger(level: int, config: str): - dirs = PlatformDirs(config) - logging_config = Path(dirs.user_config_dir, 'logging-config.yaml') - with open(logging_config, 'rt') as f: - configDict = yaml.safe_load(f.read()) - logging.config.dictConfig(configDict) - logger = logging.getLogger('development') - if level is not None: - match level: - case 0: - logger.setLevel(logging.INFO) - case 1: - logger.setLevel(logging.DEBUG) - case _: - logger.setLevel(logging.CRITICAL) - return logger - - -if __name__ == '__main__': - log = get_logger(args.verbose, args.config) - log.info('kontor started') - dirs = PlatformDirs(args.config) - database_config = Path(dirs.user_config_dir, 'database-config.yaml') - with open(database_config, 'rt') as f: - db_config = yaml.safe_load(f.read()) - print(db_config) - connect_string = ('mariadb+mariadbconnector://{}:{}@{}:{}/{}'.format( - db_config['mariadb']['user'], - db_config['mariadb']['password'], - db_config['mariadb']['host'], - db_config['mariadb']['port'], - db_config['mariadb']['database'] - )) - engine = create_engine(connect_string) - Base.metadata.create_all(bind=engine, checkfirst=True) - __session__ = sessionmaker(engine) - with __session__() as session: - comics = session.scalars(select(Comic)).all() - for comic in comics: - print(comic) - publishers = session.scalars(select(Publisher)).all() - for publisher in publishers: - print(publisher) - print(len(publisher.comics)) - log.info('kontor finished') diff --git a/kontor-scripts/log.py b/kontor-scripts/log.py new file mode 100644 index 0000000..81bdd65 --- /dev/null +++ b/kontor-scripts/log.py @@ -0,0 +1,52 @@ +import logging.config + +def get_logger(level: int, name: str) -> logging.Logger: + logging.config.dictConfig({ + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'simple': { + 'format': '[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s', + 'datefmt': '%Y-%m-%d %H:%M:%S', + }, + }, + 'handlers': { + 'console': { + 'class': logging.StreamHandler, + 'level': logging.DEBUG, + 'formatter': 'simple', + 'stream': 'ext://sys.stdout' + }, + }, + 'loggers': { + 'urllib3.connectionpool': { + 'level': 'WARNING', + 'propagate': False, + }, + 'root': { + 'level': 'DEBUG', + 'handlers': ['console'], + }, + }, + }) + logger = logging.getLogger(name) + if level is not None: + match level: + case 0: + logger.setLevel(logging.CRITICAL) + logging.getLogger("requests").setLevel(logging.WARNING) + logging.getLogger("urllib3").setLevel(logging.WARNING) + case 1: + logging.getLogger("requests").setLevel(logging.INFO) + logging.getLogger("urllib3").setLevel(logging.INFO) + logging.getLogger("stomp").setLevel(logging.INFO) + logger.setLevel(logging.INFO) + case 2: + logger.setLevel(logging.DEBUG) + logging.getLogger("requests").setLevel(logging.DEBUG) + logging.getLogger("urllib3").setLevel(logging.DEBUG) + case _: + logger.setLevel(logging.INFO) + logging.getLogger("requests").setLevel(logging.INFO) + logging.getLogger("urllib3").setLevel(logging.INFO) + return logger diff --git a/kontor-scripts/pyproject.toml b/kontor-scripts/pyproject.toml index ca0b9dd..e6ace1a 100644 --- a/kontor-scripts/pyproject.toml +++ b/kontor-scripts/pyproject.toml @@ -11,8 +11,11 @@ maintainers = [ ] dependencies = [ "beautifulsoup4>=4.13.4", + "click>=8.1.8", "coverage>=7.8.0", "fastapi[standard]>=0.115.12", + "kontor-model", + "msgspec[toml,yaml]>=0.21.1", "pathlib>=1.0.1", "platformdirs>=4.3.7", "proton>=0.9.1", @@ -21,7 +24,11 @@ dependencies = [ "python-qpid-proton>=0.40.0", "pyyaml>=6.0.2", "requests>=2.32.3", + "simple-term-menu>=1.6.6", "sqlalchemy>=2.0.40", "sqlmodel>=0.0.24", - "stomp.py", + "stomp-py", ] + +[tool.uv.sources] +kontor_model = { path = "../kontor-model", editable = true } diff --git a/kontor-scripts/read_list.py b/kontor-scripts/read_list.py deleted file mode 100644 index 4d5ba6e..0000000 --- a/kontor-scripts/read_list.py +++ /dev/null @@ -1,80 +0,0 @@ -""" -read file with URLs and store in DB -""" -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter -import logging -import json -from proton import Message, Event -from proton.handlers import MessagingHandler -from proton.reactor import Container - -parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) -parser.add_argument('-f', '--links', help='file with links') -parser.add_argument('--verbose', '-v', action='count', default=0) -args = parser.parse_args() - - -def read_links_file(links_file): - with open(links_file, 'r') as input_file: - lines = input_file.readlines() - return lines - - -class AddLinkMessage(MessagingHandler): - def __init__(self, server, url, log): - super(AddLinkMessage, self).__init__() - log.info("create AddLinkMessage") - self.server = server - self.address = "KontorMediaFile::add_link_file" - self.url = url - self.log = log - - def on_start(self, event: Event): - self.log.info("Connection...") - conn = event.container.connect(self.server, user="artemis", password="artemis") - event.container.create_sender(conn, self.address) - - def on_connection_opened(self, event: Event) -> None: - self.log.debug("connection open") - - def on_connection_error(self, event: Event) -> None: - self.log.info(f"error: {event}") - - def on_disconnected(self, event: Event) -> None: - self.log.debug(f"disconnected: {repr(event)}") - - - def on_sendable(self, event: Event): - self.log.info("send message") - message = Message(body=self.url, address=self.address, content_type="application/json", durable=True) - delivery = event.sender.send(message) - self.log.info(f"Delivery {delivery} sent") - event.connection.close() - - def on_accepted(self, event: Event) -> None: - self.log.info(f"accepted Delivery: {event.delivery.remote_state}") - - - def on_rejected(self, event: Event) -> None: - self.log.info(f"rejected Delivery: {event.delivery}") - -if __name__ == '__main__': - logging.basicConfig(level=logging.INFO, format='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s') - logging.info('kontor.read_list started') - #conn = stomp.Connection([('127.0.0.1', '61616')]) - #conn.connect('artemis', 'artemis', wait=True) - if args.links: - logging.info("read links from file") - links = read_links_file(args.links) - for link in links: - data_dict = {'url': link.strip()} - data = json.dumps(data_dict) - logging.info("send link message") - handler = AddLinkMessage("amqp://127.0.0.1:5672", data, logging) - container = Container(handler) - container.container_id = "process_add_links" - container.run() - # conn.send(body=data, destination='KontorMediaFile::add_link_file', headers={'content-type': 'application/json'}) - #conn.disconnect() - logging.info('kontor.read_list finished') - diff --git a/kontor-scripts/read_queue.py b/kontor-scripts/read_queue.py index 22dc8f6..f8e1a7b 100644 --- a/kontor-scripts/read_queue.py +++ b/kontor-scripts/read_queue.py @@ -1,37 +1,76 @@ import stomp -import json import time +import msgspec +import sys from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter -from config import get_logger +from typing import Optional +from api import Server, get_api_config +from log import get_logger + parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) parser.add_argument('--verbose', '-v', action='count', default=0) -parser.add_argument('--config', '-c', default='kontor-docker') +parser.add_argument("--config", "-c", default="kontor-api") +parser.add_argument("--server", "-s") +parser.add_argument("--messages", "-m", default="127.0.0.1") +parser.add_argument("--port", "-p", default="61616") args = parser.parse_args() -class MyListener(stomp.ConnectionListener): - def __init__(self, log): + +class Link(msgspec.Struct): + url: str + +class AddLinkListener(stomp.ConnectionListener): + def __init__(self, log, conn): self.log = log + self.conn = conn def on_error(self, frame): - self.log.info(f"received an error {frame.body}") + self.log.info("received an error %s", frame.body) def on_message(self, frame): - self.log.info(f"received a message '{frame.body}'") - data = json.loads(frame.body) - url = data['url'] - self.log.info(f"found link: {url}") + self.log.info("received a message %s", frame.body) + link = msgspec.json.decode(frame.body, type=Link) + self.log.info("found link: %s", link.url) + json_bytes = msgspec.json.encode(link) + self.conn.send(body=json_bytes, destination="media.link.add.processed") + self.conn.send(body=json_bytes, destination="media.link.update_title") + +class UpdateTitleListener(stomp.ConnectionListener): + def __init__(self, log, conn): + self.log = log + self.conn = conn + + def on_error(self, frame): + self.log.info("received an error %s", frame.body) + + def on_message(self, frame): + self.log.info("received a message %s", frame.body) + link = msgspec.json.decode(frame.body, type=Link) + self.log.info("found link: %s", link.url) + json_bytes = msgspec.json.encode(link) + self.conn.send(body=json_bytes, destination="media.link.update_title.processed") if __name__ == '__main__': - log = get_logger(args.verbose, args.config) - log.info("kontor.read_queue started") - host = [('127.0.0.1', 61616)] - conn = stomp.Connection(host_and_ports=host) - conn.set_listener('', MyListener(log)) - conn.connect(username='artemis', passcode='artemis', wait=True) - conn.subscribe(destination='KontorMediaFile::add_link_file', id=1, ack='auto', headers={}) - time.sleep(5) - conn.disconnect() - log.info("kontor.read_queue finished") + logger = get_logger(args.verbose, __file__) + logger.info("kontor.read_queue started") + #APICONFIG = get_api_config(logger, args.config) + #first_server: Optional[Server] = APICONFIG.get_server("inky") + #if not first_server: + # sys.exit(2) + #data = first_server.request(log=logger, table="media_file") + host = [(args.messages, args.port)] + conn_add = stomp.Connection(host_and_ports=host) + conn_add.set_listener('', AddLinkListener(logger, conn_add)) + conn_add.connect(username='artemis', passcode='artemis', wait=True) + conn_add.subscribe(destination='media.link', id=1, ack='auto', headers={}) + conn_update = stomp.Connection(host_and_ports=host) + conn_update.set_listener('', UpdateTitleListener(logger, conn_update)) + conn_update.connect(username='artemis', passcode='artemis', wait=True) + conn_update.subscribe(destination='media.link.update_title', id=1, ack='auto', headers={}) + time.sleep(5) + conn_add.disconnect() + conn_update.disconnect() + logger.info("kontor.read_queue finished") diff --git a/kontor-scripts/requirements.txt b/kontor-scripts/requirements.txt deleted file mode 100644 index 30839c8..0000000 --- a/kontor-scripts/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -sqlalchemy -pathlib -platformdirs -pyyaml -beautifulsoup4 -sqlmodel -requests -fastapi[standard] - diff --git a/kontor-scripts/sync.py b/kontor-scripts/sync.py new file mode 100644 index 0000000..0b91e86 --- /dev/null +++ b/kontor-scripts/sync.py @@ -0,0 +1,126 @@ +""" +Synchronize Kontor data between configured servers. +""" + +import json +from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser +from logging import Logger +from typing import Dict, List + +from api import ( + MAPPING, + EndPointNotAvailableException, + Server, + get_api_config +) +from log import get_logger + +parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) +parser.add_argument("--verbose", "-v", action="count", default=0) +parser.add_argument("--config", "-c", default="kontor-api") +parser.add_argument("--dry-run", "-m", action="store_true") +parser.add_argument("--to-file", "-f", action="store_true") +parser.add_argument("--server", "-s") +parser.add_argument("--cleanup", "-d", action="store_true") +args = parser.parse_args() + + +def create_item_id_mapping(log: Logger, data_list: List[dict]) -> Dict[str, dict]: + """ + create dictionary with id as key and dictionary as value. + """ + item_id_mapping: Dict[str, dict] = {} + for data_item in data_list: + log.debug(data_item) + item_id_mapping[data_item["id"]] = data_item + return item_id_mapping + + +def is_different(log: Logger, first_item, second_item: dict) -> bool: + """ + Check dicts for differences and returns true if values are not equals, except for last_modified_date. + """ + check_result = False + for key, value in first_item.items(): + if key in second_item.keys(): + if value != second_item[key]: + log.info("%s: %s != %s", key, value, second_item[key]) + if key == "last_modified_date": + continue + if not check_result: + check_result = True + return check_result + + +if __name__ == "__main__": + logger = get_logger(args.verbose, "kontor") + logger.info("kontor.sync started") + APICONFIG = get_api_config(logger, args.config) + server_list: List[Server] = [] + if args.server: + server = APICONFIG.get_server(args.server) + if server: + server_list.append(server) + else: + server_list.extend(APICONFIG.server) + export_data = {} + for server in server_list: + export_data[server.name] = {} + for table, path in MAPPING.items(): + try: + data = server.request(logger, table=table) + logger.info("%s: %s", table, len(data)) + export_data[server.name][table] = data + logger.info("%s: %s exported", table, len(data)) + except EndPointNotAvailableException: + logger.info("Endpoint not implemented") + if args.to_file: + try: + json_dump = json.dumps(export_data[server.name], indent=4) + file_name = f"{server.name}-data.json" + with open(file_name, "w", encoding="utf-8") as dump_file: + dump_file.write(json_dump) + except TypeError as error: + logger.info(error) + for server in server_list: + logger.info( + "%s: %s tables exported", server.name, len(export_data[server.name]) + ) + if len(server_list) > 1: + for table, path in MAPPING.items(): + mapping = create_item_id_mapping( + logger, export_data[server_list[1].name][table] + ) + for item in export_data[server_list[0].name][table]: + logger.debug("checking %s:%s", table, item["id"]) + check_item_id = item["id"] + if check_item_id in mapping: + check_item = mapping[check_item_id] + if is_different(logger, item, check_item): + logger.info( + "checking values for %s != %s", item["id"], check_item["id"] + ) + logger.debug("diff: %s\n%s", item, check_item) + if not args.dry_run: + result = server_list[1].update( + logger, table, check_item_id, item + ) + logger.info("update result: %s", result) + else: + logger.debug( + "no changes for: %s(%s - %s)", + table, + item["id"], + check_item["id"], + ) + else: + logger.info( + "item %s in %s missing: ", check_item_id, server_list[1].name + ) + if not args.dry_run: + server_list[1].create(logger, table, item) + logger.info("synchronization of %s finished", table) + logger.info("all tables synchronized") + else: + logger.info("not enough server configured for sync") + logger.info("kontor.sync finished") diff --git a/kontor-scripts/update_title.py b/kontor-scripts/update_title.py index 720510b..a55ab8b 100644 --- a/kontor-scripts/update_title.py +++ b/kontor-scripts/update_title.py @@ -2,19 +2,35 @@ download files with URLs from DB """ import logging.config +import os +import re +from typing import Any, Dict, List import requests +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker, Session +from kontor_model.db.models.base import Base import yaml from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter from pathlib import Path from bs4 import BeautifulSoup from platformdirs import PlatformDirs +from config import get_api_config +from kontor_model.db.models.media import MediaFile parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) parser.add_argument('--verbose', '-v', action='count', default=0) parser.add_argument('--config', '-c', default='kontor-docker') +parser.add_argument('--dry-run', '-m', help='excute script without storing', action="store_true") args = parser.parse_args() +DB_USER: str = os.getenv("DB_USER", "kontor") +DB_PASSWORD: str = os.getenv("DB_PASSWORD", "kontor") +DB_SERVER: str = os.getenv("DB_SERVER", "127.0.0.1") +DB_PORT: int = int(os.getenv("DB_PORT", 5432)) +DB_DBNAME: str = os.getenv("DB_DBNAME", "kontor") +DATABASE_URL: str = f"postgresql://{DB_USER}:{DB_PASSWORD}@{DB_SERVER}:{DB_PORT}/{DB_DBNAME}" + def get_logger(level: int, config: str): dirs = PlatformDirs(config) logging_config = Path(dirs.user_config_dir, 'logging-config.yaml') @@ -32,37 +48,96 @@ def get_logger(level: int, config: str): logger.setLevel(logging.CRITICAL) return logger +def get_session() -> Session: + engine = create_engine(DATABASE_URL) + Base.metadata.create_all(bind=engine, checkfirst=True) + SessionLocal = sessionmaker(bind=engine) + return SessionLocal() + +def get_media_files(all_files: bool, log: logging.Logger, api_data: Dict[str, Any])-> Any: + files_url = "" + host = api_data["host"] + port = api_data["port"] + token = api_data['token'] + headers: Dict[str, str] = {"Authorization": f"Bearer {token}"} + if all_files: + files_url= f"http://{host}:{port}/api/media/files" + else: + files_url = f"http://{host}:{port}/api/media/files?review=true" + response = requests.get(files_url, headers=headers) + log.debug(f"Status: {response.status_code}") + data = response.json() + return data + +def update_media_file(media_file: MediaFile, log: logging.Logger, api_data: Dict[str, Any]) -> Any: + host = api_data["host"] + port = api_data["port"] + token = api_data['token'] + url: str = f"http://{host}:{port}/api/media/files/{media_file.id}" + headers: Dict[str, str] = {"Authorization": f"Bearer {token}"} + item: Dict[str, Any] = {} + item['id'] = media_file.id + item['title'] = media_file.title + item['file_name'] = media_file.file_name + item['cloud_link'] = media_file.cloud_link + item['url'] = media_file.url + item['review'] = media_file.review + item['should_download'] = media_file.should_download + update = requests.put(url, headers=headers, json=item) + log.debug(f"update status: {update.status_code}") + log.debug(f"update result: {update.json()}") + return update.json() + +def get_meta_info(media_file: MediaFile, log) -> List[str]: + actor_links: List[str] = [] + try: + r = requests.get(media_file.url) + soup = BeautifulSoup(r.content, "html.parser") + error404 = soup.css.select_one('.error404-title') + if error404 and error404.get_text() == "Video nicht gefunden": + log.warning(f"{error404.get_text()}") + media_file.url = None + media_file.review = False + return actor_links + title_tag = soup.find('title') + if title_tag: + media_file.title = title_tag.get_text() + media_file.review = False + anchors = soup.find_all('a', attrs={'href': re.compile("^https://.*pornstars/.*")}) + for anchor in anchors: + link_url = str(anchor.get("href")) # type: ignore + if link_url.endswith('all/countries'): + continue + if link_url in actor_links: + continue + actor_links.append(link_url) + except Exception as error: + log.info(f"something went wrong: {error}") + media_file.title = None + media_file.review = True + log.info(f"update MediaFile with MetaInfos to {repr(media_file)}") + log.info(f"links({len(actor_links)}): {actor_links}") + return actor_links + if __name__ == '__main__': log = get_logger(args.verbose, args.config) log.info('kontor.update_titles started') - response = requests.get("http://127.0.0.1:8800/api/media/files?review=true") - log.info(f"Status: {response.status_code}") - data = response.json() + api_data = get_api_config(log, args.config) + data = get_media_files(False, log, api_data=api_data) log.info(f"data: {len(data)}") - for item in data: - link = item['url'] - log.info(f"{item['id']} - {str(link)}") - if not link: - continue - if link == "None": - item['url'] = None - else: - try: - r = requests.get(link) - soup = BeautifulSoup(r.content, "html.parser") - title_tag = soup.find('title') - if title_tag: - title= title_tag.get_text() - title = soup.title.string - item['title'] = title - item['review'] = False - except Exception as error: - log.info(f"something went wrong: {error}") - item['title'] = None - item['review'] = True - update = requests.put(f"http://127.0.0.1:8800/api/media/files/{item['id']}", json=item) - log.info(f"update status: {update.status_code}") - log.info(f"update result: {update.json()}") + session = get_session() + with session as db: + media_files = db.query(MediaFile).filter(MediaFile.review).all() + for media_file in media_files: + link = media_file.url + log.info(f"{media_file.id} - {str(link)}") + if not link: + continue + if link == "None": + media_file.url = None + else: + get_meta_info(media_file, log) + if not args.dry_run: + update_media_file(media_file, log, api_data=api_data) log.info('kontor.update_titles finished') - diff --git a/kontor-scripts/uv.lock b/kontor-scripts/uv.lock index 46d69c1..cf8b732 100644 --- a/kontor-scripts/uv.lock +++ b/kontor-scripts/uv.lock @@ -318,14 +318,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload_time = "2025-03-05T20:05:00.369Z" }, ] +[[package]] +name = "kontor-model" +version = "0.3.0" +source = { editable = "../kontor-model" } +dependencies = [ + { name = "msgspec", extra = ["toml", "yaml"] }, + { name = "pydantic", extra = ["email"] }, + { name = "sqlalchemy" }, +] + +[package.metadata] +requires-dist = [ + { name = "msgspec", extras = ["toml", "yaml"], specifier = ">=0.21.1" }, + { name = "pydantic", extras = ["email"], specifier = ">=2.13.4" }, + { name = "sqlalchemy", specifier = ">=2.0.52" }, +] + [[package]] name = "kontor-scripts" version = "0.1.0" source = { virtual = "." } dependencies = [ { name = "beautifulsoup4" }, + { name = "click" }, { name = "coverage" }, { name = "fastapi", extra = ["standard"] }, + { name = "kontor-model" }, + { name = "msgspec", extra = ["toml", "yaml"] }, { name = "pathlib" }, { name = "platformdirs" }, { name = "proton" }, @@ -334,6 +354,7 @@ dependencies = [ { name = "python-qpid-proton" }, { name = "pyyaml" }, { name = "requests" }, + { name = "simple-term-menu" }, { name = "sqlalchemy" }, { name = "sqlmodel" }, { name = "stomp-py" }, @@ -342,8 +363,11 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "beautifulsoup4", specifier = ">=4.13.4" }, + { name = "click", specifier = ">=8.1.8" }, { name = "coverage", specifier = ">=7.8.0" }, { name = "fastapi", extras = ["standard"], specifier = ">=0.115.12" }, + { name = "kontor-model", editable = "../kontor-model" }, + { name = "msgspec", extras = ["toml", "yaml"], specifier = ">=0.21.1" }, { name = "pathlib", specifier = ">=1.0.1" }, { name = "platformdirs", specifier = ">=4.3.7" }, { name = "proton", specifier = ">=0.9.1" }, @@ -352,6 +376,7 @@ requires-dist = [ { name = "python-qpid-proton", specifier = ">=0.40.0" }, { name = "pyyaml", specifier = ">=6.0.2" }, { name = "requests", specifier = ">=2.32.3" }, + { name = "simple-term-menu", specifier = ">=1.6.6" }, { name = "sqlalchemy", specifier = ">=2.0.40" }, { name = "sqlmodel", specifier = ">=0.0.24" }, { name = "stomp-py" }, @@ -406,6 +431,46 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload_time = "2022-08-14T12:40:09.779Z" }, ] +[[package]] +name = "msgspec" +version = "0.21.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/60/f79b9b013a16fa3a58350c9295ddc6789f2e335f36ea61ed10a21b215364/msgspec-0.21.1.tar.gz", hash = "sha256:2313508e394b0d208f8f56892ca9b2799e2561329de9763b19619595a6c0f72c", size = 319193, upload_time = "2026-04-12T21:44:50.394Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/74/f11ede02839b19ff459f88e3145df5d711626ca84da4e23520cebf819367/msgspec-0.21.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:764173717a01743f007e9f74520ed281f24672c604514f7d76c1c3a10e8edb66", size = 196176, upload_time = "2026-04-12T21:44:17.613Z" }, + { url = "https://files.pythonhosted.org/packages/bb/40/4476c1bd341418a046c4955aff632ec769315d1e3cb94e6acf86d461f9ed/msgspec-0.21.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:344c7cd0eaed1fb81d7959f99100ef71ec9b536881a376f11b9a6c4803365697", size = 188524, upload_time = "2026-04-12T21:44:18.815Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d9/9e9d7d7e5061b47540d03d640fab9b3965ba7ae49c1b2154861c8f007518/msgspec-0.21.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48943e278b3854c2f89f955ddc6f9f430d3f0784b16e47d10604ee0463cd21f5", size = 218880, upload_time = "2026-04-12T21:44:20.028Z" }, + { url = "https://files.pythonhosted.org/packages/74/66/2bb344f34abb4b57e60c7c9c761994e0417b9718ec1460bf00c296f2a7ea/msgspec-0.21.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9aa659ebb0101b1cbc31461212b87e341d961f0ab0772aaf068a99e001ec4aa", size = 225050, upload_time = "2026-04-12T21:44:21.577Z" }, + { url = "https://files.pythonhosted.org/packages/1a/84/7c1e412f76092277bf760cef12b7979d03314d259ab5b5cafde5d0c1722d/msgspec-0.21.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7b27d1a8ead2b6f5b0c4f2d07b8be1ccfcc041c8a0e704781edebe3ae13c484", size = 222713, upload_time = "2026-04-12T21:44:22.83Z" }, + { url = "https://files.pythonhosted.org/packages/4e/27/0bba04b2b4ef05f3d068429410bc71d2cea925f1596a8f41152cccd5edb8/msgspec-0.21.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38fe93e86b61328fe544cb7fd871fad5a27c8734bfda90f65e5dbe288ae50f61", size = 227259, upload_time = "2026-04-12T21:44:24.11Z" }, + { url = "https://files.pythonhosted.org/packages/b0/2d/09574b0eea02fed2c2c1383dbaae2c7f79dc16dcd6487a886000afb5d7c4/msgspec-0.21.1-cp313-cp313-win_amd64.whl", hash = "sha256:8bc666331c35fcce05a7cd2d6221adbe0f6058f8e750711413d22793c080ac6a", size = 189857, upload_time = "2026-04-12T21:44:25.359Z" }, + { url = "https://files.pythonhosted.org/packages/46/34/105b1576ad182879914f0c821f17ee1d13abb165cb060448f96fe2aff078/msgspec-0.21.1-cp313-cp313-win_arm64.whl", hash = "sha256:42bb1241e0750c1a4346f2aa84db26c5ffd99a4eb3a954927d9f149ff2f42898", size = 175403, upload_time = "2026-04-12T21:44:26.608Z" }, + { url = "https://files.pythonhosted.org/packages/5a/ad/86954e987d1d6a5c579e2c2e7832b65e0fff194179fdac4f581536086024/msgspec-0.21.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fab48eb45fdbfbdb2c0edfec00ffc53b6b6085beefc6b50b61e01659f9f8757f", size = 196261, upload_time = "2026-04-12T21:44:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a1/c5e46c3e42b866199365e35d11dddfd1fbd8bba4fdb3c52f965b1607ce94/msgspec-0.21.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3cb779ea0c35bc807ff941d415875c1f69ca0be91a2e907ab99a171811d86a9a", size = 188729, upload_time = "2026-04-12T21:44:28.99Z" }, + { url = "https://files.pythonhosted.org/packages/85/7d/1e29a319d678d6cb962ae5bdf32a6858ebdf38f73bc654c0e9c742a0c2c8/msgspec-0.21.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68604db36b3b4dd9bf160e436e12798a4738848144cea1aca1cb984011eb160f", size = 219866, upload_time = "2026-04-12T21:44:31.104Z" }, + { url = "https://files.pythonhosted.org/packages/25/1f/cca084ca2572810fff12ea9dbdcbe39eac048f40daf4a9077b49fcbe8cee/msgspec-0.21.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3d6b9dc50948eaf65df54d2fd0ff66e6d8c32f116037209ee861810eb9b676cb", size = 224993, upload_time = "2026-04-12T21:44:32.649Z" }, + { url = "https://files.pythonhosted.org/packages/71/94/d2120fc9d419a89a3a7c13e5b7078798c4b392a96a02a6e2b3ce43a8766c/msgspec-0.21.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:52c5e21930942302394429c5a582ce7e6b62c7f983b3760834c2ce107e0dd6df", size = 223535, upload_time = "2026-04-12T21:44:33.839Z" }, + { url = "https://files.pythonhosted.org/packages/75/17/42418b66a3ad972a89bab73dd78b79cc6282bb488a25e73c853cee7443b9/msgspec-0.21.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:abbb39d65681fa24ed394e01af3d59d869068324f900c61d06062b7fb9980f2f", size = 227222, upload_time = "2026-04-12T21:44:35.093Z" }, + { url = "https://files.pythonhosted.org/packages/c4/33/265c894268cca88ff67b144ca2b4c522fc8b9a6f1966a3640c70516e78e1/msgspec-0.21.1-cp314-cp314-win_amd64.whl", hash = "sha256:5666b1b560b97b6ec2eb3fca8a502298ebac56e13bbca1f88523538ce83d01ea", size = 193810, upload_time = "2026-04-12T21:44:36.612Z" }, + { url = "https://files.pythonhosted.org/packages/3b/8f/a6d35f25bf1fc63c492fdd88fdce01ba0875ead48c2b91f90f33653b4131/msgspec-0.21.1-cp314-cp314-win_arm64.whl", hash = "sha256:d8b8578e4c83b14ceea4cef0d0b747e31d9330fe4b03b2b2ad4063866a178f93", size = 179125, upload_time = "2026-04-12T21:44:38.198Z" }, + { url = "https://files.pythonhosted.org/packages/c6/39/74839641e64b99d87da55af0fc472854d42b46e2183b9e2a67fe1bb2a512/msgspec-0.21.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:15f523d51c00ebad412213bfe9f06f0a50ec2b93e0c19e824a2d267cabb48ea2", size = 200171, upload_time = "2026-04-12T21:44:39.414Z" }, + { url = "https://files.pythonhosted.org/packages/70/9b/ce0cca6d2d87fcd4b6ff97600790494e64f26a2c55d61507cd2755c16193/msgspec-0.21.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4e47390360583ba3d5c6cb44cf0a9f61b0a06a899d3c2c00627cedebb2e2884b", size = 192879, upload_time = "2026-04-12T21:44:40.882Z" }, + { url = "https://files.pythonhosted.org/packages/a7/08/673a7bb05e5702dc787ddd3011195b509f9867927970da59052211929987/msgspec-0.21.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f60800e6299b798142dc40b0644da77ceac5ea0568be58228417eae14135c847", size = 226281, upload_time = "2026-04-12T21:44:42.181Z" }, + { url = "https://files.pythonhosted.org/packages/7d/45/86508cf57283e9070b3c447e3ab25b792a7a0855a3ea4e0c6d111ac34c97/msgspec-0.21.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5f8e9dfcd98419cf7568808470c4317a3fb30bef0e3715b568730a2b272a20d7", size = 229863, upload_time = "2026-04-12T21:44:43.442Z" }, + { url = "https://files.pythonhosted.org/packages/2c/62/e7c9367cd08d590559faacd711edbae36840342843e669440363f33c7d36/msgspec-0.21.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:92d89dfad13bd1ea640dc3e37e724ed380da1030b272bdf5ecafb983c3ad7c75", size = 230445, upload_time = "2026-04-12T21:44:44.806Z" }, + { url = "https://files.pythonhosted.org/packages/42/b4/c0f54632103846b658a10930025f4de41c8724b5e4805a5f3b395586cb7e/msgspec-0.21.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0d03867786e5d7ba25d666df4b11320c27170f4aeafcb8e3a8b0a50a4fb742ca", size = 231822, upload_time = "2026-04-12T21:44:46.343Z" }, + { url = "https://files.pythonhosted.org/packages/ea/1d/0d85cc79d0ccf5508e9c846cc66552a6a16bf92abd1dbd8362617f7b35cd/msgspec-0.21.1-cp314-cp314t-win_amd64.whl", hash = "sha256:740fbf1c9d59992ca3537d6fbe9ebbf9eaf726a65fbf31448e0ecbc710697a63", size = 206650, upload_time = "2026-04-12T21:44:47.601Z" }, + { url = "https://files.pythonhosted.org/packages/90/91/56c5d560f20e6c20e9e4f55bd0e458f7f162aa689ee350346c04c48eac0b/msgspec-0.21.1-cp314-cp314t-win_arm64.whl", hash = "sha256:0d2cc73df6058d811a126ac3a8ad63a4dfa210c82f9cf5a004802eaf4712de90", size = 183149, upload_time = "2026-04-12T21:44:48.833Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli-w" }, +] +yaml = [ + { name = "pyyaml" }, +] + [[package]] name = "packaging" version = "25.0" @@ -478,7 +543,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.11.3" +version = "2.13.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -486,37 +551,70 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/10/2e/ca897f093ee6c5f3b0bee123ee4465c50e75431c3d5b6a3b44a47134e891/pydantic-2.11.3.tar.gz", hash = "sha256:7471657138c16adad9322fe3070c0116dd6c3ad8d649300e3cbdfe91f4db4ec3", size = 785513, upload_time = "2025-04-08T13:27:06.399Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload_time = "2026-05-06T13:43:05.343Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/1d/407b29780a289868ed696d1616f4aad49d6388e5a77f567dcd2629dcd7b8/pydantic-2.11.3-py3-none-any.whl", hash = "sha256:a082753436a07f9ba1289c6ffa01cd93db3548776088aa917cc43b63f68fa60f", size = 443591, upload_time = "2025-04-08T13:27:03.789Z" }, + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload_time = "2026-05-06T13:43:02.641Z" }, +] + +[package.optional-dependencies] +email = [ + { name = "email-validator" }, ] [[package]] name = "pydantic-core" -version = "2.33.1" +version = "2.46.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/17/19/ed6a078a5287aea7922de6841ef4c06157931622c89c2a47940837b5eecd/pydantic_core-2.33.1.tar.gz", hash = "sha256:bcc9c6fdb0ced789245b02b7d6603e17d1563064ddcfc36f046b61c0c05dd9df", size = 434395, upload_time = "2025-04-02T09:49:41.8Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload_time = "2026-05-06T13:37:06.98Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/24/eed3466a4308d79155f1cdd5c7432c80ddcc4530ba8623b79d5ced021641/pydantic_core-2.33.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:70af6a21237b53d1fe7b9325b20e65cbf2f0a848cf77bed492b029139701e66a", size = 2033551, upload_time = "2025-04-02T09:47:51.648Z" }, - { url = "https://files.pythonhosted.org/packages/ab/14/df54b1a0bc9b6ded9b758b73139d2c11b4e8eb43e8ab9c5847c0a2913ada/pydantic_core-2.33.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:282b3fe1bbbe5ae35224a0dbd05aed9ccabccd241e8e6b60370484234b456266", size = 1852785, upload_time = "2025-04-02T09:47:53.149Z" }, - { url = "https://files.pythonhosted.org/packages/fa/96/e275f15ff3d34bb04b0125d9bc8848bf69f25d784d92a63676112451bfb9/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b315e596282bbb5822d0c7ee9d255595bd7506d1cb20c2911a4da0b970187d3", size = 1897758, upload_time = "2025-04-02T09:47:55.006Z" }, - { url = "https://files.pythonhosted.org/packages/b7/d8/96bc536e975b69e3a924b507d2a19aedbf50b24e08c80fb00e35f9baaed8/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dfae24cf9921875ca0ca6a8ecb4bb2f13c855794ed0d468d6abbec6e6dcd44a", size = 1986109, upload_time = "2025-04-02T09:47:56.532Z" }, - { url = "https://files.pythonhosted.org/packages/90/72/ab58e43ce7e900b88cb571ed057b2fcd0e95b708a2e0bed475b10130393e/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6dd8ecfde08d8bfadaea669e83c63939af76f4cf5538a72597016edfa3fad516", size = 2129159, upload_time = "2025-04-02T09:47:58.088Z" }, - { url = "https://files.pythonhosted.org/packages/dc/3f/52d85781406886c6870ac995ec0ba7ccc028b530b0798c9080531b409fdb/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f593494876eae852dc98c43c6f260f45abdbfeec9e4324e31a481d948214764", size = 2680222, upload_time = "2025-04-02T09:47:59.591Z" }, - { url = "https://files.pythonhosted.org/packages/f4/56/6e2ef42f363a0eec0fd92f74a91e0ac48cd2e49b695aac1509ad81eee86a/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:948b73114f47fd7016088e5186d13faf5e1b2fe83f5e320e371f035557fd264d", size = 2006980, upload_time = "2025-04-02T09:48:01.397Z" }, - { url = "https://files.pythonhosted.org/packages/4c/c0/604536c4379cc78359f9ee0aa319f4aedf6b652ec2854953f5a14fc38c5a/pydantic_core-2.33.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e11f3864eb516af21b01e25fac915a82e9ddad3bb0fb9e95a246067398b435a4", size = 2120840, upload_time = "2025-04-02T09:48:03.056Z" }, - { url = "https://files.pythonhosted.org/packages/1f/46/9eb764814f508f0edfb291a0f75d10854d78113fa13900ce13729aaec3ae/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:549150be302428b56fdad0c23c2741dcdb5572413776826c965619a25d9c6bde", size = 2072518, upload_time = "2025-04-02T09:48:04.662Z" }, - { url = "https://files.pythonhosted.org/packages/42/e3/fb6b2a732b82d1666fa6bf53e3627867ea3131c5f39f98ce92141e3e3dc1/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:495bc156026efafd9ef2d82372bd38afce78ddd82bf28ef5276c469e57c0c83e", size = 2248025, upload_time = "2025-04-02T09:48:06.226Z" }, - { url = "https://files.pythonhosted.org/packages/5c/9d/fbe8fe9d1aa4dac88723f10a921bc7418bd3378a567cb5e21193a3c48b43/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ec79de2a8680b1a67a07490bddf9636d5c2fab609ba8c57597e855fa5fa4dacd", size = 2254991, upload_time = "2025-04-02T09:48:08.114Z" }, - { url = "https://files.pythonhosted.org/packages/aa/99/07e2237b8a66438d9b26482332cda99a9acccb58d284af7bc7c946a42fd3/pydantic_core-2.33.1-cp313-cp313-win32.whl", hash = "sha256:ee12a7be1742f81b8a65b36c6921022301d466b82d80315d215c4c691724986f", size = 1915262, upload_time = "2025-04-02T09:48:09.708Z" }, - { url = "https://files.pythonhosted.org/packages/8a/f4/e457a7849beeed1e5defbcf5051c6f7b3c91a0624dd31543a64fc9adcf52/pydantic_core-2.33.1-cp313-cp313-win_amd64.whl", hash = "sha256:ede9b407e39949d2afc46385ce6bd6e11588660c26f80576c11c958e6647bc40", size = 1956626, upload_time = "2025-04-02T09:48:11.288Z" }, - { url = "https://files.pythonhosted.org/packages/20/d0/e8d567a7cff7b04e017ae164d98011f1e1894269fe8e90ea187a3cbfb562/pydantic_core-2.33.1-cp313-cp313-win_arm64.whl", hash = "sha256:aa687a23d4b7871a00e03ca96a09cad0f28f443690d300500603bd0adba4b523", size = 1909590, upload_time = "2025-04-02T09:48:12.861Z" }, - { url = "https://files.pythonhosted.org/packages/ef/fd/24ea4302d7a527d672c5be06e17df16aabfb4e9fdc6e0b345c21580f3d2a/pydantic_core-2.33.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:401d7b76e1000d0dd5538e6381d28febdcacb097c8d340dde7d7fc6e13e9f95d", size = 1812963, upload_time = "2025-04-02T09:48:14.553Z" }, - { url = "https://files.pythonhosted.org/packages/5f/95/4fbc2ecdeb5c1c53f1175a32d870250194eb2fdf6291b795ab08c8646d5d/pydantic_core-2.33.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aeb055a42d734c0255c9e489ac67e75397d59c6fbe60d155851e9782f276a9c", size = 1986896, upload_time = "2025-04-02T09:48:16.222Z" }, - { url = "https://files.pythonhosted.org/packages/71/ae/fe31e7f4a62431222d8f65a3bd02e3fa7e6026d154a00818e6d30520ea77/pydantic_core-2.33.1-cp313-cp313t-win_amd64.whl", hash = "sha256:338ea9b73e6e109f15ab439e62cb3b78aa752c7fd9536794112e14bee02c8d18", size = 1931810, upload_time = "2025-04-02T09:48:17.97Z" }, + { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload_time = "2026-05-06T13:37:48.029Z" }, + { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload_time = "2026-05-06T13:37:17.012Z" }, + { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload_time = "2026-05-06T13:37:35.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload_time = "2026-05-06T13:37:12.313Z" }, + { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload_time = "2026-05-06T13:39:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload_time = "2026-05-06T13:37:41.406Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload_time = "2026-05-06T13:39:18.847Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload_time = "2026-05-06T13:40:17.944Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload_time = "2026-05-06T13:40:32.618Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload_time = "2026-05-06T13:36:51.018Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload_time = "2026-05-06T13:40:37.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload_time = "2026-05-06T13:39:34.152Z" }, + { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload_time = "2026-05-06T13:37:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload_time = "2026-05-06T13:38:49.139Z" }, + { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload_time = "2026-05-06T13:40:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload_time = "2026-05-06T13:38:41.019Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload_time = "2026-05-06T13:36:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload_time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload_time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload_time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload_time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload_time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload_time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload_time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload_time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload_time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload_time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload_time = "2026-05-06T13:38:03.499Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload_time = "2026-05-06T13:39:40.807Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload_time = "2026-05-06T13:37:26.72Z" }, + { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload_time = "2026-05-06T13:39:47.682Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload_time = "2026-05-06T13:40:40.428Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload_time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload_time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload_time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload_time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload_time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload_time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload_time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload_time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload_time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload_time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload_time = "2026-05-06T13:38:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload_time = "2026-05-06T13:38:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload_time = "2026-05-06T13:40:52.723Z" }, ] [[package]] @@ -654,6 +752,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload_time = "2023-10-24T04:13:38.866Z" }, ] +[[package]] +name = "simple-term-menu" +version = "1.6.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/80/f0f10b4045628645a841d3d98b584a8699005ee03a211fc7c45f6c6f0e99/simple_term_menu-1.6.6.tar.gz", hash = "sha256:9813d36f5749d62d200a5599b1ec88469c71378312adc084c00c00bfbb383893", size = 35493, upload_time = "2024-12-02T16:31:50.639Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/09/21d993e394c1fe5c44cd90453d88ed44932da8dfca006e424c072d77d29b/simple_term_menu-1.6.6-py3-none-any.whl", hash = "sha256:c2a869efa7a9f7e4a9c25858b42ca6974034951c137d5e281f5339b06ed8c9c2", size = 27600, upload_time = "2024-12-02T16:31:48.934Z" }, +] + [[package]] name = "sniffio" version = "1.3.1" @@ -674,23 +781,30 @@ wheels = [ [[package]] name = "sqlalchemy" -version = "2.0.40" +version = "2.0.52" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" }, + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/68/c3/3f2bfa5e4dcd9938405fe2fab5b6ab94a9248a4f9536ea2fd497da20525f/sqlalchemy-2.0.40.tar.gz", hash = "sha256:d827099289c64589418ebbcaead0145cd19f4e3e8a93919a0100247af245fa00", size = 9664299, upload_time = "2025-03-27T17:52:31.876Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/21/77b4c147963073040dc3c3a5cb7a8c3001a1893c0209432cb77f9df836aa/sqlalchemy-2.0.52.tar.gz", hash = "sha256:5e2d46356ac2ccb7d268ab6c2319ac6a2b42f1b8d5fd8bd3d46855cd82abee97", size = 9945637, upload_time = "2026-08-11T19:07:09.829Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/18/4e3a86cc0232377bc48c373a9ba6a1b3fb79ba32dbb4eda0b357f5a2c59d/sqlalchemy-2.0.40-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:915866fd50dd868fdcc18d61d8258db1bf9ed7fbd6dfec960ba43365952f3b01", size = 2107887, upload_time = "2025-03-27T18:40:05.461Z" }, - { url = "https://files.pythonhosted.org/packages/cb/60/9fa692b1d2ffc4cbd5f47753731fd332afed30137115d862d6e9a1e962c7/sqlalchemy-2.0.40-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a4c5a2905a9ccdc67a8963e24abd2f7afcd4348829412483695c59e0af9a705", size = 2098367, upload_time = "2025-03-27T18:40:07.182Z" }, - { url = "https://files.pythonhosted.org/packages/4c/9f/84b78357ca641714a439eb3fbbddb17297dacfa05d951dbf24f28d7b5c08/sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55028d7a3ebdf7ace492fab9895cbc5270153f75442a0472d8516e03159ab364", size = 3184806, upload_time = "2025-03-27T18:51:29.356Z" }, - { url = "https://files.pythonhosted.org/packages/4b/7d/e06164161b6bfce04c01bfa01518a20cccbd4100d5c951e5a7422189191a/sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cfedff6878b0e0d1d0a50666a817ecd85051d12d56b43d9d425455e608b5ba0", size = 3198131, upload_time = "2025-03-27T18:50:31.616Z" }, - { url = "https://files.pythonhosted.org/packages/6d/51/354af20da42d7ec7b5c9de99edafbb7663a1d75686d1999ceb2c15811302/sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb19e30fdae77d357ce92192a3504579abe48a66877f476880238a962e5b96db", size = 3131364, upload_time = "2025-03-27T18:51:31.336Z" }, - { url = "https://files.pythonhosted.org/packages/7a/2f/48a41ff4e6e10549d83fcc551ab85c268bde7c03cf77afb36303c6594d11/sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:16d325ea898f74b26ffcd1cf8c593b0beed8714f0317df2bed0d8d1de05a8f26", size = 3159482, upload_time = "2025-03-27T18:50:33.201Z" }, - { url = "https://files.pythonhosted.org/packages/33/ac/e5e0a807163652a35be878c0ad5cfd8b1d29605edcadfb5df3c512cdf9f3/sqlalchemy-2.0.40-cp313-cp313-win32.whl", hash = "sha256:a669cbe5be3c63f75bcbee0b266779706f1a54bcb1000f302685b87d1b8c1500", size = 2080704, upload_time = "2025-03-27T18:46:00.193Z" }, - { url = "https://files.pythonhosted.org/packages/1c/cb/f38c61f7f2fd4d10494c1c135ff6a6ddb63508d0b47bccccd93670637309/sqlalchemy-2.0.40-cp313-cp313-win_amd64.whl", hash = "sha256:641ee2e0834812d657862f3a7de95e0048bdcb6c55496f39c6fa3d435f6ac6ad", size = 2104564, upload_time = "2025-03-27T18:46:01.442Z" }, - { url = "https://files.pythonhosted.org/packages/d1/7c/5fc8e802e7506fe8b55a03a2e1dab156eae205c91bee46305755e086d2e2/sqlalchemy-2.0.40-py3-none-any.whl", hash = "sha256:32587e2e1e359276957e6fe5dad089758bc042a971a8a09ae8ecf7a8fe23d07a", size = 1903894, upload_time = "2025-03-27T18:40:43.796Z" }, + { url = "https://files.pythonhosted.org/packages/7f/18/e30c6fe1eca1bf34a39fbdd6066121cc9974c850faf6f349eac563697a26/sqlalchemy-2.0.52-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2eb3c6a64b1bfe6704777cfd504e7b8ad093a5f3e03ce67663a5e6742f294e43", size = 2167724, upload_time = "2026-08-11T20:58:12.679Z" }, + { url = "https://files.pythonhosted.org/packages/d0/56/2e17d161a4f7ecc1c2ffb93e607b4e1898bb551b451b283235acb8f6ce47/sqlalchemy-2.0.52-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:923bb183c1dc64fdf7b717965e3d59938ec4f8b8710b419a21ce403e5da9a9e1", size = 3321189, upload_time = "2026-08-11T21:02:41.932Z" }, + { url = "https://files.pythonhosted.org/packages/cf/b8/8490916e893f3f8d74dc9cc54c078619364999dee37047a188e73abbc852/sqlalchemy-2.0.52-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:651d6d8782e80679e6151707c7b490834d46ada526328895abf567f25e63d29c", size = 3338185, upload_time = "2026-08-11T21:17:02.597Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f7/752cc8ee453da222829b3f5c4613614bf750d97429363b70414fa10478e4/sqlalchemy-2.0.52-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b08cddb8989775e3c88799d86704bdfc3ee6e9846118201aa5997f16f27e3a15", size = 3271698, upload_time = "2026-08-11T21:02:43.963Z" }, + { url = "https://files.pythonhosted.org/packages/51/e6/074ade0c07b9e4c8e8bca46820320ed94df9702afdb6f2af06623068d2e6/sqlalchemy-2.0.52-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ab66fa9618269390d4dfa222f2f2f88f7bc4bf5da13905131b818217db7e8057", size = 3308936, upload_time = "2026-08-11T21:17:04.172Z" }, + { url = "https://files.pythonhosted.org/packages/66/07/557c0d04716705599227945ac14e0a17ad0338e899f37d8c2ddff4dcc663/sqlalchemy-2.0.52-cp313-cp313-win32.whl", hash = "sha256:c63bda077685c85ca513286547a531ba57e7a68cf0a7ed3bafcc2bbd18896f4d", size = 2127308, upload_time = "2026-08-11T21:14:53.879Z" }, + { url = "https://files.pythonhosted.org/packages/96/4e/226eda27654318ce525d043025221f689abef883da2c7126f9065121618c/sqlalchemy-2.0.52-cp313-cp313-win_amd64.whl", hash = "sha256:9876b09b9f1ce7398b0ffece585c0a911244c53191187341f6bcae640e133751", size = 2153876, upload_time = "2026-08-11T21:14:55.527Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f5/71cb30af58c9b80a4e1fac0b73bb48f86d497a774a6a2eb6d2f1e657bb73/sqlalchemy-2.0.52-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:410d52be41d17f1a236d19520fbe776257dc16516ed06bd16d433311842aefd9", size = 2169537, upload_time = "2026-08-11T20:58:13.855Z" }, + { url = "https://files.pythonhosted.org/packages/4c/93/d07ebd645d1b07b6b5ed63450a70f063a346a7e0f2c8810daf2e532400cb/sqlalchemy-2.0.52-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfe9ce533dbe4d0a2ae1486546619bd30b76bcd670539a44d910361376175f5e", size = 3319606, upload_time = "2026-08-11T21:02:45.829Z" }, + { url = "https://files.pythonhosted.org/packages/ae/5c/290c84c7c2566ecd3b65baaae0fddec9bc33b033b398a06123bb86fbfc6e/sqlalchemy-2.0.52-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:812bae5138bfc0aa46fb0686da0fc7f581f68e2bbb05bc24c3713bebaedd1437", size = 3323642, upload_time = "2026-08-11T21:17:05.675Z" }, + { url = "https://files.pythonhosted.org/packages/13/f5/2cc160590ca49173359557880b92a0572293ccb899e8f6cedf150c5a3ddf/sqlalchemy-2.0.52-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:50bff43b632a56fbf5ed9afdd76307e1512b62051bcd5afb341ae67205bbb6c8", size = 3268125, upload_time = "2026-08-11T21:02:47.649Z" }, + { url = "https://files.pythonhosted.org/packages/35/f3/ea8933fc9f7d1353e9c2ff9965eae687c4cef181120574591ed2fa0633e1/sqlalchemy-2.0.52-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:49565daf5af554f538e23aef1fc81a95a4e49658f152285e45c02f5fc44f04cd", size = 3289516, upload_time = "2026-08-11T21:17:07.267Z" }, + { url = "https://files.pythonhosted.org/packages/45/67/05cf86541c1e1716fca1e4a996954a439cd74501707cda607fb7cb02ef50/sqlalchemy-2.0.52-cp314-cp314-win32.whl", hash = "sha256:ab9da41e61b9979b910499d633b241df20c51ee5037e5405b11c2faac3cbe1a2", size = 2130249, upload_time = "2026-08-11T21:14:57.273Z" }, + { url = "https://files.pythonhosted.org/packages/96/d7/8ac6ffa1e36169e762ef65bd835046abb2251b1bc17f8f6708e14ed8d31f/sqlalchemy-2.0.52-cp314-cp314-win_amd64.whl", hash = "sha256:a593db51b3bae75db17a5738ad5f992244b3a03863f83c28117ee482c6a3f76d", size = 2156718, upload_time = "2026-08-11T21:14:58.667Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4b/e01a737eef378e734cc6394a82248a6ce13b167dfa36c731075ce9fc9c64/sqlalchemy-2.0.52-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1e61d08bdf4ee2f41024569e3400de7d6734ba498144766b11260936ccfa582", size = 2190344, upload_time = "2026-08-11T19:53:21.393Z" }, + { url = "https://files.pythonhosted.org/packages/b3/3f/3582293d1e185e71d19d7c731c3e2ee20ba21981c4a1115c0806c1f62120/sqlalchemy-2.0.52-py3-none-any.whl", hash = "sha256:3b81b8363a919ce53453591cdb93702e6bd54ade6c4fa2f468fc053baee5ed89", size = 1950700, upload_time = "2026-08-11T20:47:21.603Z" }, ] [[package]] @@ -731,6 +845,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7b/b6/ebfd6daef0c19a5ca3ac1fb2fc092331d67af5a30c868f106fcc2504c287/stomp_py-8.2.0-py3-none-any.whl", hash = "sha256:fad24e51b505996015a39ca1632df4e0225c1c552980955e21f2aebfc0d9d85c", size = 42751, upload_time = "2024-10-31T21:59:36.658Z" }, ] +[[package]] +name = "tomli-w" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184, upload_time = "2025-01-15T12:07:24.262Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675, upload_time = "2025-01-15T12:07:22.074Z" }, +] + [[package]] name = "typer" version = "0.15.2" @@ -748,23 +871,23 @@ wheels = [ [[package]] name = "typing-extensions" -version = "4.13.2" +version = "4.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload_time = "2025-04-10T14:19:05.416Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload_time = "2026-07-02T08:40:05.92Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload_time = "2025-04-10T14:19:03.967Z" }, + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload_time = "2026-07-02T08:40:04.659Z" }, ] [[package]] name = "typing-inspection" -version = "0.4.0" +version = "0.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload_time = "2025-02-25T17:27:59.638Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c09092e6b34058f36a460eea2d4c3e8b910c695975a0/typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47", size = 76928, upload_time = "2026-08-12T12:37:25.997Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload_time = "2025-02-25T17:27:57.754Z" }, + { url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload_time = "2026-08-12T12:37:24.648Z" }, ] [[package]] diff --git a/kontor-servicemix/Dockerfile b/kontor-servicemix/Dockerfile deleted file mode 100644 index 965722c..0000000 --- a/kontor-servicemix/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM openjdk:8-jdk-alpine -#ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 - -ENV SERVICEMIX_VERSION_MAJOR=7 -ENV SERVICEMIX_VERSION_MINOR=0 -ENV SERVICEMIX_VERSION_PATCH=1 -ENV SERVICEMIX_VERSION=${SERVICEMIX_VERSION_MAJOR}.${SERVICEMIX_VERSION_MINOR}.${SERVICEMIX_VERSION_PATCH} - -RUN wget http://dlcdn.apache.org/servicemix/servicemix-${SERVICEMIX_VERSION_MAJOR}/${SERVICEMIX_VERSION}/apache-servicemix-${SERVICEMIX_VERSION}.zip; \ - unzip -d /opt apache-servicemix-${SERVICEMIX_VERSION}.zip; \ - rm -f apache-servicemix-${SERVICEMIX_VERSION}.zip; \ - ln -s /opt/apache-servicemix-${SERVICEMIX_VERSION} /opt/servicemix; \ - mkdir /deploy; \ - sed -i 's/^\(felix\.fileinstall\.dir\s*=\s*\).*$/\1\/deploy/' /opt/servicemix/etc/org.apache.felix.fileinstall-deploy.cfg; \ - sed -i 's/http:\/\//https:\/\//' /opt/servicemix/etc/org.ops4j.pax.url.mvn.cfg - -VOLUME ["/deploy"] -EXPOSE 1099 8101 8181 61616 61613 44444 -ENTRYPOINT ["/opt/servicemix/bin/servicemix"] - diff --git a/kontor-servicemix/Makefile b/kontor-servicemix/Makefile deleted file mode 100644 index 38f66c3..0000000 --- a/kontor-servicemix/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -.PHONY: clean docker - -docker: - docker build -t kontor-servicemix:0.2.0-SNAPSHOT . - diff --git a/kontor-spring/.factorypath b/kontor-spring/.factorypath deleted file mode 100644 index 5751075..0000000 --- a/kontor-spring/.factorypath +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/kontor-spring/Containerfile b/kontor-spring/Containerfile new file mode 100644 index 0000000..34017e6 --- /dev/null +++ b/kontor-spring/Containerfile @@ -0,0 +1,21 @@ +# ----------------------------------------------------------------------- # +FROM docker.io/library/gradle:8.7-jdk AS builder +WORKDIR / +COPY ./src/main/ ./src/main/ +COPY ./frontend/ ./frontend/ +COPY ./build.gradle ./ +COPY ./gradle.properties ./ +COPY ./settings.gradle ./ +COPY ./gradle/libs.versions.toml ./gradle/ +RUN gradle bootJar --no-daemon + +# ----------------------------------------------------------------------- # +FROM docker.io/alpine/java:21-jdk AS run + +RUN mkdir -p /logs + +COPY --from=builder /build/libs/kontor-spring-0.3.0-SNAPSHOT.jar app.jar + +EXPOSE 8100 + +CMD ["java", "-jar", "-Dspring.profiles.active=prod", "-Dvaadin.productionMode=true", "app.jar"] diff --git a/kontor-spring/Containerfile.local b/kontor-spring/Containerfile.local new file mode 100644 index 0000000..3f3d331 --- /dev/null +++ b/kontor-spring/Containerfile.local @@ -0,0 +1,9 @@ +FROM docker.io/alpine/java:21-jdk AS run + +RUN mkdir -p /logs + +COPY ./build/libs/kontor-spring-0.3.0-SNAPSHOT.jar app.jar + +EXPOSE 8100 + +CMD ["java", "-jar", "-Dspring.profiles.active=prod", "-Dvaadin.productionMode=true", "app.jar"] diff --git a/kontor-spring/Dockerfile b/kontor-spring/Dockerfile deleted file mode 100644 index 575c521..0000000 --- a/kontor-spring/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -# ----------------------------------------------------------------------- # -FROM gradle:8.7-jdk AS builder -WORKDIR / -COPY ./src/main/ ./src/main/ -COPY ./frontend/ ./frontend/ -COPY ./build.gradle ./ -COPY ./gradle.properties ./ -COPY ./settings.gradle ./ -COPY ./gradle/libs.versions.toml ./gradle/ -RUN gradle bootJar --no-daemon - -# ----------------------------------------------------------------------- # -FROM alpine/java:21-jdk AS run - -RUN mkdir -p /logs - -RUN adduser --system appuser - -COPY --from=builder --chown=appuser:appuser /build/libs/kontor-spring-0.2.0-SNAPSHOT.jar app.jar -RUN chown appuser:root /logs - -EXPOSE 8100 -USER appuser -CMD ["java", "-jar", "-Dspring.profiles.active=prod", "-Dvaadin.productionMode=true", "app.jar"] - diff --git a/kontor-spring/build.gradle b/kontor-spring/build.gradle index b2b70f4..666c48c 100644 --- a/kontor-spring/build.gradle +++ b/kontor-spring/build.gradle @@ -1,24 +1,8 @@ -buildscript { - configurations.classpath { - resolutionStrategy.eachDependency { DependencyResolveDetails details -> - if (details.requested.group == 'com.burgstaller' && details.requested.name == 'okhttp-digest' && details.requested.version == '1.10') { - details.useTarget "io.github.rburgst:${details.requested.name}:1.21" - details.because 'Dependency has moved' - } - } - } - repositories { - mavenCentral() - maven { setUrl("https://maven.vaadin.com/vaadin-prereleases") } - maven { setUrl("https://repo.spring.io/milestone") } - } -} - plugins { id 'java' id 'application' id 'maven-publish' - id "com.google.cloud.artifactregistry.gradle-plugin" version "2.2.0" + //id "com.google.cloud.artifactregistry.gradle-plugin" version "2.2.0" id 'jvm-test-suite' id 'jacoco' id 'test-report-aggregation' @@ -27,14 +11,14 @@ plugins { alias(libs.plugins.spring.dependencies) alias(libs.plugins.vaadin) alias(libs.plugins.lombok) - alias(libs.plugins.asciidoctorPdf) - alias(libs.plugins.asciidoctorConvert) - alias(libs.plugins.asciidoctorGems) + //id 'com.github.ksoichiro.build.info' version '0.2.0' + //id 'com.pasam.gradle.buildinfo' version '0.1.3' + id 'com.gorylenko.gradle-git-properties' version '4.0.1' } repositories { + maven { setUrl("https://nexus.thpeetz.de/repository/maven-central") } mavenCentral() - ruby.gems() maven { setUrl("https://maven.vaadin.com/vaadin-prereleases") } maven { setUrl("https://repo.spring.io/milestone") } maven { setUrl("https://maven.vaadin.com/vaadin-addons") } @@ -60,11 +44,15 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.apache.camel.springboot:camel-spring-boot-starter' implementation 'org.apache.camel.springboot:camel-jms-starter' + implementation 'org.apache.camel.springboot:camel-metrics-starter' + implementation 'org.apache.camel.springboot:camel-micrometer-starter' implementation 'org.apache.activemq:artemis-jakarta-client' //implementation libs.artemis implementation 'org.springframework.boot:spring-boot-starter-actuator' developmentOnly 'org.springframework.boot:spring-boot-devtools' implementation 'io.micrometer:micrometer-registry-prometheus' + implementation libs.jolokia.core + implementation libs.prometheus.collector implementation 'org.springframework.security:spring-security-oauth2-jose' implementation 'org.springframework.security:spring-security-oauth2-resource-server' implementation 'com.h2database:h2' @@ -76,6 +64,7 @@ dependencies { implementation libs.jackson implementation libs.gson implementation libs.json + implementation libs.jsoup implementation 'org.hibernate.orm:hibernate-community-dialects' testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' @@ -87,67 +76,8 @@ dependencies { testRuntimeOnly 'org.junit.platform:junit-platform-launcher' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' - asciidoctorGems libs.rouge - //asciidoctorGems libs.diagram } -def pdfFile = layout.buildDirectory.file("docs/asciidocPdf/kontor-spring.pdf") -def pdfArtifact = artifacts.add('archives', pdfFile.get().asFile) { - type 'pdf' - builtBy asciidoctorPdf -} - -publishing { - publications { - maven(MavenPublication) { - groupId = group + '.docs' - artifactId = project.name - artifact pdfArtifact - } - bootJava(MavenPublication) { - artifact tasks.named("bootDistTar") - } - } - repositories { - maven { - name = "gitlabPackageRegistry" - url = uri("https://gitlab.com/api/v4/projects/64726715/packages/maven") - credentials(PasswordCredentials) - } - } -} - -final BUILD_DATE = new Date().format('dd.MM.yyyy').toString() - -asciidoctorPdf { - dependsOn asciidoctorGemsPrepare - - baseDirFollowsSourceFile() - - asciidoctorj { - modules { - diagram.use() - } - requires 'rouge' - attributes 'build-gradle': file('build.gradle'), - 'endpoint-url': 'https://www.thpeetz.de', - 'source-highlighter': 'rouge', - 'imagesdir': './images', - 'toc': 'left', - 'toc-title': 'Inhaltsverzeichnis', - 'revdate': BUILD_DATE, - 'revnumber': { project.version.toString() }, - 'revremark': 'Entwurf', - 'chapter-label': '', - 'icons': 'font', - 'idprefix': 'id_', - 'idseparator': '-', - 'docinfo1': '' - } -} - -build.dependsOn asciidoctorPdf - dependencyManagement { imports { mavenBom libs.vaadin.bom.get().toString() @@ -155,6 +85,25 @@ dependencyManagement { } } +publishing { + publications { + bootJava(MavenPublication) { + artifact tasks.named("bootJar") + } + } + repositories { + maven { + url = version.endsWith('SNAPSHOT') ? + 'https://nexus.thpeetz.de/repository/maven-snapshots' : + 'https://nexus.thpeetz.de/repository/maven-releases' + credentials { + username = project.findProperty('nexusUser') + password = project.findProperty('nexusPassword') + } + } + } +} + application { mainClass = 'de.thpeetz.kontor.Application' } @@ -163,6 +112,10 @@ bootRun { args = ["--spring.profiles.active=${project.properties['profile'] ?: 'prod'}"] } +springBoot { + buildInfo() +} + task dockerImage(type: Exec) { dependsOn(bootJar) commandLine "docker", "build", ".", "-t", "kontor:${project.version}" @@ -256,5 +209,5 @@ reporting { } wrapper { - gradleVersion = "8.6" + gradleVersion = libs.versions.gradle.get().toString() } diff --git a/kontor-spring/gradle.properties b/kontor-spring/gradle.properties index ba98070..9a561e0 100644 --- a/kontor-spring/gradle.properties +++ b/kontor-spring/gradle.properties @@ -1,3 +1,5 @@ description='Kontor with Spring Boot' -version=0.2.0-SNAPSHOT +version=0.3.0-SNAPSHOT group=de.thpeetz +nexusUser=kontor +nexusPassword=kontorNexus diff --git a/kontor-spring/gradle/libs.versions.toml b/kontor-spring/gradle/libs.versions.toml index 1f68ea3..a5ae22d 100644 --- a/kontor-spring/gradle/libs.versions.toml +++ b/kontor-spring/gradle/libs.versions.toml @@ -3,30 +3,28 @@ gradle = "8.6" args4j = "2.33" commonscli = "1.5.0" junit = "5.8.2" -logback = "1.1.2" +logback = "1.6.3" mockito = "1.9.5" picoli = "4.7.0" -slf4j = "1.7.22" +slf4j = "2.0.18" hsqldb = "2.7.1" sqlite = "3.25.2" spotbugs = "6.0.7" -asciidoctor = "4.0.2" -rouge = "3.15.0" -#diagram = "2.2.2" -diagram = "2.3.1" sonarqube = "3.3" -cimtConventions = "1.0.0-SNAPSHOT" springboot = "3.2.5" springdependencies = "1.1.4" -vaadin = "24.3.8" +vaadin = "24.4.23" camel = "4.10.6" artemis = "2.41.0" -lombok = "8.6" +lombok = "8.11" gson = "2.9.0" jackson = "2.16.1" json_simple = "1.1.1" +jsoup = "1.23.1" mail = "1.6.2" hypersistence = "3.9.10" +jolokia = "2.6.1" +prometheus = "1.6.0" [libraries] args4j = { module = "args4j:args4j", version.ref = "args4j" } @@ -39,6 +37,7 @@ picocli = { module = "info.picocli:picocli", version.ref = "picoli" } slf4j = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } hsqldb = { module = "org.hsqldb:hsqldb", version.ref = "hsqldb" } gson = { module = "com.google.code.gson:gson", version.ref = "gson" } +jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" } jackson = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } json = { module = "com.googlecode.json-simple:json-simple", version.ref ="json_simple" } mail = { module = "com.sun.mail:javax.mail", version.ref ="mail" } @@ -47,11 +46,8 @@ hypersistence = { module = "io.hypersistence:hypersistence-utils-hibernate-63", vaadin-bom = { module = "com.vaadin:vaadin-bom", version.ref = "vaadin" } camel-bom = { module = "org.apache.camel.springboot:camel-spring-boot-bom", version.ref = "camel"} artemis = { module = "org.apache.activemq:artemis-jms-server", version.ref = "artemis" } -asciidoctorGradleJvmGems = { module = "org.asciidoctor:asciidoctor-gradle-jvm-gems", version.ref= "asciidoctor" } -asciidoctorGradleJvm = { module = "org.asciidoctor:asciidoctor-gradle-jvm", version.ref= "asciidoctor" } -asciidoctorGradleJvmPdf = { module = "org.asciidoctor:asciidoctor-gradle-jvm-pdf", version.ref= "asciidoctor" } -rouge = { module = "rubygems:rouge", version.ref = "rouge" } -diagram = { module = "rubygems:asciidoctor-diagram", version.ref = "diagram" } +jolokia-core = { module = "org.jolokia:jolokia-core", version.ref = "jolokia" } +prometheus-collector = { module = "io.prometheus.jmx:collector", version.ref = "prometheus" } [bundles] logback = ["logbackCore", "logbackClassic"] @@ -59,13 +55,6 @@ logback = ["logbackCore", "logbackClassic"] [plugins] spotbugs = { id = "com.github.spotbugs", version.ref = "spotbugs" } sonarqube = { id = "org.sonarqube", version.ref = "sonarqube" } -asciidoctorPdf = { id = "org.asciidoctor.jvm.pdf", version.ref = "asciidoctor" } -asciidoctorConvert = { id = "org.asciidoctor.jvm.convert", version.ref = "asciidoctor" } -asciidoctorGems = { id = "org.asciidoctor.jvm.gems", version.ref = "asciidoctor" } -javaConvention = { id = "de.cimt.java-conventions", version.ref = "cimtConventions" } -applicationConvention = { id = "de.cimt.application-conventions", version.ref = "cimtConventions" } -libraryConvention = { id = "de.cimt.library-conventions", version.ref = "cimtConventions" } -asciidoctorConvention = { id = "de.cimt.asciidoctor-conventions", version.ref = "cimtConventions" } spring-boot = { id = "org.springframework.boot", version.ref = "springboot"} spring-dependencies = { id = "io.spring.dependency-management", version.ref = "springdependencies" } vaadin = { id = "com.vaadin", version.ref = "vaadin" } diff --git a/kontor-spring/settings.gradle b/kontor-spring/settings.gradle index f559dac..226b285 100644 --- a/kontor-spring/settings.gradle +++ b/kontor-spring/settings.gradle @@ -11,6 +11,7 @@ pluginManagement { } repositories { gradlePluginPortal() + maven { setUrl("https://nexus.thpeetz.de/repository/maven-central") } mavenCentral() maven { setUrl("https://maven.vaadin.com/vaadin-prereleases") } maven { setUrl("https://repo.spring.io/milestone") } diff --git a/kontor-spring/src/docs/asciidoc/kontor-spring.adoc b/kontor-spring/src/docs/asciidoc/kontor-spring.adoc deleted file mode 100644 index bd4ee00..0000000 --- a/kontor-spring/src/docs/asciidoc/kontor-spring.adoc +++ /dev/null @@ -1,509 +0,0 @@ -= Projektbeschreibung kontor-spring: Entwicklungs- und Projekthandbuch -:author: Thomas Peetz -:email: -:doctype: book -:sectnums: -:sectnumlevels: 4 -:toc: -:toclevels: 4 -:table-caption!: -:counter: table-number: 0 - -[title="Dokumenthistorie", id="Table-{counter:table-number}", options="header"] -|=== -| Version | Datum | Autor | Änderungsgrund / Bemerkungen -| 1.0.0 | 16.05.2022 | Thomas Peetz | Ersterstellung -|=== - -== Allgemeines - -=== Zweck des Dokumentes - -Das Entwicklungshandbuch beschreibt die Werkzeuge und die Vorgehensweise bei der Entwicklung -im Projekt kontor-spring und der Erstellung der Dokumentation. - -=== Verwendete Tools - -==== Gitea - -Für die Verwaltung des Sourcecode kommt ((Gitea))<> zum Einsatz. -Mit Gitea werden auch die Projektaufgaben verwaltet. - -Das Projekt und das dazugehörige Git Repository sind unter der Adresse - -https://gitea.thpeetz.de/kontor/kontor-spring - -zu finden. - -== Erstellung der Dokumentation - -Die Dokumentation des Projektes wird mit ((Asciidoctor))<> geschrieben. -Die Dokumente erhalten ihre Namen nach dem jeweiligen Hauptdokument. - -=== Quellcode Verwaltung - -Die Asciidoctor-Dateien haben die Endung `.adoc`. - -=== Buildsystem - -Zur Erstellung der PDF-Dateien aus den Asciidoctor-Dateien wird das Buildsystem ((Gradle))<> verwendet. -Die Dateien für die Dokumente liegen im Verzeichnis `src/docs/asciidoc`. - -Der Gradle Build wird über die Datei `build.gradle` definiert. - - -== Einführung - -=== Zweck - -=== Stakeholder des Systems - -=== Systemumfang - -==== Zielsetzung des Systems - -=== Systemübersicht - -==== Systemkontext - -==== Systemarchitektur - -==== Systemschnittstellen - -===== Realisierte Schnittstellen - -===== Verwendete Schnittstellen - -==== Logisches Datenmodell - -===== Benutzer ER-Diagramm - -[mermaid, kontor-user-er, png] -.Benutzer ER-Diagramm -.... -erDiagram - user { - string id PK - datetime created_date - datetime last_modified_date - int version - string email - boolean enabled - string firstName - string lastName - string password - string token - boolean tokenExpired - string userName UNIQUE - } - role { - string id PK - datetime created_date - datetime last_modified_date - int version - string name - } - authorization_matrix { - string id PK - datetime created_date - datetime last_modified_date - int version - string user_id FK - string role_id FK - } - module_data { - string id PK - datetime created_date - datetime last_modified_date - int version - boolean import_data - string module_name UNIQUE - } - user ||--o{ authorization_matrix : "matrix" - role ||--o{ authorization_matrix : "matrix" -.... - - -===== Comics ER-Diagramm - -[mermaid, kontor-comics-er, png] -.Comics ER-Diagramm -.... -erDiagram - comic { - string id PK - datetime created_date - datetime last_modified_date - int version - boolean completed - boolean currentOrder - string title - string publisher_id FK - } - volume { - string id PK - datetime created_date - datetime last_modified_date - int version - string name - string comic_id FK - } - issue { - string id PK - datetime created_date - datetime last_modified_date - int version - boolean in_stock - boolean is_read - string issue_number - string comic_id FK - string volume_id FK - } - publisher { - string id PK - datetime created_date - datetime last_modified_date - int version - string name - } - artist { - string id PK - datetime created_date - datetime last_modified_date - int version - string name - } - story_arc { - string id PK - datetime created_date - datetime last_modified_date - int version - string name - string comic_id FK - } - trade_paperback { - string id PK - datetime created_date - datetime last_modified_date - int version - int issueStart - int issueEnd - string name - string comic_id FK - } - worktype { - string id PK - datetime created_date - datetime last_modified_date - int version - string name - } - comic_work { - string id PK - datetime created_date - datetime last_modified_date - int version - string artist_id FK - string comic_id FK - string worktype_id FK - } - comic ||--o{ comic_work : "1" - artist ||--o{ comic_work : "1" - worktype ||--o{ comic-work : "1" - publisher ||--o{ comic : "1" - comic ||--o{ issue : "1" - comic ||--o{ volume : "1" - comic ||--o{ story_arc : "1" - comic ||--o{ trade_paperback : "1" - volume ||--o{ issue : "1" -.... - -===== TYSC ER-Diagramm - -[mermaid, kontor-tysc-er, png] -.TYSC ER-Diagramm -.... -erDiagram - sport { - string id PK - datetime created_date - datetime last_modified_date - int version - string name - } - team { - string id PK - datetime created_date - datetime last_modified_date - int version - string name - string short_name - string sport_id FK - } - field_position { - string id PK - datetime created_date - datetime last_modified_date - int version - string name - string short_name - string sport_id FK - } - rooster { - string id PK - datetime created_date - datetime last_modified_date - int version - int year - string player_id FK - string position_id FK - string team_id FK - } - player { - string id PK - datetime created_date - datetime last_modified_date - int version - string first_name - string last_name - } - vendor { - string id PK - datetime created_date - datetime last_modified_date - int version - string name - } - card_set { - string id PK - datetime created_date - datetime last_modified_date - int version - boolean insert_set - string name - boolean parallel_set - string vendor_id FK - } - card { - string id PK - datetime created_date - datetime last_modified_date - int version - int cardNumber - int year - string card_set FK - string rooster_id FK - string vendor_id FK - } - sport ||--o{ team : "1" - sport ||--o{ field_position : "1" - field_position ||--o{ rooster : "1" - player ||--o{ rooster : "1" - team ||--o{ rooster : "1" - vendor ||--o{ card : "1" - card_set ||--o{ card : "1" - rooster ||--o{ card : "1" -.... - -===== Bookshelf ER-Diagramm - -[mermaid, kontor-bookshelf-er, png] -.Bookshelf ER-Diagramm -.... -erDiagram - article { - string id PK - datetime created_date - datetime last_modified_date - int version - string title - } - book { - string id PK - datetime created_date - datetime last_modified_date - int version - string isbn UNIQUE - string title - int year - string publisher_id FK - } - bookshelf_publisher { - string id PK - datetime created_date - datetime last_modified_date - int version - string name UNIQUE - } - author { - string id PK - datetime created_date - datetime last_modified_date - int version - string first_name - string last_name - } - article_author { - string id PK - datetime created_date - datetime last_modified_date - int version - string article_id FK - string author_id FK - } - book_author { - string id PK - datetime created_date - datetime last_modified_date - int version - string book_id FK - string author_id FK - } - publisher ||--o{ book : "1" - article ||--o{ article_author : "1" - author ||--o{ article_author : "1" - book ||--o{ book_author : "1" - author ||--o{ book_author : "1" -.... - -===== Mail ER-Diagramm - -[mermaid, kontor-mail-er, png] -.Mail ER-Diagramm -.... -erDiagram - mail { - string id PK - datetime created_date - datetime last_modified_date - int version - string subject - string content - datetime received_date - datetime sent_date - } - mail_account { - string id PK - datetime created_date - datetime last_modified_date - int version - string host - string password - int port - string protocol - boolean start_tls - string user_name - } - mail_address { - string id PK - datetime created_date - datetime last_modified_date - int version - string internet_address UNIQUE - string personal - string user_id FK - } - user ||--o{ mail_address : "1" -.... - -==== Einschränkungen - -== Anforderungen der Domäne - -=== Systemfunktionen - -==== Anwendungsfälle - -==== Akteure - -==== Zielgruppen - -=== Anforderungen - -==== Anforderungen an externe Schnittstellen - -==== Funktionale Anforderungen - -==== Qualitätsanforderungen - -==== Randbedingungen - -==== Weitere Anforderungen - -==== Wartungs- und Supportinformationen - -=== Verifikation - -== Projektbeschreibung - -=== Ausgangslage - -//==== Rechtliche Vorgaben und Rahmenbedingungen -//=== Rahmenbedingungen - -//==== Vorhandene Regelungen - -=== Projektziele - -=== Projektabgrenzung - -//=== Voraussichtliche Kosten - -//=== Projektrisiken - -//==== Produktivität - -//==== Finanzielle Risiken - -//==== Akzeptanz - -== Projektorganisation - -=== Projekt-Aufbauorganisation - -=== Rollendefinition - -//==== Projektauftraggeber - -//==== Projektausschuss - -//==== Beratung / Qualitätssicherung - -==== Projekteiter - -==== Projektteam - -==== Liste der Stakeholder - -=== Projektablauforganisation - -==== Projekt-Phasen - -===== Erstellung der Projektdokumentation - - -== Verschiedenes - -=== Erreichbarkeiten - -[bibliography] -== Referenzen - -- [[[asciidoctor]]] http://asciidoctor.org -- [[[gitea]]] http://www.gitea.org -- [[[gradle]]] http://www.gradle.org -- [[[jenkins]]] http://jenkins-ci.org - -[glossary] -== Glossar - -[index] -== Index - -== Verzeichnisse - -=== Abbildungsverzeichnis - -=== Tabellenverzeichnis - -<> <> diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ArtistViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ArtistViewTest.java index e2eec07..b9874b1 100644 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ArtistViewTest.java +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ArtistViewTest.java @@ -11,7 +11,9 @@ import org.springframework.boot.test.context.SpringBootTest; import com.vaadin.flow.component.grid.Grid; -import de.thpeetz.kontor.comics.data.Artist; +import de.thpeetz.kontor.data.comics.Artist; +import de.thpeetz.kontor.views.comics.ArtistForm; +import de.thpeetz.kontor.views.comics.ArtistView; @SpringBootTest class ArtistViewTest { diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ArtistformTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ArtistformTest.java index a6aea11..395f16a 100644 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ArtistformTest.java +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ArtistformTest.java @@ -8,7 +8,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import de.thpeetz.kontor.comics.data.Artist; +import de.thpeetz.kontor.data.comics.Artist; +import de.thpeetz.kontor.views.comics.ArtistForm; @SpringBootTest class ArtistformTest { diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ComicViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ComicViewTest.java index 084d64e..e31f9b7 100644 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ComicViewTest.java +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ComicViewTest.java @@ -13,7 +13,9 @@ import org.springframework.boot.test.context.SpringBootTest; import com.vaadin.flow.component.grid.Grid; -import de.thpeetz.kontor.comics.data.Comic; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.views.comics.ComicForm; +import de.thpeetz.kontor.views.comics.ComicView; @SpringBootTest public class ComicViewTest { diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ComicWorkViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ComicWorkViewTest.java index 0d3113e..891963f 100644 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ComicWorkViewTest.java +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/ComicWorkViewTest.java @@ -13,7 +13,9 @@ import org.springframework.boot.test.context.SpringBootTest; import com.vaadin.flow.component.grid.Grid; -import de.thpeetz.kontor.comics.data.ComicWork; +import de.thpeetz.kontor.data.comics.ComicWork; +import de.thpeetz.kontor.views.comics.ComicWorkForm; +import de.thpeetz.kontor.views.comics.ComicWorkView; @SpringBootTest class ComicWorkViewTest { diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/IssueViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/IssueViewTest.java index 089f8f5..baaa465 100644 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/IssueViewTest.java +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/IssueViewTest.java @@ -13,7 +13,9 @@ import org.springframework.boot.test.context.SpringBootTest; import com.vaadin.flow.component.grid.Grid; -import de.thpeetz.kontor.comics.data.Issue; +import de.thpeetz.kontor.data.comics.Issue; +import de.thpeetz.kontor.views.comics.IssueForm; +import de.thpeetz.kontor.views.comics.IssueView; @SpringBootTest public class IssueViewTest { diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/PublisherViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/PublisherViewTest.java index b3bab80..174221a 100644 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/PublisherViewTest.java +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/PublisherViewTest.java @@ -11,7 +11,9 @@ import org.springframework.boot.test.context.SpringBootTest; import com.vaadin.flow.component.grid.Grid; -import de.thpeetz.kontor.comics.data.Publisher; +import de.thpeetz.kontor.data.comics.Publisher; +import de.thpeetz.kontor.views.comics.PublisherForm; +import de.thpeetz.kontor.views.comics.PublisherView; @SpringBootTest class PublisherViewTest { diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/StoryArcViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/StoryArcViewTest.java index 56f9c34..2375f43 100644 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/StoryArcViewTest.java +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/StoryArcViewTest.java @@ -13,7 +13,9 @@ import org.springframework.boot.test.context.SpringBootTest; import com.vaadin.flow.component.grid.Grid; -import de.thpeetz.kontor.comics.data.StoryArc; +import de.thpeetz.kontor.data.comics.StoryArc; +import de.thpeetz.kontor.views.comics.StoryArcForm; +import de.thpeetz.kontor.views.comics.StoryArcView; @SpringBootTest class StoryArcViewTest { diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/TradePaperbackViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/TradePaperbackViewTest.java index a3b4119..4652018 100644 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/TradePaperbackViewTest.java +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/TradePaperbackViewTest.java @@ -13,8 +13,9 @@ import org.springframework.boot.test.context.SpringBootTest; import com.vaadin.flow.component.grid.Grid; -import de.thpeetz.kontor.comics.data.TradePaperback; -import de.thpeetz.kontor.comics.data.Volume; +import de.thpeetz.kontor.data.comics.TradePaperback; +import de.thpeetz.kontor.views.comics.TradePaperBackForm; +import de.thpeetz.kontor.views.comics.TradePaperbackView; @SpringBootTest class TradePaperbackViewTest { diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/VolumeViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/VolumeViewTest.java index 15e8d15..eaf0d73 100644 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/VolumeViewTest.java +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/VolumeViewTest.java @@ -13,7 +13,9 @@ import org.springframework.boot.test.context.SpringBootTest; import com.vaadin.flow.component.grid.Grid; -import de.thpeetz.kontor.comics.data.Volume; +import de.thpeetz.kontor.data.comics.Volume; +import de.thpeetz.kontor.views.comics.VolumeForm; +import de.thpeetz.kontor.views.comics.VolumeView; @SpringBootTest class VolumeViewTest { diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/WorktypeViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/WorktypeViewTest.java index 2f15672..05bf459 100644 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/WorktypeViewTest.java +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/comics/views/WorktypeViewTest.java @@ -13,7 +13,9 @@ import org.springframework.boot.test.context.SpringBootTest; import com.vaadin.flow.component.grid.Grid; -import de.thpeetz.kontor.comics.data.Worktype; +import de.thpeetz.kontor.data.comics.Worktype; +import de.thpeetz.kontor.views.comics.WorktypeForm; +import de.thpeetz.kontor.views.comics.WorktypeView; import lombok.extern.slf4j.Slf4j; @Slf4j diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/CardSetViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/CardSetViewTest.java deleted file mode 100644 index 40d3fbb..0000000 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/CardSetViewTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import com.vaadin.flow.component.grid.Grid; - -import de.thpeetz.kontor.tysc.data.CardSet; - -@SpringBootTest -class CardSetViewTest { - - @Autowired - private CardSetView cardSetView; - - @Test - void formShownWhenCardSetSelected() { - Grid grid = cardSetView.getGrid(); - CardSet firstCardSet = getFirstItem(grid); - - CardSetForm form = cardSetView.getForm(); - - assertFalse(form.isVisible()); - grid.asSingleSelect().setValue(firstCardSet); - assertTrue(form.isVisible()); - assertEquals(firstCardSet.getName(), form.name.getValue()); - } - - private CardSet getFirstItem(Grid grid) { - int count = grid.getListDataView().getItemCount(); - List cardSets = grid.getListDataView().getItems().collect(Collectors.toList()); - assertEquals(15, count); - return cardSets.get(0); - } -} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/CardViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/CardViewTest.java deleted file mode 100644 index 0a5a3ed..0000000 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/CardViewTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import com.vaadin.flow.component.grid.Grid; - -import de.thpeetz.kontor.tysc.data.Card; - -@SpringBootTest -class CardViewTest { - - @Autowired - private CardView cardView; - - @Test - void formShownWhenCardSelected() { - Grid grid = cardView.getGrid(); - Card firstCard = getFirstItem(grid); - - CardForm form = cardView.getForm(); - - assertFalse(form.isVisible()); - grid.asSingleSelect().setValue(firstCard); - assertTrue(form.isVisible()); - assertEquals(String.valueOf(firstCard.getCardNumber()), form.cardNumber.getValue()); - } - - private Card getFirstItem(Grid grid) { - int count = grid.getListDataView().getItemCount(); - List cards = grid.getListDataView().getItems().collect(Collectors.toList()); - assertEquals(10, count); - return cards.get(0); - } -} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/FieldPositionViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/FieldPositionViewTest.java deleted file mode 100644 index 737b74d..0000000 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/FieldPositionViewTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import com.vaadin.flow.component.grid.Grid; - -import de.thpeetz.kontor.tysc.data.FieldPosition; - -@SpringBootTest -class FieldPositionViewTest { - - @Autowired - private PositionView positionView; - - @Test - void formShownWhenPositionSelected() { - Grid grid = positionView.getGrid(); - FieldPosition firstFieldPosition = getFirstItem(grid); - - PositionForm form = positionView.getForm(); - - assertFalse(form.isVisible()); - grid.asSingleSelect().setValue(firstFieldPosition); - assertTrue(form.isVisible()); - assertEquals(firstFieldPosition.getName(), form.name.getValue()); - } - - private FieldPosition getFirstItem(Grid grid) { - int count = grid.getListDataView().getItemCount(); - List positions = grid.getListDataView().getItems().collect(Collectors.toList()); - assertEquals(44, count); - return positions.get(0); - } -} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/PlayerViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/PlayerViewTest.java deleted file mode 100644 index 5e7d640..0000000 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/PlayerViewTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import com.vaadin.flow.component.grid.Grid; - -import de.thpeetz.kontor.tysc.data.Player; - -@SpringBootTest -class PlayerViewTest { - - @Autowired - private PlayerView playerView; - - @Test - void formShownWhenPlayerSelected() { - Grid grid = playerView.getGrid(); - Player firstPlayer = getFirstItem(grid); - - PlayerForm form = playerView.getForm(); - - assertFalse(form.isVisible()); - grid.asSingleSelect().setValue(firstPlayer); - assertTrue(form.isVisible()); - assertEquals(firstPlayer.getLastName(), form.lastName.getValue()); - assertEquals(firstPlayer.getFirstName(), form.firstName.getValue()); - } - - private Player getFirstItem(Grid grid) { - int count = grid.getListDataView().getItemCount(); - List players = grid.getListDataView().getItems().collect(Collectors.toList()); - assertEquals(38, count); - return players.get(0); - } -} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/RoosterViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/RoosterViewTest.java deleted file mode 100644 index d04f306..0000000 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/RoosterViewTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import com.vaadin.flow.component.grid.Grid; - -import de.thpeetz.kontor.tysc.data.Rooster; - -@SpringBootTest -class RoosterViewTest { - - @Autowired - private RoosterView roosterView; - - @Test - void formShownWhenRoosterSelected() { - Grid grid = roosterView.getGrid(); - Rooster firstRooster = getFirstItem(grid); - - RoosterForm form = roosterView.getForm(); - - assertFalse(form.isVisible()); - grid.asSingleSelect().setValue(firstRooster); - assertTrue(form.isVisible()); - assertEquals(firstRooster.getYear(), form.year.getValue()); - } - - private Rooster getFirstItem(Grid grid) { - int count = grid.getListDataView().getItemCount(); - List roosters = grid.getListDataView().getItems().collect(Collectors.toList()); - assertEquals(11, count); - return roosters.get(0); - } -} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/SportViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/SportViewTest.java deleted file mode 100644 index ca86d0a..0000000 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/SportViewTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import com.vaadin.flow.component.grid.Grid; - -import de.thpeetz.kontor.tysc.data.Sport; - -@SpringBootTest -class SportViewTest { - - @Autowired - private SportView sportView; - - @Test - void formShownWhenSportSelected() { - Grid grid = sportView.getGrid(); - Sport firstSport = getFirstItem(grid); - - SportForm form = sportView.getForm(); - - assertFalse(form.isVisible()); - grid.asSingleSelect().setValue(firstSport); - assertTrue(form.isVisible()); - assertEquals(firstSport.getName(), form.name.getValue()); - } - - private Sport getFirstItem(Grid grid) { - int count = grid.getListDataView().getItemCount(); - List sports = grid.getListDataView().getItems().collect(Collectors.toList()); - assertEquals(4, count); - return sports.get(0); - } -} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/TeamViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/TeamViewTest.java deleted file mode 100644 index da0ea19..0000000 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/TeamViewTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import com.vaadin.flow.component.grid.Grid; - -import de.thpeetz.kontor.tysc.data.Team; - -@SpringBootTest -class TeamViewTest { - - @Autowired - private TeamView teamView; - - @Test - void formShownWhenTeamSelected() { - Grid grid = teamView.getGrid(); - Team firstTeam = getFirstItem(grid); - - TeamForm form = teamView.getForm(); - - assertFalse(form.isVisible()); - grid.asSingleSelect().setValue(firstTeam); - assertTrue(form.isVisible()); - assertEquals(firstTeam.getName(), form.name.getValue()); - } - - private Team getFirstItem(Grid grid) { - int count = grid.getListDataView().getItemCount(); - List teams = grid.getListDataView().getItems().collect(Collectors.toList()); - assertEquals(122, count); - return teams.get(0); - } -} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/VendorViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/VendorViewTest.java deleted file mode 100644 index ef80d22..0000000 --- a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/tysc/views/VendorViewTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import com.vaadin.flow.component.grid.Grid; - -import de.thpeetz.kontor.tysc.data.Vendor; - -@SpringBootTest -class VendorViewTest { - - @Autowired - private VendorView vendorView; - - @Test - void formShownWhenVendorSelected() { - Grid grid = vendorView.getGrid(); - Vendor firstVendor = getFirstItem(grid); - - VendorForm form = vendorView.getForm(); - - assertFalse(form.isVisible()); - grid.asSingleSelect().setValue(firstVendor); - assertTrue(form.isVisible()); - assertEquals(firstVendor.getName(), form.name.getValue()); - } - - private Vendor getFirstItem(Grid grid) { - int count = grid.getListDataView().getItemCount(); - List vendors = grid.getListDataView().getItems().collect(Collectors.toList()); - assertEquals(9, count); - return vendors.get(0); - } -} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/CardSetViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/CardSetViewTest.java new file mode 100644 index 0000000..1cd18ea --- /dev/null +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/CardSetViewTest.java @@ -0,0 +1,43 @@ +package de.thpeetz.kontor.views.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.vaadin.flow.component.grid.Grid; + +import de.thpeetz.kontor.data.tysc.CardSet; + +@SpringBootTest +class CardSetViewTest { + + @Autowired + private CardSetView cardSetView; + + @Test + void formShownWhenCardSetSelected() { + Grid grid = cardSetView.getGrid(); + CardSet firstCardSet = getFirstItem(grid); + + CardSetForm form = cardSetView.getForm(); + + assertFalse(form.isVisible()); + grid.asSingleSelect().setValue(firstCardSet); + assertTrue(form.isVisible()); + assertEquals(firstCardSet.getName(), form.name.getValue()); + } + + private CardSet getFirstItem(Grid grid) { + int count = grid.getListDataView().getItemCount(); + List cardSets = grid.getListDataView().getItems().collect(Collectors.toList()); + assertEquals(15, count); + return cardSets.get(0); + } +} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/CardViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/CardViewTest.java new file mode 100644 index 0000000..d924d0b --- /dev/null +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/CardViewTest.java @@ -0,0 +1,43 @@ +package de.thpeetz.kontor.views.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.vaadin.flow.component.grid.Grid; + +import de.thpeetz.kontor.data.tysc.Card; + +@SpringBootTest +class CardViewTest { + + @Autowired + private CardView cardView; + + @Test + void formShownWhenCardSelected() { + Grid grid = cardView.getGrid(); + Card firstCard = getFirstItem(grid); + + CardForm form = cardView.getForm(); + + assertFalse(form.isVisible()); + grid.asSingleSelect().setValue(firstCard); + assertTrue(form.isVisible()); + assertEquals(String.valueOf(firstCard.getCardNumber()), form.cardNumber.getValue()); + } + + private Card getFirstItem(Grid grid) { + int count = grid.getListDataView().getItemCount(); + List cards = grid.getListDataView().getItems().collect(Collectors.toList()); + assertEquals(10, count); + return cards.get(0); + } +} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/FieldPositionViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/FieldPositionViewTest.java new file mode 100644 index 0000000..8cb2adf --- /dev/null +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/FieldPositionViewTest.java @@ -0,0 +1,43 @@ +package de.thpeetz.kontor.views.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.vaadin.flow.component.grid.Grid; + +import de.thpeetz.kontor.data.tysc.FieldPosition; + +@SpringBootTest +class FieldPositionViewTest { + + @Autowired + private PositionView positionView; + + @Test + void formShownWhenPositionSelected() { + Grid grid = positionView.getGrid(); + FieldPosition firstFieldPosition = getFirstItem(grid); + + PositionForm form = positionView.getForm(); + + assertFalse(form.isVisible()); + grid.asSingleSelect().setValue(firstFieldPosition); + assertTrue(form.isVisible()); + assertEquals(firstFieldPosition.getName(), form.name.getValue()); + } + + private FieldPosition getFirstItem(Grid grid) { + int count = grid.getListDataView().getItemCount(); + List positions = grid.getListDataView().getItems().collect(Collectors.toList()); + assertEquals(44, count); + return positions.get(0); + } +} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/PlayerViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/PlayerViewTest.java new file mode 100644 index 0000000..dbc031a --- /dev/null +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/PlayerViewTest.java @@ -0,0 +1,44 @@ +package de.thpeetz.kontor.views.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.vaadin.flow.component.grid.Grid; + +import de.thpeetz.kontor.data.tysc.Player; + +@SpringBootTest +class PlayerViewTest { + + @Autowired + private PlayerView playerView; + + @Test + void formShownWhenPlayerSelected() { + Grid grid = playerView.getGrid(); + Player firstPlayer = getFirstItem(grid); + + PlayerForm form = playerView.getForm(); + + assertFalse(form.isVisible()); + grid.asSingleSelect().setValue(firstPlayer); + assertTrue(form.isVisible()); + assertEquals(firstPlayer.getLastName(), form.lastName.getValue()); + assertEquals(firstPlayer.getFirstName(), form.firstName.getValue()); + } + + private Player getFirstItem(Grid grid) { + int count = grid.getListDataView().getItemCount(); + List players = grid.getListDataView().getItems().collect(Collectors.toList()); + assertEquals(38, count); + return players.get(0); + } +} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/RoosterViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/RoosterViewTest.java new file mode 100644 index 0000000..0946532 --- /dev/null +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/RoosterViewTest.java @@ -0,0 +1,43 @@ +package de.thpeetz.kontor.views.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.vaadin.flow.component.grid.Grid; + +import de.thpeetz.kontor.data.tysc.Rooster; + +@SpringBootTest +class RoosterViewTest { + + @Autowired + private RoosterView roosterView; + + @Test + void formShownWhenRoosterSelected() { + Grid grid = roosterView.getGrid(); + Rooster firstRooster = getFirstItem(grid); + + RoosterForm form = roosterView.getForm(); + + assertFalse(form.isVisible()); + grid.asSingleSelect().setValue(firstRooster); + assertTrue(form.isVisible()); + assertEquals(firstRooster.getYear(), form.year.getValue()); + } + + private Rooster getFirstItem(Grid grid) { + int count = grid.getListDataView().getItemCount(); + List roosters = grid.getListDataView().getItems().collect(Collectors.toList()); + assertEquals(11, count); + return roosters.get(0); + } +} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/SportViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/SportViewTest.java new file mode 100644 index 0000000..584a0df --- /dev/null +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/SportViewTest.java @@ -0,0 +1,43 @@ +package de.thpeetz.kontor.views.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.vaadin.flow.component.grid.Grid; + +import de.thpeetz.kontor.data.tysc.Sport; + +@SpringBootTest +class SportViewTest { + + @Autowired + private SportView sportView; + + @Test + void formShownWhenSportSelected() { + Grid grid = sportView.getGrid(); + Sport firstSport = getFirstItem(grid); + + SportForm form = sportView.getForm(); + + assertFalse(form.isVisible()); + grid.asSingleSelect().setValue(firstSport); + assertTrue(form.isVisible()); + assertEquals(firstSport.getName(), form.name.getValue()); + } + + private Sport getFirstItem(Grid grid) { + int count = grid.getListDataView().getItemCount(); + List sports = grid.getListDataView().getItems().collect(Collectors.toList()); + assertEquals(4, count); + return sports.get(0); + } +} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/TeamViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/TeamViewTest.java new file mode 100644 index 0000000..02792cd --- /dev/null +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/TeamViewTest.java @@ -0,0 +1,43 @@ +package de.thpeetz.kontor.views.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.vaadin.flow.component.grid.Grid; + +import de.thpeetz.kontor.data.tysc.Team; + +@SpringBootTest +class TeamViewTest { + + @Autowired + private TeamView teamView; + + @Test + void formShownWhenTeamSelected() { + Grid grid = teamView.getGrid(); + Team firstTeam = getFirstItem(grid); + + TeamForm form = teamView.getForm(); + + assertFalse(form.isVisible()); + grid.asSingleSelect().setValue(firstTeam); + assertTrue(form.isVisible()); + assertEquals(firstTeam.getName(), form.name.getValue()); + } + + private Team getFirstItem(Grid grid) { + int count = grid.getListDataView().getItemCount(); + List teams = grid.getListDataView().getItems().collect(Collectors.toList()); + assertEquals(122, count); + return teams.get(0); + } +} diff --git a/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/VendorViewTest.java b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/VendorViewTest.java new file mode 100644 index 0000000..9bc160e --- /dev/null +++ b/kontor-spring/src/integrationTest/java/de/thpeetz/kontor/views/tysc/VendorViewTest.java @@ -0,0 +1,43 @@ +package de.thpeetz.kontor.views.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.vaadin.flow.component.grid.Grid; + +import de.thpeetz.kontor.data.tysc.Vendor; + +@SpringBootTest +class VendorViewTest { + + @Autowired + private VendorView vendorView; + + @Test + void formShownWhenVendorSelected() { + Grid grid = vendorView.getGrid(); + Vendor firstVendor = getFirstItem(grid); + + VendorForm form = vendorView.getForm(); + + assertFalse(form.isVisible()); + grid.asSingleSelect().setValue(firstVendor); + assertTrue(form.isVisible()); + assertEquals(firstVendor.getName(), form.name.getValue()); + } + + private Vendor getFirstItem(Grid grid) { + int count = grid.getListDataView().getItemCount(); + List vendors = grid.getListDataView().getItems().collect(Collectors.toList()); + assertEquals(9, count); + return vendors.get(0); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/Application.java b/kontor-spring/src/main/java/de/thpeetz/kontor/Application.java index c304f35..fe481c7 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/Application.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/Application.java @@ -1,15 +1,28 @@ package de.thpeetz.kontor; +import org.apache.camel.CamelContext; +import org.apache.camel.component.micrometer.MicrometerConstants; +import org.apache.camel.component.micrometer.messagehistory.MicrometerMessageHistoryFactory; +import org.apache.camel.component.micrometer.routepolicy.MicrometerRoutePolicyFactory; +import org.apache.camel.spring.boot.CamelContextConfiguration; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; import com.vaadin.flow.component.page.AppShellConfigurator; import com.vaadin.flow.server.PWA; import com.vaadin.flow.theme.Theme; +import io.micrometer.core.instrument.Clock; +import io.micrometer.prometheus.PrometheusConfig; +import io.micrometer.prometheus.PrometheusMeterRegistry; +import io.prometheus.client.CollectorRegistry; import lombok.extern.slf4j.Slf4j; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + + @Slf4j @EnableJpaAuditing @SpringBootApplication @@ -17,6 +30,27 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @PWA(name = "Vaadin Kontor", shortName = "Kontor", offlinePath = "offline.html", offlineResources = { "images/offline.png" }) public class Application implements AppShellConfigurator { + @Bean(name = { MicrometerConstants.METRICS_REGISTRY_NAME, "prometheusMeterRegistry" }) + public PrometheusMeterRegistry prometheusMeterRegistry( + PrometheusConfig prometheusConfig, CollectorRegistry collectorRegistry, Clock clock) { + return new PrometheusMeterRegistry(prometheusConfig, collectorRegistry, clock); + } + + @Bean + public CamelContextConfiguration camelContextConfiguration(@Autowired PrometheusMeterRegistry registry) { + return new CamelContextConfiguration() { + @Override + public void beforeApplicationStart(CamelContext camelContext) { + camelContext.addRoutePolicyFactory(new MicrometerRoutePolicyFactory()); + camelContext.setMessageHistoryFactory(new MicrometerMessageHistoryFactory()); + } + + @Override + public void afterApplicationStart(CamelContext camelContext) { + } + }; + } + public static void main(String[] args) { log.info("Starting Kontor application"); SpringApplication.run(Application.class); diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/AdminConstants.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/AdminConstants.java deleted file mode 100644 index 5beefb1..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/AdminConstants.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.thpeetz.kontor.admin; - -import com.vaadin.flow.component.icon.VaadinIcon; -import com.vaadin.flow.component.sidenav.SideNavItem; -import com.vaadin.flow.router.RouterLink; -import de.thpeetz.kontor.admin.views.AssignmentView; -import de.thpeetz.kontor.admin.views.PermissionView; -import de.thpeetz.kontor.admin.views.ProfileView; -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.comics.views.ComicWorkView; -import de.thpeetz.kontor.comics.views.IssueWorkView; -import de.thpeetz.kontor.media.MediaConstants; -import de.thpeetz.kontor.media.views.MediaActorFileView; - -public class AdminConstants { - - private AdminConstants() { - // private constructor to hide the implicit public one - } - - public static final String ADMIN_TITLE = "Verwaltung"; - public static final String AUTHORIZATION = "Berechtigungen"; - public static final String ASSIGNMENT_ROUTE = "/admin/assignment"; - public static final String DATA = "Daten"; - public static final String METADATA_ROUTE = "admin/metadata"; - public static final String PERMISSION = "Berechtigungen"; - public static final String PERMISSION_ROUTE = "/admin/permission"; - public static final String PROFILE = "Benutzer"; - public static final String PROFILE_ROUTE = "/admin/profile"; - public static final String ADMIN = "admin"; - public static final String ADMIN_ROUTE = "/admin"; - - public static RouterLink getProfileNavigation() { - return new RouterLink(PROFILE, ProfileView.class); - } - - public static RouterLink getPermissionNavigation() { - return new RouterLink(PERMISSION, PermissionView.class); - } - - public static RouterLink getAuthorizationNavigation() { - return new RouterLink(AUTHORIZATION, AssignmentView.class); - } - - public static SideNavItem getAdminNavigation() { - SideNavItem administration = new SideNavItem(ADMIN_TITLE, PROFILE_ROUTE, VaadinIcon.GROUP.create()); - administration.addItem(new SideNavItem(PROFILE, PROFILE_ROUTE, VaadinIcon.USERS.create())); - administration.addItem(new SideNavItem(PERMISSION, PermissionView.class)); - SideNavItem data = new SideNavItem(DATA, ASSIGNMENT_ROUTE, VaadinIcon.DATABASE.create()); - data.addItem(new SideNavItem(ComicConstants.COMICWORK, ComicWorkView.class)); - data.addItem(new SideNavItem(ComicConstants.ISSUEWORK, IssueWorkView.class)); - data.addItem(new SideNavItem(MediaConstants.MEDIAACTORFILE, MediaActorFileView.class)); - data.addItem(new SideNavItem(AUTHORIZATION, AssignmentView.class)); - administration.addItem(data); - return administration; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/MailProperties.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/MailProperties.java deleted file mode 100644 index 9e8a6b4..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/MailProperties.java +++ /dev/null @@ -1,78 +0,0 @@ -package de.thpeetz.kontor.admin; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -import org.springframework.stereotype.Component; - -@Component -@ConfigurationProperties(prefix = "mail") -public class MailProperties { - - private String protocol; - private String host; - private Integer port; - private String userName; - private String password; - private Boolean startTls; - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public String getHost() { - return host; - } - - public void setHost(String host) { - this.host = host; - } - - public Integer getPort() { - return port; - } - - public void setPort(Integer port) { - this.port = port; - } - - public Boolean getStartTls() { - return startTls; - } - - public void setStartTls(Boolean startTls) { - this.startTls = startTls; - } - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - @Override - public String toString() { - final StringBuffer sb = new StringBuffer("MailProperties{"); - sb.append("protocol='").append(protocol).append('\''); - sb.append(", host='").append(host).append('\''); - sb.append(", port=").append(port); - sb.append(", starttls=").append(startTls); - sb.append(", userName='").append(userName).append('\''); - sb.append(", password='").append(password).append('\''); - sb.append('}'); - return sb.toString(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/SetupModuleAdmin.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/SetupModuleAdmin.java deleted file mode 100644 index 47ffacf..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/SetupModuleAdmin.java +++ /dev/null @@ -1,126 +0,0 @@ -package de.thpeetz.kontor.admin; - -import de.thpeetz.kontor.admin.data.Permission; -import de.thpeetz.kontor.admin.data.Profile; -import de.thpeetz.kontor.admin.data.Assignment; -import de.thpeetz.kontor.admin.repository.AssignmentRepository; -import de.thpeetz.kontor.admin.repository.ProfileRepository; -import de.thpeetz.kontor.admin.repository.MailAccountRepository; -import de.thpeetz.kontor.admin.services.AdminService; -import de.thpeetz.kontor.mailclient.data.MailAccount; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Component; - -import java.util.Collection; -import java.util.List; - -@Slf4j -@Component -public class SetupModuleAdmin implements ApplicationListener { - boolean alreadySetup = false; - - @Autowired - private ProfileRepository profileRepository; - - @Autowired - private AssignmentRepository assignmentRepository; - - @Autowired - private PasswordEncoder passwordEncoder; - - @Autowired - private MailAccountRepository mailAccountRepository; - - @Autowired - private MailProperties mailProperties; - - @Autowired - private AdminService adminService; - - @Override - public void onApplicationEvent(ContextRefreshedEvent event) { - if (alreadySetup) { - return; - } - - // Create initial roles and users - Permission adminPermission = adminService.addPermission("ROLE_ADMIN"); - Permission userPermission = adminService.addPermission("ROLE_USER"); - List profiles = profileRepository.findAll(); - if (profiles.isEmpty()) { - Profile adminProfile = initAdminUser(); - initAssignments(adminPermission, adminProfile); - initAssignments(userPermission, adminProfile); - } - log.info("MailProperties: {}", mailProperties); - initMail(mailProperties); - } - - private void initMail(MailProperties mailProperties) { - log.info("initMail: Host {} with User {}", mailProperties.getHost(), mailProperties.getUserName()); - if (mailProperties.getHost() == null || mailProperties.getHost().isEmpty()) { - return; - } - boolean addMailAccount = false; - List mailAccounts = mailAccountRepository.findAll(); - if (mailAccounts.isEmpty()) { - addMailAccount = true; - } - for (MailAccount mailAccount : mailAccounts) { - String accountUser = mailAccount.getUserName(); - String propertyUser = mailProperties.getUserName(); - String accountHost = mailAccount.getHost(); - String propertyHost = mailProperties.getHost(); - if (propertyHost.equals(accountHost) && propertyUser.equals(accountUser)) { - log.debug("already configured: {}", mailAccount); - } else { - addMailAccount = true; - } - } - if (addMailAccount) { - log.info("add Mail Account: {}", mailProperties); - MailAccount mailAccount = new MailAccount(); - mailAccount.setProtocol(mailProperties.getProtocol()); - mailAccount.setHost(mailProperties.getHost()); - mailAccount.setPort(mailProperties.getPort()); - mailAccount.setUserName(mailProperties.getUserName()); - mailAccount.setPassword(mailProperties.getPassword()); - mailAccount.setStartTls(mailProperties.getStartTls()); - mailAccountRepository.save(mailAccount); - } - } - - private void initAssignments(Permission permission, Profile profile) { - log.info("initAssignments: Permission {} for Profile {}", permission.getName(), profile.getUserName()); - Collection configuredRoles = assignmentRepository.findByProfile(profile); - if (configuredRoles.stream().anyMatch(assignment -> assignment.getPermission().getId().equals(permission.getId()))) { - log.info("Permission {} already defined", permission.getName()); - } else { - log.info("add Permission {} to Profile {}", permission.getName(), profile.getUserName()); - final Assignment assignment = new Assignment(); - assignment.setProfile(profile); - assignment.setPermission(permission); - assignmentRepository.save(assignment); - } - } - - private Profile initAdminUser() { - log.info("initAdminUser"); - Profile admin = profileRepository.findByUserName("admin"); - if (admin == null) { - log.info("Profile admin not found, will be created."); - admin = new Profile(); - admin.setFirstName("Admin"); - admin.setLastName("Administrator"); - admin.setUserName("admin"); - admin.setEmail("admin@example.org"); - admin.setPassword(passwordEncoder.encode("admin")); - profileRepository.save(admin); - } - return admin; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/Assignment.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/Assignment.java deleted file mode 100644 index 0f1f3ab..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/Assignment.java +++ /dev/null @@ -1,34 +0,0 @@ -package de.thpeetz.kontor.admin.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity -public class Assignment extends AbstractEntity { - - @ManyToOne - @JoinColumn(name = "profile_id") - @NotNull - private Profile profile; - - @ManyToOne - @JoinColumn(name = "permission_id") - @NotNull - private Permission permission; - - @Override - public String toString() { - final StringBuffer sb = new StringBuffer("Assignment{"); - sb.append("profile=").append(profile.getUserName()); - sb.append(", permission=").append(permission.getName()); - sb.append('}'); - return sb.toString(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/Permission.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/Permission.java deleted file mode 100644 index d5d27a0..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/Permission.java +++ /dev/null @@ -1,29 +0,0 @@ -package de.thpeetz.kontor.admin.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.OneToMany; -import jakarta.validation.constraints.NotEmpty; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import lombok.extern.slf4j.Slf4j; - -import javax.annotation.Nullable; -import java.util.List; - -@Slf4j -@Getter -@Setter -@ToString -@Entity -public class Permission extends AbstractEntity { - - @NotEmpty - private String name; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "permission") - @Nullable - private List assignments; -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/Profile.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/Profile.java deleted file mode 100644 index 8773fb5..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/Profile.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.thpeetz.kontor.admin.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.*; -import jakarta.validation.constraints.NotEmpty; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import lombok.extern.slf4j.Slf4j; - -import javax.annotation.Nullable; -import java.util.LinkedList; -import java.util.List; - -@Slf4j -@Getter -@Setter -@ToString -@Entity -@Table(indexes = @Index(columnList = "userName"), uniqueConstraints = @UniqueConstraint(columnNames = {"userName"})) -public class Profile extends AbstractEntity { - - private String firstName; - - private String lastName; - - @NotEmpty - private String userName; - - private String email; - - private String password; - - private boolean enabled; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "profile") - @Nullable - private List assignments = new LinkedList<>(); - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "profile") - @Nullable - private List tokens = new LinkedList<>(); - - public String getFullName() { - StringBuilder fullNameBuilder = new StringBuilder(); - if (firstName != null) { - fullNameBuilder.append(firstName); - } - if (lastName != null) { - if (!fullNameBuilder.isEmpty()) { - fullNameBuilder.append(" "); - } - fullNameBuilder.append(lastName); - } - return fullNameBuilder.toString(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/Token.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/Token.java deleted file mode 100644 index afd4167..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/Token.java +++ /dev/null @@ -1,37 +0,0 @@ -package de.thpeetz.kontor.admin.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.Index; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import lombok.extern.slf4j.Slf4j; -import java.util.Date; - -@Slf4j -@Getter -@Setter -@ToString -@Entity -@Table(indexes = @Index(columnList = "token"), uniqueConstraints = @UniqueConstraint(columnNames = {"token"})) -public class Token extends AbstractEntity { - - private String token; - - private String name; - - private Date lastUsedDate; - - private boolean enabled; - - @ManyToOne - @JoinColumn(name="profile_id") - @NotNull - private Profile profile; -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/AssignmentRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/AssignmentRepository.java deleted file mode 100644 index eb20059..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/AssignmentRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.thpeetz.kontor.admin.repository; - -import de.thpeetz.kontor.admin.data.*; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface AssignmentRepository extends JpaRepository { - - List findByProfile(Profile profile); - - List findByPermission(Permission permission); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/MailAccountRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/MailAccountRepository.java deleted file mode 100644 index 1cd3885..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/MailAccountRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.thpeetz.kontor.admin.repository; - -import de.thpeetz.kontor.mailclient.data.MailAccount; -import org.springframework.data.jpa.repository.JpaRepository; - - -public interface MailAccountRepository extends JpaRepository { -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/PermissionRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/PermissionRepository.java deleted file mode 100644 index 9e6e863..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/PermissionRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.thpeetz.kontor.admin.repository; - -import de.thpeetz.kontor.admin.data.Permission; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import java.util.List; - -public interface PermissionRepository extends JpaRepository { - - @Query("select p from Permission p " + - "where lower(p.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - @Query("select p from Permission p " + - "where lower(p.name) like lower(:name) ") - Permission findByName(@Param("name") String name); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/ProfileRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/ProfileRepository.java deleted file mode 100644 index 6edf48c..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/ProfileRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.thpeetz.kontor.admin.repository; - -import de.thpeetz.kontor.admin.data.Profile; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import java.util.List; -import java.util.UUID; - -public interface ProfileRepository extends JpaRepository { - - @Query("select p from Profile p " + - "where lower(p.lastName) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - Profile findByUserName(String userName); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/AdminService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/AdminService.java deleted file mode 100644 index 0bffa05..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/AdminService.java +++ /dev/null @@ -1,107 +0,0 @@ -package de.thpeetz.kontor.admin.services; - -import java.util.Collection; -import java.util.List; - -import de.thpeetz.kontor.admin.data.*; -import de.thpeetz.kontor.admin.repository.*; -import org.springframework.stereotype.Service; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Service -public class AdminService { - - - private final ProfileRepository profileRepository; - private final PermissionRepository permissionRepository; - private final AssignmentRepository assignmentRepository; - - public AdminService(ProfileRepository profileRepository, - PermissionRepository permissionRepository, - AssignmentRepository assignmentRepository) { - this.profileRepository = profileRepository; - this.permissionRepository = permissionRepository; - this.assignmentRepository = assignmentRepository; - } - - public List findAllProfiles() { return profileRepository.findAll(); } - - public Profile getProfile(String userName) { - log.debug("get Profile {}", userName); - return profileRepository.findByUserName(userName); - } - - public List findAllPermissions() { return permissionRepository.findAll(); } - - public Collection findAllPermissions(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return permissionRepository.findAll(); - } else { - return permissionRepository.search(stringFilter); - } - } - - public Permission addPermission(String permissionName) { - Permission permission = permissionRepository.findByName(permissionName); - if (permission == null) { - log.info("Permission {} was not found, will create it.", permissionName); - permission = new Permission(); - permission.setName(permissionName); - permissionRepository.save(permission); - } - return permission; - } - - public void savePermission(Permission permission) { - if (permission == null) { - log.warn("Permission is null. Can't save it."); - } - log.info("savePermission: permission={}", permission); - permissionRepository.save(permission); - } - - public void deletePermission(Permission permission) { - if (permission == null) { - log.warn("Permission is null. Can't delete it."); - return; - } - log.info("deletePermission: permission={}", permission); - permissionRepository.delete(permission); - } - - public List findAllAssignments() { - return assignmentRepository.findAll(); - } - - public void saveAssignment(Assignment assignment) { - if (assignment == null) { - log.warn("Assignment is null. Can't save it."); - return; - } - log.info("saveAssignment: assignment={}", assignment); - assignmentRepository.save(assignment); - } - - public void deleteAssignment(Assignment assignment) { - if (assignment == null) { - log.warn("Assignment is null. Can't delete it."); - return; - } - log.info("deleteAssignment: assignment={}", assignment); - assignmentRepository.delete(assignment); - } - - public String getProfileFullName(String userName) { - log.debug("get Fullname für Profile {}", userName); - Profile profile = profileRepository.findByUserName(userName); - if (profile == null) { - log.info("keinen Eintrag für {} gefunden", userName); - return userName; - } else { - log.info("Voller Name des Profile {}: {}", userName, profile.getFullName()); - return profile.getFullName(); - } - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/KontorUserDetailsService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/KontorUserDetailsService.java deleted file mode 100644 index 21f76ac..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/KontorUserDetailsService.java +++ /dev/null @@ -1,133 +0,0 @@ -package de.thpeetz.kontor.admin.services; - -import de.thpeetz.kontor.admin.data.Assignment; -import de.thpeetz.kontor.admin.data.Profile; -import de.thpeetz.kontor.admin.data.Permission; -import de.thpeetz.kontor.admin.repository.AssignmentRepository; -import de.thpeetz.kontor.admin.repository.ProfileRepository; -import de.thpeetz.kontor.admin.repository.PermissionRepository; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Service; - -import java.math.BigInteger; -import java.security.SecureRandom; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -@Slf4j -@Service("userDetailsService") -public class KontorUserDetailsService implements UserDetailsService { - - private static final SecureRandom random = new SecureRandom(); - - @Autowired - private ProfileRepository profileRepository; - - @Autowired - private PermissionRepository permissionRepository; - - @Autowired - private AssignmentRepository assignmentRepository; - - public Collection findAllProfiles(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return profileRepository.findAll(); - } else { - return profileRepository.search(stringFilter); - } - } - - public void saveProfile(Profile profile) { - if (profile == null) { - log.warn("Profile is null. Can't save it."); - return; - } - log.info("saveProfile: profile={}", profile); - profileRepository.save(profile); - } - - public void saveProfile(Profile profile, List permissions) { - if (profile == null) { - log.warn("Profile is null. Can't save it."); - return; - } - log.info("First save Profile: {}", profile); - profile = profileRepository.save(profile); - List copy = permissions.stream().collect(Collectors.toList()); - List assignments = profile.getAssignments(); - assignments.forEach(assignment -> { - if (permissions.contains(assignment.getPermission())) { - log.info("Permission {} already assigned", assignment.getPermission()); - copy.remove(assignment.getPermission()); - } else { - log.info("Permission {} has to be removed", assignment.getPermission()); - assignmentRepository.delete(assignment); - } - }); - log.info("remaining roles: {}", copy); - for (Permission permission : copy) { - Assignment assignment = new Assignment(); - assignment.setProfile(profile); - assignment.setPermission(permission); - assignmentRepository.save(assignment); - } - } - - public void deleteProfile(Profile profile) { - if (profile == null) { - log.warn("Profile is null. Can't delete it."); - return; - } - log.info("deleteProfile: profile={}", profile); - profileRepository.delete(profile); - } - - @Override - public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { - - log.info("loadUserByUsername: userName={}", userName); - Profile profile = profileRepository.findByUserName(userName); - if (profile == null) { - log.info("User not found"); - return null; - } - - Collection authorities = getAuthorities(profile); - log.info("Profile {} hat Permissions: {}", userName, authorities); - return new org.springframework.security.core.userdetails.User(profile.getUserName(), profile.getPassword(), - authorities); - } - - private Collection getAuthorities(Profile profile) { - return assignmentRepository.findByProfile(profile).stream() - .map(assignment -> assignment.getPermission().getName()) - .map(SimpleGrantedAuthority::new) - .collect(Collectors.toList()); - } - - public String getRememberedUser(String id) { - log.info("getRememberedUser: id={}", id); - return "admin"; - } - - public String rememberUser(String username) { - String randomId = new BigInteger(130, random).toString(32); - log.info("rememberUser: username={}", username); - return randomId; - } - - public void removeRememberedUser(String id) { - log.info("removeRememberedUser: id={}", id); - } - - public List findAllPermissions() { - return permissionRepository.findAll(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/MailService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/MailService.java deleted file mode 100644 index d817197..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/MailService.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.thpeetz.kontor.admin.services; - -import de.thpeetz.kontor.mailclient.data.MailAccount; -import de.thpeetz.kontor.admin.repository.MailAccountRepository; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; - -import org.springframework.stereotype.Service; - -@Slf4j -@Service -public class MailService { - - private final MailAccountRepository mailAccountRepository; - - public MailService(MailAccountRepository mailAccountRepository) { - this.mailAccountRepository = mailAccountRepository; - } - - public List findAllMailAccounts() { - return mailAccountRepository.findAll(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/AdminLayout.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/AdminLayout.java deleted file mode 100644 index fa6dbe7..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/AdminLayout.java +++ /dev/null @@ -1,36 +0,0 @@ -package de.thpeetz.kontor.admin.views; - -import com.vaadin.flow.component.applayout.AppLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.theme.lumo.LumoUtility; - -import de.thpeetz.kontor.admin.AdminConstants; -import de.thpeetz.kontor.admin.services.AdminService; -import de.thpeetz.kontor.common.views.KontorLayoutUtil; -import de.thpeetz.kontor.security.SecurityService; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class AdminLayout extends AppLayout { - - private final AdminService adminService; - - private final SecurityService securityService; - - public AdminLayout(AdminService adminService, SecurityService securityService) { - this.adminService = adminService; - this.securityService = securityService; - - KontorLayoutUtil layout = new KontorLayoutUtil(this, adminService, securityService); - layout.setSecondaryNavigation(getSecondaryNavigation()); - layout.createHeader(AdminConstants.ADMIN_TITLE); - } - - private HorizontalLayout getSecondaryNavigation() { - HorizontalLayout navigation = new HorizontalLayout(); - navigation.addClassNames(LumoUtility.JustifyContent.CENTER, LumoUtility.Gap.SMALL, LumoUtility.Height.MEDIUM); - navigation.add(AdminConstants.getProfileNavigation(), AdminConstants.getPermissionNavigation(), - AdminConstants.getAuthorizationNavigation()); - return navigation; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/AssignmentForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/AssignmentForm.java deleted file mode 100644 index 3dcd115..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/AssignmentForm.java +++ /dev/null @@ -1,112 +0,0 @@ -package de.thpeetz.kontor.admin.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.admin.data.Assignment; -import de.thpeetz.kontor.admin.data.Permission; -import de.thpeetz.kontor.admin.data.Profile; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class AssignmentForm extends FormLayout { - - ComboBox profile = new ComboBox<>("Proile"); - ComboBox permission = new ComboBox<>("Permission"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Assignment.class); - - public AssignmentForm(List profiles, List permissions) { - addClassName("assignment-form"); - binder.bindInstanceFields(this); - - profile.setItems(profiles); - profile.setItemLabelGenerator(Profile::getUserName); - permission.setItems(permissions); - permission.setItemLabelGenerator(Permission::getName); - add(profile, permission, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setAssignment(Assignment assignment) { - binder.setBean(assignment); - } - - public abstract static class AssignmentFormEvent extends ComponentEvent { - private Assignment assignment; - - protected AssignmentFormEvent(AssignmentForm source, Assignment assignment) { - super(source, false); - this.assignment = assignment; - } - - public Assignment getAssignment() { - return assignment; - } - } - - public static class SaveEvent extends AssignmentFormEvent { - SaveEvent(AssignmentForm source, Assignment assignment) { - super(source, assignment); - } - } - - public static class DeleteEvent extends AssignmentFormEvent { - DeleteEvent(AssignmentForm source, Assignment assignment) { - super(source, assignment); - } - } - - public static class CloseEvent extends AssignmentFormEvent { - CloseEvent(AssignmentForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/AssignmentView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/AssignmentView.java deleted file mode 100644 index bc4e547..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/AssignmentView.java +++ /dev/null @@ -1,114 +0,0 @@ -package de.thpeetz.kontor.admin.views; - -import de.thpeetz.kontor.admin.data.Assignment; -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; - -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.admin.AdminConstants; -import de.thpeetz.kontor.admin.services.AdminService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.RolesAllowed; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@SpringComponent -@Scope("prototype") -@RolesAllowed("ROLE_ADMIN") -@Route(value = AdminConstants.ASSIGNMENT_ROUTE, layout = MainLayout.class) -@PageTitle("Authorization | Admin | Kontor") -public class AssignmentView extends VerticalLayout { - - Grid grid = new Grid<>(Assignment.class); - AssignmentForm form; - AdminService service; - - public AssignmentView(AdminService service) { - this.service = service; - addClassName("assignment-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("assignment-grid"); - grid.setSizeFull(); - grid.setColumns("profile.userName", "permission.name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editAssignment(event.getValue())); - } - - private void configureForm() { - form = new AssignmentForm(service.findAllProfiles(), service.findAllPermissions()); - form.setWidth("25em"); - form.addSaveListener(this::saveAssignment); - form.addDeleteListener(this::deleteAssignment); - form.addCloseListener(e -> closeEditor()); - } - - private void saveAssignment(AssignmentForm.SaveEvent event) { - Assignment assignment = event.getAssignment(); - service.saveAssignment(assignment); - updateList(); - closeEditor(); - } - - private void deleteAssignment(AssignmentForm.DeleteEvent event) { - service.deleteAssignment(event.getAssignment()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - Button addAuthorizationMaxtrixButton = new Button("Add permission", click -> addAssignment()); - HorizontalLayout toolbar = new HorizontalLayout(addAuthorizationMaxtrixButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editAssignment(Assignment assignment) { - if (assignment == null) { - closeEditor(); - } else { - form.setAssignment(assignment); - form.setVisible(true); - addClassName("editing"); - } - } - - public void closeEditor() { - form.setAssignment(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addAssignment() { - grid.asSingleSelect().clear(); - editAssignment(new Assignment()); - } - - private void updateList() { - grid.setItems(service.findAllAssignments()); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/LoginView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/LoginView.java deleted file mode 100644 index 286bc03..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/LoginView.java +++ /dev/null @@ -1,51 +0,0 @@ -package de.thpeetz.kontor.admin.views; - -import org.springframework.security.core.context.SecurityContextHolder; - -import com.vaadin.flow.component.html.H1; -import com.vaadin.flow.component.html.Span; -import com.vaadin.flow.component.login.LoginForm; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.router.BeforeEnterEvent; -import com.vaadin.flow.router.BeforeEnterObserver; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.server.auth.AnonymousAllowed; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Route("login") -@PageTitle("Login | Vaadin Kontor") -@AnonymousAllowed -public class LoginView extends VerticalLayout implements BeforeEnterObserver { - - private final LoginForm login = new LoginForm(); - - public LoginView() { - addClassName("login-view"); - setSizeFull(); - setAlignItems(Alignment.CENTER); - setJustifyContentMode(JustifyContentMode.CENTER); - - login.setAction("login"); - - add(new H1("Vaadin Kontor")); - add(new Span("Username: user, Password: password")); - add(new Span("Username: admin, Password: password")); - add(login); - } - - @Override - public void beforeEnter(BeforeEnterEvent beforeEnterEvent) { - log.info("beforeEnter: {}", beforeEnterEvent.getLocation()); - log.info("beforeEnter: {}", SecurityContextHolder.getContext().getAuthentication()); - // inform the user about an authentication error - if (beforeEnterEvent.getLocation() - .getQueryParameters() - .getParameters() - .containsKey("error")) { - login.setError(true); - } - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/PermissionForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/PermissionForm.java deleted file mode 100644 index 521c992..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/PermissionForm.java +++ /dev/null @@ -1,101 +0,0 @@ -package de.thpeetz.kontor.admin.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; -import de.thpeetz.kontor.admin.data.Permission; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class PermissionForm extends FormLayout { - - TextField name = new TextField("Role name"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Permission.class); - - public PermissionForm() { - addClassName("permission-form"); - binder.bindInstanceFields(this); - add(name, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setPermission(Permission permission) { - binder.setBean(permission); - } - - public abstract static class PermissionFormEvent extends ComponentEvent { - private Permission permission; - - protected PermissionFormEvent(PermissionForm source, Permission permission) { - super(source, false); - this.permission = permission; - } - - public Permission getPermission() { - return permission; - } - } - - public static class SaveEvent extends PermissionFormEvent { - SaveEvent(PermissionForm source, Permission permission) { - super(source, permission); - } - } - - public static class DeleteEvent extends PermissionFormEvent { - DeleteEvent(PermissionForm source, Permission permission) { - super(source, permission); - } - } - - public static class CloseEvent extends PermissionFormEvent { - CloseEvent(PermissionForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/PermissionView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/PermissionView.java deleted file mode 100644 index f23881d..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/PermissionView.java +++ /dev/null @@ -1,119 +0,0 @@ -package de.thpeetz.kontor.admin.views; - -import de.thpeetz.kontor.admin.data.Permission; -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.admin.AdminConstants; -import de.thpeetz.kontor.admin.services.AdminService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.RolesAllowed; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@SpringComponent -@Scope("prototype") -@RolesAllowed("ROLE_ADMIN") -@Route(value = AdminConstants.PERMISSION_ROUTE, layout = MainLayout.class) -@PageTitle("Permissions | Admin | Kontor") -public class PermissionView extends VerticalLayout { - - Grid grid = new Grid<>(Permission.class); - TextField filterText = new TextField(); - PermissionForm form; - AdminService service; - - public PermissionView(AdminService service) { - this.service = service; - addClassName("permission-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("permission-grid"); - grid.setSizeFull(); - grid.setColumns("name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editPermission(event.getValue())); - } - - private void configureForm() { - form = new PermissionForm(); - form.setWidth("25em"); - form.addSaveListener(this::savePermission); - form.addDeleteListener(this::deletePermission); - form.addCloseListener(e -> closeEditor()); - } - - private void savePermission(PermissionForm.SaveEvent event) { - service.savePermission(event.getPermission()); - updateList(); - closeEditor(); - } - - private void deletePermission(PermissionForm.DeleteEvent event) { - service.deletePermission(event.getPermission()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by user name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - Button addUserButton = new Button("Add user", click -> addPermission()); - HorizontalLayout toolbar = new HorizontalLayout(filterText, addUserButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editPermission(Permission permission) { - if (permission == null) { - closeEditor(); - } else { - form.setPermission(permission); - form.setVisible(true); - addClassName("editing"); - } - } - - public void closeEditor() { - form.setPermission(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addPermission() { - grid.asSingleSelect().clear(); - editPermission(new Permission()); - } - - private void updateList() { - grid.setItems(service.findAllPermissions(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/ProfileForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/ProfileForm.java deleted file mode 100644 index cb3166c..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/ProfileForm.java +++ /dev/null @@ -1,143 +0,0 @@ -package de.thpeetz.kontor.admin.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.checkbox.Checkbox; -import com.vaadin.flow.component.checkbox.CheckboxGroup; -import com.vaadin.flow.component.checkbox.CheckboxGroupVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.EmailField; -import com.vaadin.flow.component.textfield.PasswordField; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; -import de.thpeetz.kontor.admin.data.Permission; -import de.thpeetz.kontor.admin.data.Profile; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; - -@Slf4j -public class ProfileForm extends FormLayout { - - TextField userName = new TextField("User name"); - PasswordField password = new PasswordField("Password"); - EmailField email = new EmailField("Email"); - TextField firstName = new TextField("First name"); - TextField lastName = new TextField("Last name"); - Checkbox enabled = new Checkbox("Enabled"); - String originalPassword; - - CheckboxGroup permissionList = new CheckboxGroup<>("Permissions"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Profile.class); - - public ProfileForm() { - addClassName("profile-form"); - binder.bindInstanceFields(this); - add(userName, password, email, firstName, lastName, enabled, configurePermissionsGroup(), createButtonsLayout()); - } - - private CheckboxGroup configurePermissionsGroup() { - permissionList.addThemeVariants(CheckboxGroupVariant.LUMO_VERTICAL); - permissionList.setItemLabelGenerator(Permission::getName); - permissionList.addValueChangeListener(event -> { - log.debug("permissions changed: {}", event); - }); - return permissionList; - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new ProfileForm.DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new ProfileForm.CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new ProfileForm.SaveEvent(this, binder.getBean())); - } - } - - public void setProfile(Profile profile) { - binder.setBean(profile); - //log.debug("UserForm.setUser: {}", user); - if (profile != null) { - this.originalPassword = profile.getPassword(); - } else { - this.originalPassword = null; - } - } - - public void setPermissions(List permissions, Profile profile) { - permissionList.setItems(permissions); - profile.getAssignments().stream().forEach(assignment -> { - permissionList.select(assignment.getPermission()); - }); - } - - public boolean hasPasswordChanged(Profile profile) { - return !originalPassword.equals(profile.getPassword()); - } - - public abstract static class ProfileFormEvent extends ComponentEvent { - private Profile profile; - - protected ProfileFormEvent(ProfileForm source, Profile profile) { - super(source, false); - this.profile = profile; - } - - public Profile getProfile() { - return profile; - } - } - - public static class SaveEvent extends ProfileForm.ProfileFormEvent { - SaveEvent(ProfileForm source, Profile profile) { - super(source, profile); - } - } - - public static class DeleteEvent extends ProfileForm.ProfileFormEvent { - DeleteEvent(ProfileForm source, Profile profile) { - super(source, profile); - } - } - - public static class CloseEvent extends ProfileForm.ProfileFormEvent { - CloseEvent(ProfileForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(ProfileForm.DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(ProfileForm.SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(ProfileForm.CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/ProfileView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/ProfileView.java deleted file mode 100644 index 16bc6b0..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/ProfileView.java +++ /dev/null @@ -1,135 +0,0 @@ -package de.thpeetz.kontor.admin.views; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; -import de.thpeetz.kontor.admin.data.Permission; -import de.thpeetz.kontor.admin.data.Profile; -import de.thpeetz.kontor.admin.services.KontorUserDetailsService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.RolesAllowed; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.security.crypto.password.PasswordEncoder; - -import java.util.List; -import java.util.stream.Collectors; - -@Slf4j -@SpringComponent -@Scope("prototype") -@RolesAllowed("ROLE_ADMIN") -@Route(value = "admin/profile", layout = MainLayout.class) -@PageTitle("Profile | Admin | Kontor") -public class ProfileView extends VerticalLayout { - - Grid grid = new Grid<>(Profile.class); - TextField filterText = new TextField(); - ProfileForm form; - KontorUserDetailsService service; - - @Autowired - PasswordEncoder passwordEncoder; - - public ProfileView(KontorUserDetailsService service) { - this.service = service; - addClassName("profile-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("profile-grid"); - grid.setSizeFull(); - grid.setColumns("userName", "email", "firstName", "lastName", "enabled"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editProfile(event.getValue())); - } - - private void configureForm() { - form = new ProfileForm(); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveProfile); - form.addDeleteListener(this::deleteProfile); - form.addCloseListener(e -> closeEditor()); - } - - private void saveProfile(ProfileForm.SaveEvent event) { - Profile profile = event.getProfile(); - log.debug("ProfileView.saveProfile: {}", profile); - List permissions = form.permissionList.getSelectedItems().stream().collect(Collectors.toList()); - log.info("selected permissions: {}", permissions); - if (form.hasPasswordChanged(profile)) { - profile.setPassword(passwordEncoder.encode(profile.getPassword())); - log.debug("password changed for profile {}", profile); - } - service.saveProfile(profile, permissions); - updateList(); - closeEditor(); - } - - private void deleteProfile(ProfileForm.DeleteEvent event) { - service.deleteProfile(event.getProfile()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by user name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - Button addProfileButton = new Button("Add profile", click -> addProfile()); - HorizontalLayout toolbar = new HorizontalLayout(filterText, addProfileButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editProfile(Profile profile) { - if (profile == null) { - closeEditor(); - } else { - form.setProfile(profile); - form.setPermissions(service.findAllPermissions(), profile); - form.setVisible(true); - addClassName("editing"); - } - } - - public void closeEditor() { - form.setProfile(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addProfile() { - grid.asSingleSelect().clear(); - editProfile(new Profile()); - } - - private void updateList() { - grid.setItems(service.findAllProfiles(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/UserProfileView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/UserProfileView.java deleted file mode 100644 index ef00bf2..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/views/UserProfileView.java +++ /dev/null @@ -1,73 +0,0 @@ -package de.thpeetz.kontor.admin.views; - -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import de.thpeetz.kontor.admin.data.Profile; -import de.thpeetz.kontor.admin.services.AdminService; -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.security.SecurityService; -import jakarta.annotation.security.PermitAll; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Route(value="user/profile", layout = MainLayout.class) -@PermitAll -@PageTitle("Profile | User | Kontor") -public class UserProfileView extends VerticalLayout { - - private SecurityService securityService; - - private AdminService adminService; - - TextField firstName = new TextField("First name"); - TextField lastName = new TextField("Last name"); - - Button save = new Button("Save"); - Button close = new Button("Cancel"); - Binder binder = new BeanValidationBinder<>(Profile.class); - - public UserProfileView(AdminService adminService, SecurityService securityService) { - this.adminService = adminService; - this.securityService = securityService; - binder.bindInstanceFields(this); - - add(firstName, lastName, createButtonsLayout()); - securityService.getAuthenticatedUser().ifPresent(user -> { - log.info("UserProfileView: {}", user.getUsername()); - binder.setBean(adminService.getProfile(user.getUsername())); - }); - - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - close.addClickListener(event -> closeView()); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - log.info("update user profile"); - } - } - - private void closeView() { - log.info("close user profile view"); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/BookshelfConstants.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/BookshelfConstants.java deleted file mode 100644 index 58661a0..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/BookshelfConstants.java +++ /dev/null @@ -1,53 +0,0 @@ -package de.thpeetz.kontor.bookshelf; - -import com.vaadin.flow.component.icon.VaadinIcon; -import com.vaadin.flow.component.sidenav.SideNav; -import com.vaadin.flow.component.sidenav.SideNavItem; -import com.vaadin.flow.router.RouterLink; - -import de.thpeetz.kontor.bookshelf.views.ArticleView; -import de.thpeetz.kontor.bookshelf.views.AuthorView; -import de.thpeetz.kontor.bookshelf.views.BookView; -import de.thpeetz.kontor.bookshelf.views.BookshelfPublisherView; - -public class BookshelfConstants { - - public static final String AUTHOR = "Author"; - public static final String ARTICLE = "Article"; - public static final String BOOK = "Book"; - public static final String BOOKSHELF = "Bookshelf"; - public static final String PUBLISHER = "Publisher"; - public static final String PUBLISHER_ROUTE = "bookshelf/publisher"; - public static final String AUTHOR_ROUTE = "bookshelf/author"; - public static final String BOOK_ROUTE = "bookshelf/book"; - public static final String ARTICLE_ROUTE = "bookshelf/article"; - - public static RouterLink getPublisherLink() { - return new RouterLink(PUBLISHER, BookshelfPublisherView.class); - } - - public static RouterLink getAuthorLink() { - return new RouterLink(AUTHOR, AuthorView.class); - } - - public static RouterLink getBookLink() { - return new RouterLink(BOOK, BookView.class); - } - - public static RouterLink getArticleLink() { - return new RouterLink(ARTICLE, ArticleView.class); - } - - public static SideNavItem getBookshelfNavigation() { - SideNavItem bookshelf = new SideNavItem(BOOKSHELF, BookView.class, VaadinIcon.OPEN_BOOK.create()); - bookshelf.addItem(new SideNavItem(BOOK, BookView.class)); - bookshelf.addItem(new SideNavItem(PUBLISHER, BookshelfPublisherView.class)); - bookshelf.addItem(new SideNavItem(AUTHOR, AuthorView.class)); - bookshelf.addItem(new SideNavItem(ARTICLE, ArticleView.class)); - return bookshelf; - } - - private BookshelfConstants() { - // private constructor to hide the implicit public one - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/SetupModuleBookshelf.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/SetupModuleBookshelf.java deleted file mode 100644 index f505654..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/SetupModuleBookshelf.java +++ /dev/null @@ -1,46 +0,0 @@ -package de.thpeetz.kontor.bookshelf; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.stereotype.Component; - -import de.thpeetz.kontor.bookshelf.data.ArticleAuthorRepository; -import de.thpeetz.kontor.bookshelf.data.Author; -import de.thpeetz.kontor.bookshelf.data.AuthorRepository; -import de.thpeetz.kontor.bookshelf.data.BookAuthorRepository; -import de.thpeetz.kontor.bookshelf.data.BookRepository; -import de.thpeetz.kontor.bookshelf.data.BookshelfPublisher; -import de.thpeetz.kontor.bookshelf.data.BookshelfPublisherRepository; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Component -public class SetupModuleBookshelf implements ApplicationListener { - - boolean alreadySetup = false; - - @Autowired - private BookshelfPublisherRepository publisherRepository; - - @Autowired - private AuthorRepository authorRepository; - - @Autowired - private ArticleAuthorRepository articleAuthorRepository; - - @Autowired - private BookRepository bookRepository; - - @Autowired - private BookAuthorRepository bookAuthorRepository; - - @Override - public void onApplicationEvent(ContextRefreshedEvent event) { - if (alreadySetup) { - log.info("SetupModuleBookshelf already executed, skipping"); - return; - } - log.info("Set up Bookshelf data"); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/Article.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/Article.java deleted file mode 100644 index 3ee6a16..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/Article.java +++ /dev/null @@ -1,27 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import java.util.LinkedList; -import java.util.List; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.*; -import jakarta.validation.constraints.NotEmpty; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@ToString -@Entity -@Table(indexes = @Index(columnList = "title"), uniqueConstraints = @UniqueConstraint(columnNames = {"title"})) -public class Article extends AbstractEntity { - - @NotEmpty - private String title; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "article") - @Nullable - private List authors = new LinkedList<>(); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/ArticleAuthor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/ArticleAuthor.java deleted file mode 100644 index c2b3851..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/ArticleAuthor.java +++ /dev/null @@ -1,29 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.Index; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity -@Table(indexes = @Index(columnList = "author_id, article_id"), uniqueConstraints = @UniqueConstraint(columnNames = {"author_id", "article_id"})) -public class ArticleAuthor extends AbstractEntity { - - @ManyToOne - @JoinColumn(name = "author_id") - @NotNull - private Author author; - - @ManyToOne - @JoinColumn(name = "article_id") - @NotNull - private Article article; -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/ArticleAuthorRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/ArticleAuthorRepository.java deleted file mode 100644 index d7933de..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/ArticleAuthorRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import java.util.List; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface ArticleAuthorRepository extends JpaRepository { - - List findByAuthor(Author author); - - List findByArticle(Article article); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/ArticleRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/ArticleRepository.java deleted file mode 100644 index c6b2602..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/ArticleRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import java.util.List; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface ArticleRepository extends JpaRepository { - - @Query("select a from Article a " + - "where lower(a.title) like lower(concat('%', :searchTerm, '%'))") - List
    search(@Param("searchTerm") String searchTerm); - - List
    findByTitle(String title); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/Author.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/Author.java deleted file mode 100644 index 42d83e0..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/Author.java +++ /dev/null @@ -1,44 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import java.util.LinkedList; -import java.util.List; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.Index; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotEmpty; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@ToString -@Entity -@Table(indexes = { - @Index(columnList = "firstName, lastName"), - @Index(columnList = "lastName, firstName") -}, uniqueConstraints = { - @UniqueConstraint(columnNames = { "firstName", "lastName" }) -}) -public class Author extends AbstractEntity { - - @NotEmpty - private String firstName; - - @NotEmpty - private String lastName; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "author") - @Nullable - private List bookAuthors = new LinkedList<>(); - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "author") - @Nullable - private List articleAuthors = new LinkedList<>(); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/AuthorRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/AuthorRepository.java deleted file mode 100644 index 3e87334..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/AuthorRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import java.util.List; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface AuthorRepository extends JpaRepository { - - @Query("select a from Author a " + - "where lower(a.firstName) like lower(concat('%', :searchTerm, '%')) " + - "or lower(a.lastName) like lower(concat('%', :searchTerm, '%'))") - List search(@Param("searchTerm") String searchTerm); - - Author findByFirstNameAndLastName(String firstName, String lastName); - -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/Book.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/Book.java deleted file mode 100644 index e0f6782..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/Book.java +++ /dev/null @@ -1,42 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import java.util.LinkedList; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.*; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@ToString -@Entity -@Table(indexes = @Index(columnList = "title, isbn"), uniqueConstraints = @UniqueConstraint(columnNames = {"isbn"})) -public class Book extends AbstractEntity { - - @NotEmpty - private String title; - - @NotEmpty - private String isbn; - - @Nullable - private int year; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "book") - @Nullable - private List authors = new LinkedList<>(); - - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "publisher_id") - @NotNull - @JsonIgnoreProperties({ "books" }) - private BookshelfPublisher publisher; -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookAuthor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookAuthor.java deleted file mode 100644 index 86a0e10..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookAuthor.java +++ /dev/null @@ -1,29 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.Index; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Entity -@Table(indexes = @Index(columnList = "author_id, book_id"), uniqueConstraints = @UniqueConstraint(columnNames = {"author_id", "book_id"})) -public class BookAuthor extends AbstractEntity { - - @ManyToOne - @JoinColumn(name = "author_id") - @NotNull - private Author author; - - @ManyToOne - @JoinColumn(name = "book_id") - @NotNull - private Book book; -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookAuthorRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookAuthorRepository.java deleted file mode 100644 index a0cf650..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookAuthorRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import java.util.List; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface BookAuthorRepository extends JpaRepository { - - List findByAuthor(Author author); - - List findByBook(Book book); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookRepository.java deleted file mode 100644 index e6ee013..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookRepository.java +++ /dev/null @@ -1,21 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import java.util.List; - -public interface BookRepository extends JpaRepository { - - @Query("select b from Book b " + - "where lower(b.title) like lower(concat('%', :searchTerm, '%')) " + - "or lower(b.isbn) like lower(concat('%', :searchTerm, '%'))") - List search(@Param("searchTerm") String searchTerm); - - List findByTitle(String name); - - List findByTitleIgnoreCase(String name); - - List findByIsbn(String isbn); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookshelfPublisher.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookshelfPublisher.java deleted file mode 100644 index da97d7a..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookshelfPublisher.java +++ /dev/null @@ -1,32 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import java.util.LinkedList; -import java.util.List; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.Index; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotEmpty; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@ToString -@Entity -@Table(indexes = @Index(columnList = "name"), uniqueConstraints = @UniqueConstraint(columnNames = { "name" })) -public class BookshelfPublisher extends AbstractEntity { - - @NotEmpty - private String name; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "publisher", orphanRemoval = true) - @Nullable - List books = new LinkedList<>(); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookshelfPublisherRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookshelfPublisherRepository.java deleted file mode 100644 index b50ba84..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/data/BookshelfPublisherRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import java.util.List; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface BookshelfPublisherRepository extends JpaRepository { - - @Query("select p from BookshelfPublisher p " + - "where lower(p.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - BookshelfPublisher findByName(String name); - - List findByNameIgnoreCase(String name); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/services/BookshelfService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/services/BookshelfService.java deleted file mode 100644 index 6d92a2c..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/services/BookshelfService.java +++ /dev/null @@ -1,118 +0,0 @@ -package de.thpeetz.kontor.bookshelf.services; - -import java.util.List; - -import de.thpeetz.kontor.bookshelf.data.*; -import org.springframework.stereotype.Service; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Service -public class BookshelfService { - - private final AuthorRepository authorRepository; - private final ArticleAuthorRepository articleAuthorRepository; - private final ArticleRepository articleRepository; - private final BookRepository bookRepository; - private final BookAuthorRepository bookAuthorRepository; - private final BookshelfPublisherRepository publisherRepository; - - public BookshelfService(AuthorRepository authorRepository, ArticleAuthorRepository articleAuthorRepository, - ArticleRepository articleRepository, BookRepository bookRepository, - BookAuthorRepository bookAuthorRepository, BookshelfPublisherRepository publisherRepository) { - this.authorRepository = authorRepository; - this.articleAuthorRepository = articleAuthorRepository; - this.articleRepository = articleRepository; - this.bookRepository = bookRepository; - this.bookAuthorRepository = bookAuthorRepository; - this.publisherRepository = publisherRepository; - } - - public List findAllPublishers(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return publisherRepository.findAll(); - } else { - return publisherRepository.search(stringFilter); - } - } - - public BookshelfPublisher findPublisherByName(String publisherName) { - return publisherRepository.findByName(publisherName); - } - - public void deletePublisher(BookshelfPublisher publisher) { - publisherRepository.delete(publisher); - } - - public void savePublisher(BookshelfPublisher publisher) { - if (publisher == null) { - log.warn("Publisher is null. Are you sure you have connected your form to the application?"); - return; - } - publisherRepository.save(publisher); - } - - public List findAllAuthors(String filter) { - if (filter == null || filter.isEmpty()) { - return authorRepository.findAll(); - } else { - return authorRepository.search(filter); - } - } - - public void saveAuthor(Author author) { - if (author == null) { - log.warn("Author is null. Are you sure you have connected your form to the application?"); - return; - } - authorRepository.save(author); - } - - public void deleteAuthor(Author author) { - authorRepository.delete(author); - } - - public List findAllBooks(String filter) { - if (filter == null || filter.isEmpty()) { - return bookRepository.findAll(); - } else { - return bookRepository.search(filter); - } - } - - public void saveBook(Book book) { - if (book == null) { - log.warn("Book is null. Are you sure you have connected your form to the application?"); - return; - } - bookRepository.save(book); - } - - public void deleteBook(Book book) { - BookshelfPublisher publisher = book.getPublisher(); - publisher.getBooks().remove(book); - publisherRepository.save(publisher); - bookRepository.delete(book); - } - - public List
    findAllArticles(String filter) { - if (filter == null || filter.isEmpty()) { - return articleRepository.findAll(); - } else { - return articleRepository.search(filter); - } - } - - public void saveArticle(Article article) { - if (article == null) { - log.warn("Article is null, Are you sure you have connected your form to the application?"); - return; - } - articleRepository.save(article); - } - - public void deleteArticle(Article article) { - articleRepository.delete(article); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/ArticleForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/ArticleForm.java deleted file mode 100644 index 7fb7958..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/ArticleForm.java +++ /dev/null @@ -1,106 +0,0 @@ -package de.thpeetz.kontor.bookshelf.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; -import de.thpeetz.kontor.bookshelf.data.Article; -import de.thpeetz.kontor.bookshelf.data.Author; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; - -@Slf4j -public class ArticleForm extends FormLayout { - - TextField title = new TextField("Title"); - Grid author = new Grid<>(Author.class); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder
    binder = new BeanValidationBinder<>(Article.class); - - public ArticleForm() { - addClassName("article-form"); - binder.bindInstanceFields(this); - - add(title, author, createButtonsLayout()); - } - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new ArticleForm.DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new ArticleForm.CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new ArticleForm.SaveEvent(this, binder.getBean())); - } - } - - public void setArticle(Article article) { - binder.setBean(article); - } - - public abstract static class ArticleFormEvent extends ComponentEvent { - private Article article; - - protected ArticleFormEvent(ArticleForm source, Article article) { - super(source, false); - this.article = article; - } - - public Article getArticle() { - return article; - } - } - - public static class SaveEvent extends ArticleForm.ArticleFormEvent { - SaveEvent(ArticleForm source, Article article) { - super(source, article); - } - } - - public static class DeleteEvent extends ArticleForm.ArticleFormEvent { - DeleteEvent(ArticleForm source, Article article) { - super(source, article); - } - } - - public static class CloseEvent extends ArticleForm.ArticleFormEvent { - CloseEvent(ArticleForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(ArticleForm.DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(ArticleForm.SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(ArticleForm.CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/ArticleView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/ArticleView.java deleted file mode 100644 index 334f577..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/ArticleView.java +++ /dev/null @@ -1,126 +0,0 @@ -package de.thpeetz.kontor.bookshelf.views; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; -import de.thpeetz.kontor.bookshelf.BookshelfConstants; -import de.thpeetz.kontor.bookshelf.data.Article; -import de.thpeetz.kontor.bookshelf.data.Book; -import de.thpeetz.kontor.bookshelf.data.BookAuthor; -import de.thpeetz.kontor.bookshelf.services.BookshelfService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.PermitAll; -import lombok.Getter; -import org.springframework.context.annotation.Scope; - -import java.util.stream.Collectors; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = BookshelfConstants.ARTICLE_ROUTE, layout = MainLayout.class) -@PageTitle("Article | Bookshelf | Kontor") -public class ArticleView extends VerticalLayout { - - @Getter - Grid
    grid = new Grid<>(Article.class); - TextField filterText = new TextField(); - @Getter - ArticleForm form; - BookshelfService service; - - public ArticleView(BookshelfService service) { - this.service = service; - addClassName("article-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("article-grid"); - grid.setSizeFull(); - grid.setColumns("title"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editArticle(event.getValue())); - } - - private void configureForm() { - form = new ArticleForm(); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveArticle); - form.addDeleteListener(this::deleteArticle); - form.addCloseListener(e -> closeEditor()); - } - - private void saveArticle(ArticleForm.SaveEvent event) { - service.saveArticle(event.getArticle()); - updateList(); - closeEditor(); - } - - private void deleteArticle(ArticleForm.DeleteEvent event) { - service.deleteArticle(event.getArticle()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by title or isbn..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addArticleButton = new Button("Add article"); - addArticleButton.addClickListener(click -> addArticle()); - - HorizontalLayout toolbar = new HorizontalLayout(filterText, addArticleButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editArticle(Article article) { - if (article == null) { - closeEditor(); - } else { - form.setArticle(article); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setArticle(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addArticle() { - grid.asSingleSelect().clear(); - editArticle(new Article()); - } - - public void updateList() { - grid.setItems(service.findAllArticles(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/AuthorForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/AuthorForm.java deleted file mode 100644 index 34d0f5d..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/AuthorForm.java +++ /dev/null @@ -1,117 +0,0 @@ -package de.thpeetz.kontor.bookshelf.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.listbox.ListBox; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; -import de.thpeetz.kontor.bookshelf.data.Author; -import de.thpeetz.kontor.bookshelf.data.Book; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; - -@Slf4j -public class AuthorForm extends FormLayout { - - TextField firstName = new TextField("First Name"); - TextField lastName = new TextField("Last Name"); - ListBox books = new ListBox<>(); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Author.class); - - public AuthorForm() { - addClassName("author-form"); - binder.bindInstanceFields(this); - - books.setHeight("100px"); - //books.setColumns("title", "publisher.name"); - //books.getColumns().forEach(col -> col.setAutoWidth(true)); - add(firstName, lastName, books, createButtonsLayout()); - } - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new AuthorForm.DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new AuthorForm.CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new AuthorForm.SaveEvent(this, binder.getBean())); - } - } - - public void setAuthor(Author author) { - binder.setBean(author); - } - - public void setBooks(List books) { - log.info("setting Books: ", books); - this.books.setItems(books); - } - - public abstract static class AuthorFormEvent extends ComponentEvent { - private Author author; - - protected AuthorFormEvent(AuthorForm source, Author author) { - super(source, false); - this.author = author; - } - - public Author getAuthor() { - return author; - } - } - - public static class SaveEvent extends AuthorForm.AuthorFormEvent { - SaveEvent(AuthorForm source, Author author) { - super(source, author); - } - } - - public static class DeleteEvent extends AuthorForm.AuthorFormEvent { - DeleteEvent(AuthorForm source, Author author) { - super(source, author); - } - } - - public static class CloseEvent extends AuthorForm.AuthorFormEvent { - CloseEvent(AuthorForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(AuthorForm.DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(AuthorForm.SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(AuthorForm.CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/AuthorView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/AuthorView.java deleted file mode 100644 index 17897b0..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/AuthorView.java +++ /dev/null @@ -1,132 +0,0 @@ -package de.thpeetz.kontor.bookshelf.views; - -import java.util.stream.Collectors; - -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.bookshelf.BookshelfConstants; -import de.thpeetz.kontor.bookshelf.data.Author; -import de.thpeetz.kontor.bookshelf.data.BookAuthor; -import de.thpeetz.kontor.bookshelf.services.BookshelfService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = BookshelfConstants.AUTHOR_ROUTE, layout = MainLayout.class) -@PageTitle("Author | Bookshelf | Kontor") -public class AuthorView extends VerticalLayout { - - Grid grid = new Grid<>(Author.class); - TextField filterText = new TextField(); - AuthorForm form; - BookshelfService service; - - public AuthorView(BookshelfService service) { - this.service = service; - addClassName("author-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - public Grid getGrid() { - return grid; - } - - public AuthorForm getForm() { - return form; - } - - private void configureGrid() { - grid.addClassName("author-grid"); - grid.setSizeFull(); - grid.setColumns("firstName", "lastName"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editAuthor(event.getValue())); - } - - private void configureForm() { - form = new AuthorForm(); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveAuthor); - form.addDeleteListener(this::deleteAuthor); - form.addCloseListener(e -> closeEditor()); - } - private void saveAuthor(AuthorForm.SaveEvent event) { - service.saveAuthor(event.getAuthor()); - updateList(); - closeEditor(); - } - - private void deleteAuthor(AuthorForm.DeleteEvent event) { - service.deleteAuthor(event.getAuthor()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addAuthorButton = new Button("Add author"); - addAuthorButton.addClickListener(click -> addAuthor()); - - HorizontalLayout toolbar = new HorizontalLayout(filterText, addAuthorButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editAuthor(Author author) { - if (author == null) { - closeEditor(); - } else { - form.setAuthor(author); - form.setBooks(author.getBookAuthors().stream().map(BookAuthor::getBook).collect(Collectors.toList())); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setAuthor(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addAuthor() { - grid.asSingleSelect().clear(); - editAuthor(new Author()); - } - - public void updateList() { - grid.setItems(service.findAllAuthors(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/BookForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/BookForm.java deleted file mode 100644 index 61da274..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/BookForm.java +++ /dev/null @@ -1,111 +0,0 @@ -package de.thpeetz.kontor.bookshelf.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.IntegerField; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; -import de.thpeetz.kontor.bookshelf.data.Book; -import de.thpeetz.kontor.bookshelf.data.BookshelfPublisher; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; - -@Slf4j -public class BookForm extends FormLayout { - - TextField title = new TextField("Title"); - TextField isbn = new TextField("ISBN"); - IntegerField year = new IntegerField("Year"); - ComboBox publisher = new ComboBox<>("Publisher"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Book.class); - - public BookForm(List publishers) { - addClassName("book-form"); - binder.bindInstanceFields(this); - - publisher.setItems(publishers); - publisher.setItemLabelGenerator(BookshelfPublisher::getName); - add(title, isbn, year, publisher, createButtonsLayout()); - } - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new BookForm.DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new BookForm.CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new BookForm.SaveEvent(this, binder.getBean())); - } - } - - public void setBook(Book book) { - binder.setBean(book); - } - - public abstract static class BookFormEvent extends ComponentEvent { - private Book book; - - protected BookFormEvent(BookForm source, Book book) { - super(source, false); - this.book = book; - } - - public Book getBook() { - return book; - } - } - - public static class SaveEvent extends BookForm.BookFormEvent { - SaveEvent(BookForm source, Book book) { - super(source, book); - } - } - - public static class DeleteEvent extends BookForm.BookFormEvent { - DeleteEvent(BookForm source, Book book) { - super(source, book); - } - } - - public static class CloseEvent extends BookForm.BookFormEvent { - CloseEvent(BookForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(BookForm.DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(BookForm.SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(BookForm.CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/BookView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/BookView.java deleted file mode 100644 index 9e04dc6..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/BookView.java +++ /dev/null @@ -1,124 +0,0 @@ -package de.thpeetz.kontor.bookshelf.views; - -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.bookshelf.BookshelfConstants; -import de.thpeetz.kontor.bookshelf.data.Book; -import de.thpeetz.kontor.bookshelf.services.BookshelfService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.PermitAll; -import lombok.Getter; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = BookshelfConstants.BOOK_ROUTE, layout = MainLayout.class) -@PageTitle("Book | Bookshelf | Kontor") -public class BookView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(Book.class); - TextField filterText = new TextField(); - @Getter - BookForm form; - BookshelfService service; - - public BookView(BookshelfService service) { - this.service = service; - addClassName("book-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("book-grid"); - grid.setSizeFull(); - grid.setColumns("title", "isbn", "publisher.name", "year"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editBook(event.getValue())); - } - - private void configureForm() { - form = new BookForm(service.findAllPublishers(null)); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveBook); - form.addDeleteListener(this::deleteBook); - form.addCloseListener(e -> closeEditor()); - } - - private void saveBook(BookForm.SaveEvent event) { - service.saveBook(event.getBook()); - updateList(); - closeEditor(); - } - - private void deleteBook(BookForm.DeleteEvent event) { - service.deleteBook(event.getBook()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by title or isbn..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addBookButton = new Button("Add book"); - addBookButton.addClickListener(click -> addBook()); - - HorizontalLayout toolbar = new HorizontalLayout(filterText, addBookButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editBook(Book book) { - if (book == null) { - closeEditor(); - } else { - form.setBook(book); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setBook(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addBook() { - grid.asSingleSelect().clear(); - editBook(new Book()); - } - - public void updateList() { - grid.setItems(service.findAllBooks(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/BookshelfLayout.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/BookshelfLayout.java deleted file mode 100644 index 6105a47..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/BookshelfLayout.java +++ /dev/null @@ -1,34 +0,0 @@ -package de.thpeetz.kontor.bookshelf.views; - -import com.vaadin.flow.component.applayout.AppLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.theme.lumo.LumoUtility; - -import de.thpeetz.kontor.admin.services.AdminService; -import de.thpeetz.kontor.bookshelf.BookshelfConstants; -import de.thpeetz.kontor.common.views.KontorLayoutUtil; -import de.thpeetz.kontor.security.SecurityService; - -public class BookshelfLayout extends AppLayout { - - private final AdminService adminService; - - private final SecurityService securityService; - - public BookshelfLayout(AdminService adminService, SecurityService securityService) { - this.adminService = adminService; - this.securityService = securityService; - - KontorLayoutUtil layout = new KontorLayoutUtil(this, adminService, securityService); - layout.setSecondaryNavigation(getSecondaryNavigation()); - layout.createHeader(BookshelfConstants.BOOKSHELF); - } - - private HorizontalLayout getSecondaryNavigation() { - HorizontalLayout navigation = new HorizontalLayout(); - navigation.addClassNames(LumoUtility.JustifyContent.CENTER, LumoUtility.Gap.SMALL, LumoUtility.Height.MEDIUM); - navigation.add(BookshelfConstants.getBookLink(), BookshelfConstants.getArticleLink(), - BookshelfConstants.getPublisherLink(), BookshelfConstants.getAuthorLink()); - return navigation; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/BookshelfPublisherView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/BookshelfPublisherView.java deleted file mode 100644 index de5f9b5..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/BookshelfPublisherView.java +++ /dev/null @@ -1,131 +0,0 @@ -package de.thpeetz.kontor.bookshelf.views; - -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.common.views.SeparateMainLayout; -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.bookshelf.BookshelfConstants; -import de.thpeetz.kontor.bookshelf.data.BookshelfPublisher; -import de.thpeetz.kontor.bookshelf.services.BookshelfService; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = BookshelfConstants.PUBLISHER_ROUTE, layout = MainLayout.class) -@PageTitle("Publisher | Bookshelf | Kontor") -public class BookshelfPublisherView extends VerticalLayout { - - Grid grid = new Grid<>(BookshelfPublisher.class); - TextField filterText = new TextField(); - PublisherForm form; - - BookshelfService service; - - public BookshelfPublisherView(BookshelfService service) { - this.service = service; - addClassName("publisher-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("publisher-grid"); - grid.setSizeFull(); - grid.setColumns("name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editPublisher(event.getValue())); - } - - private void configureForm() { - form = new PublisherForm(); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::savePublisher); - form.addDeleteListener(this::deletePublisher); - form.addCloseListener(e -> closeEditor()); - } - - private void savePublisher(PublisherForm.SaveEvent event) { - service.savePublisher(event.getPublisher()); - updateList(); - closeEditor(); - } - - private void deletePublisher(PublisherForm.DeleteEvent event) { - service.deletePublisher(event.getPublisher()); - updateList(); - closeEditor(); - } - - public Grid getGrid() { - return grid; - } - - public PublisherForm getForm() { - return form; - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addPublisherButton = new Button("Add publisher"); - addPublisherButton.addClickListener(click -> addPublisher()); - - HorizontalLayout toolbar = new HorizontalLayout(filterText, addPublisherButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editPublisher(BookshelfPublisher publisher) { - if (publisher == null) { - closeEditor(); - } else { - form.setPublisher(publisher); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setPublisher(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addPublisher() { - grid.asSingleSelect().clear(); - editPublisher(new BookshelfPublisher()); - } - - public void updateList() { - grid.setItems(service.findAllPublishers(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/PublisherForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/PublisherForm.java deleted file mode 100644 index 7b48122..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/bookshelf/views/PublisherForm.java +++ /dev/null @@ -1,108 +0,0 @@ -package de.thpeetz.kontor.bookshelf.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.bookshelf.data.BookshelfPublisher; - -public class PublisherForm extends FormLayout { - private TextField name = new TextField("Name"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder(BookshelfPublisher.class); - - public PublisherForm() { - addClassName("publisher-form"); - binder.bindInstanceFields(this); - - add(name, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public TextField getName() { - return name; - } - - public void setName(TextField name) { - this.name = name; - } - - public void setPublisher(BookshelfPublisher publisher) { - binder.setBean(publisher); - } - - public abstract static class PublisherFormEvent extends ComponentEvent { - private BookshelfPublisher publisher; - - protected PublisherFormEvent(PublisherForm source, BookshelfPublisher publisher) { - super(source, false); - this.publisher = publisher; - } - - public BookshelfPublisher getPublisher() { - return publisher; - } - } - - public static class SaveEvent extends PublisherFormEvent { - SaveEvent(PublisherForm source, BookshelfPublisher publisher) { - super(source, publisher); - } - } - - public static class DeleteEvent extends PublisherFormEvent { - DeleteEvent(PublisherForm source, BookshelfPublisher publisher) { - super(source, publisher); - } - } - - public static class CloseEvent extends PublisherFormEvent { - CloseEvent(PublisherForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/ComicConstants.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/ComicConstants.java deleted file mode 100644 index 2c6c559..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/ComicConstants.java +++ /dev/null @@ -1,101 +0,0 @@ -package de.thpeetz.kontor.comics; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.icon.VaadinIcon; -import com.vaadin.flow.component.sidenav.SideNavItem; -import com.vaadin.flow.router.RouterLink; - -import de.thpeetz.kontor.comics.views.ArtistView; -import de.thpeetz.kontor.comics.views.ComicView; -import de.thpeetz.kontor.comics.views.ComicWorkView; -import de.thpeetz.kontor.comics.views.IssueView; -import de.thpeetz.kontor.comics.views.IssueWorkView; -import de.thpeetz.kontor.comics.views.PublisherView; -import de.thpeetz.kontor.comics.views.StoryArcView; -import de.thpeetz.kontor.comics.views.TradePaperbackView; -import de.thpeetz.kontor.comics.views.VolumeView; -import de.thpeetz.kontor.comics.views.WorktypeView; - -/** - * The {@code ComicConstants} class contains constant values related to comics. - */ -public class ComicConstants { - - public static final String COMICS = "Comics"; - public static final String COMICS_ROUTE = "comics/comic"; - public static final String PUBLISHER = "Publisher"; - public static final String PUBLISHER_ROUTE = "comics/publisher"; - public static final String COMICWORK = "ComicWork"; - public static final String ISSUEWORK = "IssueWork"; - public static final String COMICWORK_ROUTE = "comics/comicwork"; - public static final String ISSUEWORK_ROUTE = "comics/issuework"; - public static final String WORKTYPE = "Worktype"; - public static final String WORKTYPE_ROUTE = "comics/worktype"; - public static final String ARTIST = "Artist"; - public static final String ARTIST_ROUTE = "comics/artist"; - public static final String TPB = "TradePaperback"; - public static final String TPB_ROUTE = "comics/tradepaperback"; - public static final String STORYARC = "Story Arc"; - public static final String STORYARC_ROTE = "comics/storyarc"; - public static final String ISSUE = "Issue"; - public static final String ISSUE_ROUTE = "comics/issue"; - public static final String VOLUME = "Volume"; - public static final String VOLUME_ROUTE = "comics/volume"; - - public static RouterLink getArtistLink() { - return new RouterLink(ARTIST, ArtistView.class); - } - - public static RouterLink getComicLink() { - return new RouterLink(COMICS, ComicView.class); - } - - public static RouterLink getPublisherLink() { - return new RouterLink(PUBLISHER, PublisherView.class); - } - - public static RouterLink getComicWorkLink() { - return new RouterLink(COMICWORK, ComicWorkView.class); - } - - public static RouterLink getIssueWorkLink() { - return new RouterLink(ISSUEWORK, IssueWorkView.class); - } - - public static RouterLink getIssueLink() { - return new RouterLink(ISSUE, IssueView.class); - } - - public static RouterLink getTradePaperbackLink() { - return new RouterLink(TPB, TradePaperbackView.class); - } - - public static Component getStoryArcLink() { - return new RouterLink(STORYARC, StoryArcView.class); - } - - public static RouterLink getWorktypeLink() { - return new RouterLink(WORKTYPE, WorktypeView.class); - } - - public static RouterLink getVolumeLink() { - return new RouterLink(VOLUME, VolumeView.class); - } - - public static SideNavItem getComicsNavigation() { - SideNavItem comics = new SideNavItem(COMICS, COMICS_ROUTE, VaadinIcon.RECORDS.create()); - comics.addItem(new SideNavItem(ARTIST, ArtistView.class)); - comics.addItem(new SideNavItem(COMICS, ComicView.class)); - comics.addItem(new SideNavItem(PUBLISHER, PublisherView.class)); - comics.addItem(new SideNavItem(ISSUE, IssueView.class)); - comics.addItem(new SideNavItem(TPB, TradePaperbackView.class)); - comics.addItem(new SideNavItem(STORYARC, StoryArcView.class)); - comics.addItem(new SideNavItem(VOLUME, VolumeView.class)); - comics.addItem(new SideNavItem(WORKTYPE, WorktypeView.class)); - return comics; - } - - private ComicConstants() { - // private constructor to hide the implicit public one - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/SetupModuleComics.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/SetupModuleComics.java deleted file mode 100644 index 16d716e..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/SetupModuleComics.java +++ /dev/null @@ -1,60 +0,0 @@ -package de.thpeetz.kontor.comics; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.stereotype.Component; - -import de.thpeetz.kontor.comics.repository.ArtistRepository; -import de.thpeetz.kontor.comics.repository.ComicRepository; -import de.thpeetz.kontor.comics.repository.ComicWorkRepository; -import de.thpeetz.kontor.comics.repository.IssueRepository; -import de.thpeetz.kontor.comics.repository.PublisherRepository; -import de.thpeetz.kontor.comics.repository.StoryArcRepository; -import de.thpeetz.kontor.comics.repository.TradePaperbackRepository; -import de.thpeetz.kontor.comics.repository.VolumeRepository; -import de.thpeetz.kontor.comics.repository.WorktypeRepository; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Component -public class SetupModuleComics implements ApplicationListener { - - boolean alreadySetup = false; - - @Autowired - private PublisherRepository publisherRepository; - - @Autowired - private ArtistRepository artistRepository; - - @Autowired - private WorktypeRepository worktypeRepository; - - @Autowired - private ComicRepository comicRepository; - - @Autowired - private ComicWorkRepository comicWorkRepository; - - @Autowired - private StoryArcRepository storyArcRepository; - - @Autowired - private TradePaperbackRepository tradePaperbackRepository; - - @Autowired - private IssueRepository issueRepository; - - @Autowired - private VolumeRepository volumeRepository; - - @Override - public void onApplicationEvent(ContextRefreshedEvent event) { - if (alreadySetup) { - log.info("SetupModuleComics already executed, skipping"); - return; - } - log.info("Set up Comics data"); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Artist.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Artist.java deleted file mode 100644 index 8e14329..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Artist.java +++ /dev/null @@ -1,50 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import java.util.LinkedList; -import java.util.List; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import io.micrometer.common.lang.Nullable; -import jakarta.persistence.CascadeType; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.OneToMany; -import jakarta.validation.constraints.NotEmpty; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; - -/** - * Represents an artist in the system. - */ -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Slf4j -@Entity -public class Artist extends AbstractEntity { - - @NotEmpty - @Column(unique = true) - private String name; - - private String weblink; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "artist", cascade = CascadeType.REFRESH, orphanRemoval = true) - @Nullable - List comicWorks = new LinkedList<>(); - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "artist", cascade = CascadeType.REFRESH, orphanRemoval = true) - @Nullable - List issueWorks = new LinkedList<>(); - - @Override - public String toString() { - final StringBuffer sb = new StringBuffer("Artist{"); - sb.append("name='").append(name).append('\''); - sb.append('}'); - return sb.toString(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Comic.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Comic.java deleted file mode 100644 index d20ea37..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Comic.java +++ /dev/null @@ -1,83 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import java.util.LinkedList; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.CascadeType; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -/** - * Represents a comic entity. - */ -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Entity -public class Comic extends AbstractEntity { - - @NotEmpty - @Column(unique = true) - private String title; - - @ManyToOne - @JoinColumn(name = "publisher_id") - @NotNull - @JsonIgnoreProperties({ "comics" }) - private Publisher publisher; - - private Boolean currentOrder = false; - - private Boolean completed = false; - - @Nullable - private String weblink; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true) - @Nullable - List comicWorks; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true) - @Nullable - private List issues = new LinkedList<>(); - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true) - @Nullable - private List storyArcs = new LinkedList<>(); - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true) - @Nullable - private List tradePaperbacks = new LinkedList<>(); - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true) - @Nullable - private List volumes = new LinkedList<>(); - - @Override - public String toString() { - final StringBuffer sb = new StringBuffer("Comic{"); - sb.append("title='").append(title).append('\''); - sb.append(", publisher=").append(publisher); - sb.append(", currentOrder=").append(currentOrder); - sb.append(", completed=").append(completed); - sb.append('}'); - return sb.toString(); - } - - public String getPublisherName() { - return this.publisher.getName(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/ComicWork.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/ComicWork.java deleted file mode 100644 index 840f93c..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/ComicWork.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.Index; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Entity -@Table(indexes = {@Index(columnList = "comic_id, artist_id, workType_id") }, - uniqueConstraints = @UniqueConstraint(columnNames = {"comic_id", "artist_id", "workType_id" }) -) -public class ComicWork extends AbstractEntity { - - @ManyToOne - @JoinColumn(name = "comic_id") - @NotNull - private Comic comic; - - @ManyToOne - @JoinColumn(name = "artist_id") - @NotNull - private Artist artist; - - @ManyToOne - @JoinColumn(name = "workType_id") - @NotNull - private Worktype workType; - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("ComicWork{"); - sb.append("comic=").append(comic); - sb.append(", artist=").append(artist); - sb.append(", workType=").append(workType); - sb.append('}'); - return sb.toString(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Issue.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Issue.java deleted file mode 100644 index 9d97320..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Issue.java +++ /dev/null @@ -1,108 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import de.thpeetz.kontor.common.data.*; -import io.hypersistence.utils.hibernate.type.basic.YearMonthDateType; -import jakarta.annotation.Nullable; -import jakarta.persistence.*; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.hibernate.annotations.Type; - -import java.time.YearMonth; -import java.util.*; - -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Entity -public class Issue extends AbstractEntity { - - @ManyToOne - @JoinColumn(name = "comic_id") - @NotNull - @JsonIgnoreProperties({ "issues" }) - private Comic comic; - - @ManyToOne - @JoinColumn(name = "volume_id") - @JsonIgnoreProperties({ "issues" }) - @Nullable - private Volume volume; - - @ManyToOne - @JoinColumn(name = "storyArc_id") - @JsonIgnoreProperties({ "issues" }) - @Nullable - private StoryArc storyArc; - - @NotEmpty - private String issueNumber; - - @Nullable - private String title; - - @Nullable - @Type(YearMonthDateType.class) - @Column(name = "published_on", columnDefinition = "date") - private YearMonth publishedOn; - - private Boolean isRead; - - private Boolean inStock; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "issue", cascade = CascadeType.REFRESH, orphanRemoval = true) - @Nullable - List issueWorks; - - public String getComicTitle() { - return comic.getTitle(); - } - - public String getVolumeName() { - if (volume != null) { - return volume.getName(); - } - return null; - } - - public String getFullTitle() { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append(this.getComic().getTitle()); - stringBuilder.append(" #"); - stringBuilder.append(this.getIssueNumber()); - if (this.title !=null && !this.title.isEmpty()) { - stringBuilder.append(": "); - stringBuilder.append(this.title); - } - return stringBuilder.toString(); - } - - @Override - public String toString() { - StringBuilder result = new StringBuilder(); - result.append("Issue{"); - result.append("comic="); - result.append(comic); - result.append(", volume="); - result.append(volume); - result.append(", storyArc="); - result.append(storyArc); - result.append(", issueNumber='"); - result.append(issueNumber); - result.append(", title='"); - result.append(title); - result.append(", publishedOn="); - result.append(publishedOn); - result.append(", isRead="); - result.append(isRead); - result.append(", inStock="); - result.append(inStock); - result.append("}"); - return result.toString(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/IssueWork.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/IssueWork.java deleted file mode 100644 index b9d545c..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/IssueWork.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.Index; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Entity -@Table(indexes = {@Index(columnList = "issue_id, artist_id, workType_id") }, - uniqueConstraints = @UniqueConstraint(columnNames = {"issue_id", "artist_id", "workType_id" }) -) -public class IssueWork extends AbstractEntity { - - @ManyToOne - @JoinColumn(name = "issue_id") - @NotNull - private Issue issue; - - @ManyToOne - @JoinColumn(name = "artist_id") - @NotNull - private Artist artist; - - @ManyToOne - @JoinColumn(name = "workType_id") - @NotNull - private Worktype workType; - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("IssueWork{"); - sb.append("issue=").append(issue); - sb.append(", artist=").append(artist); - sb.append(", workType=").append(workType); - sb.append('}'); - return sb.toString(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Publisher.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Publisher.java deleted file mode 100644 index cd27a43..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Publisher.java +++ /dev/null @@ -1,63 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import java.util.LinkedList; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonBackReference; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.CascadeType; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.Column; -import jakarta.persistence.OneToMany; -import jakarta.persistence.ManyToOne; -import jakarta.validation.constraints.*; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Entity -public class Publisher extends AbstractEntity { - - @NotEmpty - @Column(unique = true) - private String name; - - private String weblink; - - @JsonBackReference - @ManyToOne - @JoinColumn(name = "parent_publisher_id") - @Nullable - @JsonIgnoreProperties({ "comics" }) - private Publisher parentCompany; - - @OneToMany(fetch = FetchType.LAZY, mappedBy = "parentCompany", cascade = CascadeType.ALL, orphanRemoval = true) - @Nullable - private List imprints = new LinkedList<>(); - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "publisher", cascade = CascadeType.ALL, orphanRemoval = true) - @Nullable - private List comics = new LinkedList<>(); - - public String getParentCompanyName() { - if (parentCompany != null) { - return parentCompany.name; - } - return null; - } - - @Override - public String toString() { - final StringBuffer sb = new StringBuffer("Publisher{"); - sb.append("name='").append(name).append('\''); - sb.append('}'); - return sb.toString(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/StoryArc.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/StoryArc.java deleted file mode 100644 index 11d328c..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/StoryArc.java +++ /dev/null @@ -1,46 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import jakarta.annotation.Nullable; -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.CascadeType; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.OneToMany; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -import java.util.*; - -@Getter -@Setter -@ToString -@EqualsAndHashCode(callSuper = false) -@Entity -public class StoryArc extends AbstractEntity { - - @NotEmpty - private String name; - - @ManyToOne - @JoinColumn(name = "comic_id") - @NotNull - @JsonIgnoreProperties({ "storyArcs" }) - private Comic comic; - - @ManyToOne - @JoinColumn(name = "volume_id") - @JsonIgnoreProperties({ "storyArcs" }) - @Nullable - private Volume volume; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "storyArc", cascade = CascadeType.REMOVE, orphanRemoval = true) - @Nullable - private List issues = new LinkedList<>(); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/TradePaperback.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/TradePaperback.java deleted file mode 100644 index 07ee8d3..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/TradePaperback.java +++ /dev/null @@ -1,32 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@ToString -@EqualsAndHashCode(callSuper = false) -@Entity -public class TradePaperback extends AbstractEntity { - - @NotEmpty - private String name; - - @ManyToOne - @JoinColumn(name = "comic_id") - @NotNull - private Comic comic; - - private Integer issueStart; - - private Integer issueEnd; -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Volume.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Volume.java deleted file mode 100644 index 60c3821..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Volume.java +++ /dev/null @@ -1,55 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import java.util.LinkedList; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.*; -import jakarta.persistence.CascadeType; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Entity -public class Volume extends AbstractEntity { - - @NotEmpty - private String name; - - @ManyToOne - @JoinColumn(name = "comic_id") - @NotNull - @JsonIgnoreProperties({ "volumes" }) - private Comic comic; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "volume", cascade = CascadeType.REMOVE, orphanRemoval = true) - @Nullable - private List storyArcs = new LinkedList<>(); - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "volume", cascade = CascadeType.REMOVE, orphanRemoval = true) - @Nullable - private List issues = new LinkedList<>(); - - @Override - public String toString() { - StringBuilder result = new StringBuilder("Volume{"); - result.append("name="); - result.append(name); - result.append("comic=Comic{title="); - result.append(comic.getTitle()); - result.append("}}"); - return result.toString(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Worktype.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Worktype.java deleted file mode 100644 index 0416641..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/data/Worktype.java +++ /dev/null @@ -1,47 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import java.util.LinkedList; -import java.util.List; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import io.micrometer.common.lang.Nullable; -import jakarta.persistence.CascadeType; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.OneToMany; -import jakarta.validation.constraints.NotEmpty; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -/** - * Represents a work type in the application. - * This class extends the AbstractEntity class. - */ -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Entity -public class Worktype extends AbstractEntity { - - @NotEmpty - @Column(unique = true) - private String name; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "workType", cascade = CascadeType.REFRESH, orphanRemoval = true) - @Nullable - List comicWorks = new LinkedList<>(); - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "workType", cascade = CascadeType.REFRESH, orphanRemoval = true) - @Nullable - List issueWorks = new LinkedList<>(); - - @Override - public String toString() { - final StringBuffer sb = new StringBuffer("Worktype{"); - sb.append("name='").append(name).append('\''); - sb.append('}'); - return sb.toString(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ArtistRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ArtistRepository.java deleted file mode 100644 index feff0c0..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ArtistRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface ArtistRepository extends JpaRepository { - @Query("select a from Artist a " + - "where lower(a.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - List findByNameIgnoreCase(String name); - - Artist findByName(String name); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ComicRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ComicRepository.java deleted file mode 100644 index 2da13e1..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ComicRepository.java +++ /dev/null @@ -1,39 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface ComicRepository extends JpaRepository { - @Query("select c from Comic c " + - "where lower(c.title) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - @Query("select c from Comic c " + - "where lower(c.title) like lower(concat('%', :searchTerm, '%')) " + - "AND c.currentOrder=:currentOrder AND c.completed=:completed") - List search(@Param("searchTerm") String searchTerm, Boolean currentOrder, Boolean completed); - - Comic findByTitleAndPublisher(String title, Publisher publisher); - - List findByTitle(String title); - - List findByTitleIgnoreCase(String title); - - List findByCurrentOrderAndCompleted(Boolean currentOrder, Boolean completed); - - List findByCurrentOrder(Boolean currentOrder); - - List findByCompleted(Boolean completed); - - @Query("select c from Comic c " + - "where lower(c.title) like lower(concat('%', :searchTerm, '%')) AND c.currentOrder=:currentOrder") - List searchAndFilterByCurrentOrder(String searchTerm, Boolean currentOrder); - - @Query("select c from Comic c " + - "where lower(c.title) like lower(concat('%', :searchTerm, '%')) AND c.completed=:completed") - List searchAndFilterByCompleted(String searchTerm, Boolean completed); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ComicWorkRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ComicWorkRepository.java deleted file mode 100644 index 9eba50e..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/ComicWorkRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - -public interface ComicWorkRepository extends JpaRepository { - - @Query("SELECT c from ComicWork c where c.comic = ?1 and c.artist = ?2 and c.workType = ?3") - ComicWork findbyComicAndArtistAndWorktype(Comic comic, Artist artist, Worktype worktype); - - @Query("select c from ComicWork c where c.comic = ?1") - List findByComic(Comic comic); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/IssueRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/IssueRepository.java deleted file mode 100644 index 9719304..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/IssueRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface IssueRepository extends JpaRepository { - @Query("select i from Issue i " + - "where lower(i.issueNumber) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - List findByComic(Comic comic); - - Issue findByComicAndIssueNumber(Comic comic, String issueNumber); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/IssueWorkRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/IssueWorkRepository.java deleted file mode 100644 index a2e0347..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/IssueWorkRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import de.thpeetz.kontor.comics.data.*; -import org.springframework.data.jpa.repository.*; - -import java.util.*; - -public interface IssueWorkRepository extends JpaRepository { - - @Query("SELECT i from IssueWork i where i.issue = ?1 and i.artist = ?2 and i.workType = ?3") - IssueWork findbyIssueAndArtistAndWorktype(Issue issue, Artist artist, Worktype worktype); - - @Query("select i from IssueWork i where i.issue = ?1") - List findByIssue(Issue issue); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/PublisherRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/PublisherRepository.java deleted file mode 100644 index 076b32e..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/PublisherRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface PublisherRepository extends JpaRepository { - @Query("select p from Publisher p " + - "where lower(p.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - Publisher findByName(String name); - - List findByNameIgnoreCase(String name); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/StoryArcRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/StoryArcRepository.java deleted file mode 100644 index 23326fb..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/StoryArcRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface StoryArcRepository extends JpaRepository { - @Query("select s from StoryArc s " + - "where lower(s.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - StoryArc findByNameAndComic(String name, Comic comic); - - List findByComic(Comic comic); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/TradePaperbackRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/TradePaperbackRepository.java deleted file mode 100644 index d8c5787..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/TradePaperbackRepository.java +++ /dev/null @@ -1,21 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface TradePaperbackRepository extends JpaRepository { - @Query("select t from TradePaperback t " + - "where lower(t.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - List findByComic(Comic comic); - - List findByNameAndComic(String name, Comic comic); - - @Query("select t from TradePaperback t where t.name = ?1 and t.comic = ?2 and t.issueStart = ?3 and t.issueEnd = ?4") - TradePaperback findByFields(String name, Comic comic, int start, int end); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/VolumeRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/VolumeRepository.java deleted file mode 100644 index cf98406..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/VolumeRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface VolumeRepository extends JpaRepository { - - List findByName(String name); - - List findByComic(Comic comic); - -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/WorktypeRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/WorktypeRepository.java deleted file mode 100644 index 12755c9..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/repository/WorktypeRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface WorktypeRepository extends JpaRepository { - @Query("select w from Worktype w " + - "where lower(w.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - - Worktype findByName(String name); - - List findByNameIgnoreCase(String name); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/services/ComicService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/services/ComicService.java deleted file mode 100644 index b3e5fc1..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/services/ComicService.java +++ /dev/null @@ -1,353 +0,0 @@ -package de.thpeetz.kontor.comics.services; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import de.thpeetz.kontor.comics.repository.*; -import de.thpeetz.kontor.common.views.FilterOption; -import de.thpeetz.kontor.common.views.SearchFilter; -import org.springframework.stereotype.Service; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Service -public class ComicService { - - private final PublisherRepository publisherRepository; - private final ComicRepository comicRepository; - private final ArtistRepository artistRepository; - private final IssueRepository issueRepository; - private final StoryArcRepository storyArcRepository; - private final TradePaperbackRepository tradePaperbackRepository; - private final ComicWorkRepository comicWorkRepository; - private final IssueWorkRepository issueWorkRepository; - private final VolumeRepository volumeRepository; - private final WorktypeRepository worktypeRepository; - - public ComicService(PublisherRepository publisherRepository, ComicRepository comicRepository, - ArtistRepository artistRepository, IssueRepository issueRepository, StoryArcRepository storyArcRepository, - TradePaperbackRepository tradePaperbackRepository, ComicWorkRepository comicWorkRepository, IssueWorkRepository issueWorkRepository, - VolumeRepository volumeRepository, WorktypeRepository worktypeRepository) { - - this.publisherRepository = publisherRepository; - this.comicRepository = comicRepository; - this.artistRepository = artistRepository; - this.issueRepository = issueRepository; - this.storyArcRepository = storyArcRepository; - this.tradePaperbackRepository = tradePaperbackRepository; - this.comicWorkRepository = comicWorkRepository; - this.issueWorkRepository = issueWorkRepository; - this.volumeRepository = volumeRepository; - this.worktypeRepository = worktypeRepository; - } - - public List findAllPublishers(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return publisherRepository.findAll(); - } else { - return publisherRepository.search(stringFilter); - } - } - - public Publisher findPublisherByName(String publisherName) { - return publisherRepository.findByName(publisherName); - } - - public void deletePublisher(Publisher publisher) { - publisherRepository.delete(publisher); - } - - public void savePublisher(Publisher publisher) { - if (publisher == null) { - log.warn("Publisher is null. Are you sure you have connected your form to the application?"); - return; - } - publisherRepository.save(publisher); - } - - public List findAllComics(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return comicRepository.findAll(); - } else { - return comicRepository.search(stringFilter); - } - } - public List findAllComicsByFilter(SearchFilter searchFilter) { - if (searchFilter == null) return comicRepository.findAll(); - if (searchFilter.getFilterOptions().isEmpty()) return comicRepository.search(searchFilter.getSearchTerm()); - if (searchFilter.getFilterOptions().size() == 1) { - FilterOption option = searchFilter.getFilterOptions().getFirst(); - if (searchFilter.getSearchTerm() != null && !searchFilter.getSearchTerm().isEmpty()) { - switch (option.getName()) { - case "Bestellung": - return comicRepository.searchAndFilterByCurrentOrder(searchFilter.getSearchTerm(), option.getValue()); - case "Abgeschlossen": - return comicRepository.searchAndFilterByCompleted(searchFilter.getSearchTerm(), option.getValue()); - } - } - switch (option.getName()) { - case "Bestellung": - return comicRepository.findByCurrentOrder(option.getValue()); - case "Abgeschlossen": - return comicRepository.findByCompleted(option.getValue()); - } - } - if (searchFilter.getFilterOptions().size() == 2) { - if (searchFilter.getSearchTerm() != null && !searchFilter.getSearchTerm().isEmpty()) { - return comicRepository.search(searchFilter.getSearchTerm(), - searchFilter.getFilter("Bestellung").getValue(), - searchFilter.getFilter("Abgeschlossen").getValue()); - } - return comicRepository.findByCurrentOrderAndCompleted(searchFilter.getFilter("Bestellung").getValue(), - searchFilter.getFilter("Abgeschlossen").getValue()); - } - return comicRepository.findAll(); - } - - - public Comic findComicByTitle(String title) { - List comics = comicRepository.findByTitle(title); - if (comics.size() == 1) { - return comics.get(0); - } - return null; - } - - public void deleteComic(Comic comic) { - Publisher publisher = comic.getPublisher(); - publisher.getComics().remove(comic); - publisherRepository.save(publisher); - comicRepository.delete(comic); - } - - public void saveComic(Comic comic) { - if (comic == null) { - log.warn("Comic is null. Are you sure you have connected your form to the application?"); - return; - } - comicRepository.save(comic); - } - - public List findAllArtists(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return artistRepository.findAll(); - } else { - return artistRepository.search(stringFilter); - } - } - - public Artist findArtistByName(String artistName) { - if (artistName == null || artistName.isEmpty()) { - return null; - } else { - return artistRepository.findByName(artistName); - } - } - - public void deleteArtist(Artist artist) { - artistRepository.delete(artist); - } - - public void saveArtist(Artist artist) { - if (artist == null) { - log.warn("Artist is null. Are you sure you have connected your form to the application?"); - return; - } - artistRepository.save(artist); - } - - public List findAllIssues() { - return issueRepository.findAll(); - } - - public List findAllIssuesForComic(Comic comic) { - if (comic == null) { - return issueRepository.findAll(); - } else { - log.info("Find issues for Comic: {}", comic); - return issueRepository.findByComic(comic); - } - } - - public void saveIssue(Issue issue) { - if (issue == null) { - log.warn("Issue is null. Are you sure you have connected your form to the application?"); - return; - } - issueRepository.save(issue); - } - - public void deleteIssue(Issue issue) { - issueRepository.delete(issue); - } - - public List findAllStoryArcs() { - return storyArcRepository.findAll(); - } - - public List findAllStoryArcsForComic(Comic comic) { - if (comic == null) { - return storyArcRepository.findAll(); - } else { - log.info("Find Story Arc for Comic: {}", comic); - return storyArcRepository.findByComic(comic); - } - } - - public void saveStoryArc(StoryArc storyArc) { - storyArcRepository.save(storyArc); - } - - public void deleteStoryArc(StoryArc storyArc) { - Comic comic = storyArc.getComic(); - comic.getStoryArcs().remove(storyArc); - comicRepository.save(comic); - storyArcRepository.delete(storyArc); - } - - public List findAllTradePaperbacks(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return tradePaperbackRepository.findAll(); - } else { - return tradePaperbackRepository.search(stringFilter); - } - } - - public void deleteTradePaperBack(TradePaperback tradepaperback) { - tradePaperbackRepository.delete(tradepaperback); - } - - public void saveTradePaperBack(TradePaperback tradepaperback) { - if (tradepaperback == null) { - log.warn("TradePaperBack is null. Are you sure you have connected your form to the application?"); - return; - } - tradePaperbackRepository.save(tradepaperback); - } - - public List findAllComicWorks() { - return comicWorkRepository.findAll(); - } - - public void saveComicWork(ComicWork comicWork) { - if (comicWork == null) { - log.warn("ComicWork is null. Are you sure you have connected your form to the application?"); - return; - } - comicWorkRepository.save(comicWork); - } - - public void deleteComicWork(ComicWork comicWork) { - Comic comic = comicWork.getComic(); - comic.getComicWorks().remove(comicWork); - comicRepository.save(comic); - Artist artist = comicWork.getArtist(); - artist.getComicWorks().remove(comicWork); - artistRepository.save(artist); - Worktype worktype = comicWork.getWorkType(); - worktype.getComicWorks().remove(comicWork); - worktypeRepository.save(worktype); - comicWorkRepository.delete(comicWork); - } - - public List findAllIssueWorks() { - return issueWorkRepository.findAll(); - } - - public void saveIssueWork(IssueWork issueWork) { - if (issueWork == null) { - log.warn("IssueWork is null. Are you sure you have connected your form to the application?"); - return; - } - issueWorkRepository.save(issueWork); - } - - public void deleteIssueWork(IssueWork issueWork) { - Issue issue = issueWork.getIssue(); - issue.getIssueWorks().remove(issueWork); - issueRepository.save(issue); - Artist artist = issueWork.getArtist(); - artist.getIssueWorks().remove(issueWork); - artistRepository.save(artist); - Worktype worktype = issueWork.getWorkType(); - worktype.getIssueWorks().remove(issueWork); - worktypeRepository.save(worktype); - issueWorkRepository.delete(issueWork); - } - - public List findAllVolumes() { - return volumeRepository.findAll(); - } - - public List findAllVolumesForComic(Comic comic) { - if (comic == null) { - return volumeRepository.findAll(); - } else { - log.info("Find Volume for Comic: {}", comic); - return volumeRepository.findByComic(comic); - } - } - - public void saveVolume(Volume volume) { - if (volume == null) { - log.warn("Volume is null. Are you sure you have connected your form to the application?"); - return; - } - volumeRepository.save(volume); - } - - public void deleteVolume(Volume volume) { - Comic comic = volume.getComic(); - comic.getVolumes().remove(volume); - comicRepository.save(comic); - volumeRepository.delete(volume); - } - - public List findAllWorktypes(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return worktypeRepository.findAll(); - } else { - return worktypeRepository.search(stringFilter); - } - } - - public Worktype findWorktypeByName(String worktypeName) { - if (worktypeName == null || worktypeName.isEmpty()) { - return null; - } else { - return worktypeRepository.findByName(worktypeName); - } - } - - public void saveWorktype(Worktype worktype) { - if (worktype == null) { - log.warn("Worktype is null. Are you sure you have connected your form to the application?"); - return; - } - worktypeRepository.save(worktype); - } - - public void deleteWorktype(Worktype worktype) { - List comicWorks = worktype.getComicWorks(); - List issueWorks = worktype.getIssueWorks(); - if (comicWorks == null) { - log.warn("reference to ComicWork is null"); - } else { - log.info("found {} references to ComicWork", comicWorks.size()); - comicWorks.forEach(comicWork -> { - comicWork.setWorkType(null); - }); - } - if (issueWorks == null) { - log.warn("reference to ComicWork is null"); - } else { - log.info("found {} references to IssueWork", issueWorks.size()); - issueWorks.forEach(issueWork -> { - issueWork.setWorkType(null); - }); - } - log.info("delete Worktype: {}", worktype); - worktypeRepository.delete(worktype); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ArtistForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ArtistForm.java deleted file mode 100644 index 5eb1e0d..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ArtistForm.java +++ /dev/null @@ -1,117 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.comics.data.Artist; -import de.thpeetz.kontor.comics.data.ComicWork; -import lombok.*; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class ArtistForm extends FormLayout { - - TextField name = new TextField("Name"); - TextField weblink = new TextField("Link"); - Grid comicWorks = new Grid<>(ComicWork.class); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Artist.class); - - public ArtistForm() { - addClassName("artist-form"); - binder.bindInstanceFields(this); - - comicWorks.setColumns("workType.name", "comic.title"); - comicWorks.getColumnByKey("workType.name").setHeader("Work type"); - comicWorks.getColumnByKey("comic.title").setHeader("Comic"); - comicWorks.getColumns().forEach(col -> col.setAutoWidth(true)); - add(name, weblink, comicWorks, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setArtist(Artist artist) { - binder.setBean(artist); - } - - public void setComicWorks(List works) { - log.info("Setting comic works: {}", works); - this.comicWorks.setItems(works); - } - - @Getter - public abstract static class ArtistFormEvent extends ComponentEvent { - private final Artist artist; - - protected ArtistFormEvent(ArtistForm source, Artist artist) { - super(source, false); - this.artist = artist; - } - - } - - public static class SaveEvent extends ArtistFormEvent { - SaveEvent(ArtistForm source, Artist artist) { - super(source, artist); - } - } - - public static class DeleteEvent extends ArtistFormEvent { - DeleteEvent(ArtistForm source, Artist artist) { - super(source, artist); - } - } - - public static class CloseEvent extends ArtistFormEvent { - CloseEvent(ArtistForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ArtistView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ArtistView.java deleted file mode 100644 index 1a6b2a5..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ArtistView.java +++ /dev/null @@ -1,124 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import lombok.Getter; -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.comics.data.Artist; -import de.thpeetz.kontor.comics.services.ComicService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = "artist", layout = MainLayout.class) -@PageTitle("Artist | Comics | Kontor") -public class ArtistView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(Artist.class); - TextField filterText = new TextField(); - @Getter - ArtistForm form; - ComicService service; - - public ArtistView(ComicService service) { - this.service = service; - addClassName("artist-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("artist-grid"); - grid.setSizeFull(); - grid.setColumns("name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editArtist(event.getValue())); - } - - private void configureForm() { - form = new ArtistForm(); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveArtist); - form.addDeleteListener(this::deleteArtist); - form.addCloseListener(e -> closeEditor()); - } - - private void saveArtist(ArtistForm.SaveEvent event) { - service.saveArtist(event.getArtist()); - updateList(); - closeEditor(); - } - - private void deleteArtist(ArtistForm.DeleteEvent event) { - service.deleteArtist(event.getArtist()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addArtistButton = new Button("Add artist"); - addArtistButton.addClickListener(click -> addArtist()); - - HorizontalLayout toolbar = new HorizontalLayout(filterText, addArtistButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editArtist(Artist artist) { - if (artist == null) { - closeEditor(); - } else { - form.setArtist(artist); - form.setComicWorks(artist.getComicWorks()); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setArtist(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addArtist() { - grid.asSingleSelect().clear(); - editArtist(new Artist()); - } - - public void updateList() { - grid.setItems(service.findAllArtists(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicForm.java deleted file mode 100644 index 56aa1b2..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicForm.java +++ /dev/null @@ -1,130 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import java.util.List; - -import lombok.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.checkbox.Checkbox; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.ComicWork; -import de.thpeetz.kontor.comics.data.Publisher; - -public class ComicForm extends FormLayout { - - private static final Logger log = LoggerFactory.getLogger(ComicForm.class); - - TextField title = new TextField("Title"); - ComboBox publisher = new ComboBox<>("Publisher"); - TextField weblink = new TextField("Link"); - Checkbox currentOrder = new Checkbox("Current order"); - Checkbox completed = new Checkbox("Completed"); - Grid comicWorks = new Grid<>(ComicWork.class); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Comic.class); - - public ComicForm(List publishers) { - addClassName("comic-form"); - binder.bindInstanceFields(this); - - publisher.setItems(publishers); - publisher.setItemLabelGenerator(Publisher::getName); - // comicWorks.addClassName("comic-works-grid"); - // comicWorks.setSizeFull(); - comicWorks.setColumns("workType.name", "artist.name"); - comicWorks.getColumnByKey("workType.name").setHeader("Work type"); - comicWorks.getColumnByKey("artist.name").setHeader("Artist"); - comicWorks.getColumns().forEach(col -> col.setAutoWidth(true)); - add(title, publisher, weblink, currentOrder, completed, comicWorks, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setComic(Comic comic) { - binder.setBean(comic); - } - - public void setComicWorks(List works) { - log.info("Setting comic works: {}", works); - comicWorks.setItems(works); - } - - @Getter - public abstract static class ComicFormEvent extends ComponentEvent { - private final Comic comic; - - protected ComicFormEvent(ComicForm source, Comic comic) { - super(source, false); - this.comic = comic; - } - - } - - public static class SaveEvent extends ComicFormEvent { - SaveEvent(ComicForm source, Comic comic) { - super(source, comic); - } - } - - public static class DeleteEvent extends ComicFormEvent { - DeleteEvent(ComicForm source, Comic comic) { - super(source, comic); - } - } - - public static class CloseEvent extends ComicFormEvent { - CloseEvent(ComicForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicLayout.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicLayout.java deleted file mode 100644 index cffdbdb..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicLayout.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import com.vaadin.flow.component.applayout.AppLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.theme.lumo.LumoUtility; - -import de.thpeetz.kontor.admin.services.AdminService; -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.common.views.KontorLayoutUtil; -import de.thpeetz.kontor.security.SecurityService; -import lombok.extern.slf4j.Slf4j; - -/** - * Represents a custom layout for the comic view in the application. - * This layout extends the AppLayout class. - */ -@Slf4j -public class ComicLayout extends AppLayout { - - private final AdminService adminService; - - private final SecurityService securityService; - - public ComicLayout(AdminService adminService, SecurityService securityService) { - this.adminService = adminService; - this.securityService = securityService; - - KontorLayoutUtil layout = new KontorLayoutUtil(this, adminService, securityService); - layout.setSecondaryNavigation(getSecondaryNavigation()); - layout.createHeader(ComicConstants.COMICS); - } - - private HorizontalLayout getSecondaryNavigation() { - HorizontalLayout navigation = new HorizontalLayout(); - navigation.addClassNames(LumoUtility.JustifyContent.CENTER, LumoUtility.Gap.SMALL, LumoUtility.Height.MEDIUM); - navigation.add(ComicConstants.getComicLink(), ComicConstants.getPublisherLink(), ComicConstants.getIssueLink(), - ComicConstants.getTradePaperbackLink(), ComicConstants.getStoryArcLink(), - ComicConstants.getVolumeLink(), ComicConstants.getArtistLink(), ComicConstants.getComicWorkLink(), - ComicConstants.getWorktypeLink()); - return navigation; - } -} - diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicView.java deleted file mode 100644 index 7437193..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicView.java +++ /dev/null @@ -1,159 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import de.thpeetz.kontor.common.views.ColumnToggleContextMenu; -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.common.views.SearchFilterField; -import de.thpeetz.kontor.common.views.StatusIcon; -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.services.ComicService; -import jakarta.annotation.security.PermitAll; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = ComicConstants.COMICS_ROUTE, layout = MainLayout.class) -@PageTitle("Comic | Comics | Kontor") -public class ComicView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(Comic.class, false); - Grid.Column idColumn = grid.addColumn(Comic::getId) - .setHeader("ID").setResizable(true).setSortable(true); - Grid.Column createdColumn = grid.addColumn(Comic::getCreatedDate) - .setHeader("Erstellt").setResizable(true).setSortable(true); - Grid.Column modifiedColumn = grid.addColumn(Comic::getLastModifiedDate) - .setHeader("Geändert").setResizable(true).setSortable(true); - Grid.Column titleColumn = grid.addColumn(Comic::getTitle) - .setHeader("Titel").setResizable(true).setSortable(true); - Grid.Column publisherColumn = grid.addColumn(Comic::getPublisherName) - .setHeader("Verlag").setResizable(true).setSortable(true); - Grid.Column currentOrderColumn = grid.addComponentColumn(comic -> StatusIcon.create(comic.getCurrentOrder())) - .setHeader("Bestellung").setWidth("6rem").setSortable(true); - Grid.Column completedColumn = grid.addComponentColumn(comic -> StatusIcon.create(comic.getCompleted())) - .setHeader("Abgeschlossen").setWidth("6rem").setSortable(true); - Grid.Column weblinkColumn = grid.addColumn(Comic::getWeblink) - .setHeader("Link").setResizable(true).setSortable(true); - SearchFilterField searchFilterField = new SearchFilterField(); - @Getter - ComicForm form; - ComicService service; - - public ComicView(ComicService service) { - this.service = service; - addClassName("comic-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("comic-grid"); - grid.setSizeFull(); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editComic(event.getValue())); - } - - private void configureForm() { - form = new ComicForm(service.findAllPublishers(null)); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveComic); - form.addDeleteListener(this::deleteComic); - form.addCloseListener(e -> closeEditor()); - } - - private void saveComic(ComicForm.SaveEvent event) { - service.saveComic(event.getComic()); - updateList(); - closeEditor(); - } - - private void deleteComic(ComicForm.DeleteEvent event) { - service.deleteComic(event.getComic()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - searchFilterField.addFilter("Bestellung"); - searchFilterField.addFilter("Abgeschlossen"); - searchFilterField.addValueChangeListener(e -> updateList()); - - Button addComicButton = new Button("Add comic"); - addComicButton.addClickListener(click -> addComic()); - - Button menuButton = new Button("Show/Hide Columns"); - menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); - columnToggleContextMenu.addColumnToggleItem(idColumn); - columnToggleContextMenu.addColumnToggleItem(createdColumn); - columnToggleContextMenu.addColumnToggleItem(modifiedColumn); - columnToggleContextMenu.addColumnToggleItem(titleColumn); - columnToggleContextMenu.addColumnToggleItem(publisherColumn); - columnToggleContextMenu.addColumnToggleItem(currentOrderColumn); - columnToggleContextMenu.addColumnToggleItem(completedColumn); - columnToggleContextMenu.addColumnToggleItem(weblinkColumn); - HorizontalLayout toolbar = new HorizontalLayout(searchFilterField, addComicButton, menuButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editComic(Comic comic) { - if (comic == null) { - closeEditor(); - } else { - form.setComic(comic); - if (comic.getComicWorks() == null) { - log.info("No comic works"); - } else { - log.info("Comic works sze: {}", comic.getComicWorks().size()); - } - form.setComicWorks(comic.getComicWorks()); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setComic(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addComic() { - grid.asSingleSelect().clear(); - editComic(new Comic()); - } - - public void updateList() { - grid.setItems(service.findAllComicsByFilter(searchFilterField.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicWorkForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicWorkForm.java deleted file mode 100644 index 698a37e..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicWorkForm.java +++ /dev/null @@ -1,113 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.comics.data.Artist; -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.ComicWork; -import de.thpeetz.kontor.comics.data.Worktype; - -public class ComicWorkForm extends FormLayout { - ComboBox comic = new ComboBox<>("Comic"); - ComboBox artist = new ComboBox<>("Artist"); - ComboBox workType = new ComboBox<>("Worktype"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(ComicWork.class); - - public ComicWorkForm(List comics, List artists, List workTypes) { - addClassName("comicwork-form"); - binder.bindInstanceFields(this); - - comic.setItems(comics); - comic.setItemLabelGenerator(Comic::getTitle); - artist.setItems(artists); - artist.setItemLabelGenerator(Artist::getName); - workType.setItems(workTypes); - workType.setItemLabelGenerator(Worktype::getName); - add(comic, artist, workType, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setComicWork(ComicWork comicWork) { - binder.setBean(comicWork); - } - - public abstract static class ComicWorkFormEvent extends ComponentEvent { - private ComicWork comicWork; - - protected ComicWorkFormEvent(ComicWorkForm source, ComicWork comicWork) { - super(source, false); - this.comicWork = comicWork; - } - - public ComicWork getComicWork() { - return comicWork; - } - } - - public static class SaveEvent extends ComicWorkFormEvent { - SaveEvent(ComicWorkForm source, ComicWork comicWork) { - super(source, comicWork); - } - } - - public static class DeleteEvent extends ComicWorkFormEvent { - DeleteEvent(ComicWorkForm source, ComicWork comicWork) { - super(source, comicWork); - } - } - - public static class CloseEvent extends ComicWorkFormEvent { - CloseEvent(ComicWorkForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicWorkView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicWorkView.java deleted file mode 100644 index 449a76c..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/ComicWorkView.java +++ /dev/null @@ -1,122 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.comics.data.ComicWork; -import de.thpeetz.kontor.comics.services.ComicService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = ComicConstants.COMICWORK_ROUTE, layout = MainLayout.class) -@PageTitle("ComicWork | Comics | Kontor") -public class ComicWorkView extends VerticalLayout { - - Grid grid = new Grid<>(ComicWork.class); - ComicWorkForm form; - ComicService service; - - public ComicWorkView(ComicService service) { - this.service = service; - addClassName("comicWork-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - public Grid getGrid() { - return grid; - } - - private void configureGrid() { - grid.addClassName("comic-grid"); - grid.setSizeFull(); - grid.setColumns("comic.title", "artist.name", "workType.name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editComicWork(event.getValue())); - } - - public ComicWorkForm getForm() { - return form; - } - - private void configureForm() { - form = new ComicWorkForm(service.findAllComics(null), service.findAllArtists(null), - service.findAllWorktypes(null)); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveComicWork); - form.addDeleteListener(this::deleteComicWork); - form.addCloseListener(e -> closeEditor()); - } - - private void saveComicWork(ComicWorkForm.SaveEvent event) { - service.saveComicWork(event.getComicWork()); - updateList(); - closeEditor(); - } - - private void deleteComicWork(ComicWorkForm.DeleteEvent event) { - service.deleteComicWork(event.getComicWork()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - Button addComicButton = new Button("Add ComicWork"); - addComicButton.addClickListener(click -> addComicWork()); - - HorizontalLayout toolbar = new HorizontalLayout(addComicButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editComicWork(ComicWork comicWork) { - if (comicWork == null) { - closeEditor(); - } else { - form.setComicWork(comicWork); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setComicWork(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addComicWork() { - grid.asSingleSelect().clear(); - editComicWork(new ComicWork()); - } - - public void updateList() { - grid.setItems(service.findAllComicWorks()); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueForm.java deleted file mode 100644 index 2f59921..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueForm.java +++ /dev/null @@ -1,150 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.checkbox.Checkbox; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.*; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; - -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.Issue; -import de.thpeetz.kontor.comics.data.IssueWork; -import de.thpeetz.kontor.comics.data.Volume; -import de.thpeetz.kontor.common.views.YearMonthField; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class IssueForm extends FormLayout { - - ComboBox comic = new ComboBox<>("Comic"); - ComboBox volume = new ComboBox<>("Volume"); - TextField issueNumber = new TextField("Issue number"); - TextField title = new TextField("Full Title"); - YearMonthField publishedOn = new YearMonthField(); - Checkbox isRead = new Checkbox("Read"); - Checkbox inStock = new Checkbox("In stock"); - Grid issueWorks = new Grid<>(IssueWork.class); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Issue.class); - - public IssueForm(List comics, List volumes) { - addClassName("issue-form"); - binder.bindInstanceFields(this); - - comic.setItems(comics); - comic.addValueChangeListener(event -> { - if (event.getValue() != null) { - volume.setItems(event.getValue().getVolumes()); - } else { - volume.clear(); - } - }); - comic.setItemLabelGenerator(Comic::getTitle); - volume.setItems(volumes); - volume.setItemLabelGenerator(Volume::getName); - issueWorks.setColumns("workType.name", "artist.name"); - issueWorks.getColumnByKey("workType.name").setHeader("Work type"); - issueWorks.getColumnByKey("artist.name").setHeader("Artist"); - issueWorks.getColumns().forEach(col -> col.setAutoWidth(true)); - add(comic, volume, issueNumber, title, publishedOn, isRead, inStock,issueWorks, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setIssue(Issue issue) { - log.debug("IssueForm.setIssue: {}", issue); - Volume issueVolume = null; - if (issue != null) { - issueVolume = issue.getVolume(); - } - binder.setBean(issue); - if (issue != null && issue.getComic() != null) { - log.debug("populate list of volumes"); - volume.setItems(issue.getComic().getVolumes()); - log.debug("Issue.Volume= {}", issue.getVolume()); - if (issueVolume != null) { - log.debug("Set volume {} for issue: {}", issueVolume, issue); - volume.setValue(issueVolume); - } - } - } - - public void setIssueWorks(List works) { - log.info("Setting issue works: {}", works); - issueWorks.setItems(works); - } - - public abstract static class IssueFormEvent extends ComponentEvent { - @lombok.Getter - private final Issue issue; - - protected IssueFormEvent(IssueForm source, Issue issue) { - super(source, false); - this.issue = issue; - } - } - - public static class SaveEvent extends IssueFormEvent { - SaveEvent(IssueForm source, Issue issue) { - super(source, issue); - } - } - - public static class DeleteEvent extends IssueFormEvent { - DeleteEvent(IssueForm source, Issue issue) { - super(source, issue); - } - } - - public static class CloseEvent extends IssueFormEvent { - CloseEvent(IssueForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueView.java deleted file mode 100644 index bd441b0..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueView.java +++ /dev/null @@ -1,184 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.grid.GridSortOrder; -import com.vaadin.flow.data.provider.SortDirection; -import de.thpeetz.kontor.common.views.ColumnToggleContextMenu; -import de.thpeetz.kontor.common.views.StatusIcon; -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.Issue; -import de.thpeetz.kontor.comics.services.ComicService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.PermitAll; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -import java.util.ArrayList; -import java.util.List; - -@Slf4j -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = ComicConstants.ISSUE_ROUTE, layout = MainLayout.class) -@PageTitle("Issue | Comics | Kontor") -public class IssueView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(Issue.class, false); - Grid.Column idColumn = grid.addColumn(Issue::getId) - .setHeader("ID").setResizable(true).setSortable(true); - Grid.Column createdColumn = grid.addColumn(Issue::getCreatedDate) - .setHeader("Erstellt").setResizable(true).setSortable(true); - Grid.Column modifiedColumn = grid.addColumn(Issue::getLastModifiedDate) - .setHeader("Geändert").setResizable(true).setSortable(true); - Grid.Column versionColumn = grid.addColumn(Issue::getVersion) - .setHeader("Version").setResizable(true).setSortable(true); - Grid.Column titleColumn = grid.addColumn(Issue::getComicTitle) - .setHeader("Comic").setResizable(true).setSortable(true); - Grid.Column volumeColumn = grid.addColumn(Issue::getVolumeName) - .setHeader("Volume").setResizable(true).setSortable(true); - Grid.Column issueNumberColumn = grid.addColumn(Issue::getIssueNumber) - .setHeader("Heft Nummer").setResizable(true).setSortable(true); - Grid.Column issueTitleColumn = grid.addColumn(Issue::getTitle) - .setHeader("Full Title").setResizable(true).setSortable(true); - Grid.Column publishedOncolumn = grid.addColumn(Issue::getPublishedOn) - .setHeader("Published").setResizable(true).setSortable(true); - Grid.Column isReadColumn = grid.addComponentColumn(issueColumn -> StatusIcon.create(issueColumn.getIsRead())) - .setHeader("Gelesen?").setWidth("6rem").setSortable(true); - Grid.Column inStockColumn = grid.addComponentColumn(issueColumn -> StatusIcon.create(issueColumn.getInStock())) - .setHeader("Im Bestand?").setWidth("6rem").setSortable(true); - ComboBox comicFilter = new ComboBox<>("Comic"); - @Getter - IssueForm form; - ComicService service; - - public IssueView(ComicService service) { - this.service = service; - addClassName("issue-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("issue-grid"); - grid.setSizeFull(); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - idColumn.setVisible(false); - createdColumn.setVisible(false); - modifiedColumn.setVisible(false); - versionColumn.setVisible(false); - grid.setMultiSort(true); - List> sortOrder = new ArrayList<>(); - sortOrder.add(new GridSortOrder(titleColumn, SortDirection.ASCENDING)); - sortOrder.add(new GridSortOrder(issueNumberColumn, SortDirection.ASCENDING)); - grid.sort(sortOrder); - grid.asSingleSelect().addValueChangeListener(event -> editIssue(event.getValue())); - } - - private void configureForm() { - form = new IssueForm(service.findAllComics(null), service.findAllVolumes()); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveIssue); - form.addDeleteListener(this::deleteIssue); - form.addCloseListener(e -> closeEditor()); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - comicFilter.setItems(service.findAllComics(null)); - comicFilter.setItemLabelGenerator(Comic::getTitle); - comicFilter.setClearButtonVisible(true); - comicFilter.addValueChangeListener(e -> updateList()); - - Button addIssueButton = new Button("Add issue"); - addIssueButton.addClickListener(click -> addIssue()); - - Button menuButton = new Button("Show/Hide Columns"); - menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); - columnToggleContextMenu.addColumnToggleItem(idColumn); - columnToggleContextMenu.addColumnToggleItem(createdColumn); - columnToggleContextMenu.addColumnToggleItem(modifiedColumn); - columnToggleContextMenu.addColumnToggleItem(versionColumn); - columnToggleContextMenu.addColumnToggleItem(titleColumn); - columnToggleContextMenu.addColumnToggleItem(volumeColumn); - columnToggleContextMenu.addColumnToggleItem(issueNumberColumn); - columnToggleContextMenu.addColumnToggleItem(issueTitleColumn); - columnToggleContextMenu.addColumnToggleItem(publishedOncolumn); - columnToggleContextMenu.addColumnToggleItem(isReadColumn); - columnToggleContextMenu.addColumnToggleItem(inStockColumn); - HorizontalLayout toolbar = new HorizontalLayout(comicFilter, addIssueButton, menuButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - private void saveIssue(IssueForm.SaveEvent event) { - service.saveIssue(event.getIssue()); - updateList(); - closeEditor(); - } - - private void deleteIssue(IssueForm.DeleteEvent event) { - service.deleteIssue(event.getIssue()); - updateList(); - closeEditor(); - } - - public void editIssue(Issue issue) { - if (issue == null) { - closeEditor(); - } else { - form.setIssue(issue); - if (issue.getIssueWorks() == null) { - log.info("No issue works"); - } else { - log.info("Issue works sze: {}", issue.getIssueWorks().size()); - } - form.setIssueWorks(issue.getIssueWorks()); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setIssue(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addIssue() { - grid.asSingleSelect().clear(); - editIssue(new Issue()); - } - - private void updateList() { - grid.setItems(service.findAllIssuesForComic(comicFilter.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueWorkForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueWorkForm.java deleted file mode 100644 index 597d3e0..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueWorkForm.java +++ /dev/null @@ -1,115 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.comics.data.Artist; -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.IssueWork; -import de.thpeetz.kontor.comics.data.Worktype; -import de.thpeetz.kontor.common.views.ComicIssueField; - -public class IssueWorkForm extends FormLayout { - ComicIssueField issue = new ComicIssueField("Issue"); - ComboBox artist = new ComboBox<>("Artist"); - ComboBox workType = new ComboBox<>("Worktype"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(IssueWork.class); - - public IssueWorkForm(List comics, List artists, List workTypes) { - addClassName("issuework-form"); - binder.bindInstanceFields(this); - - issue.setComics(comics); - //issue.setItems(issues); - //issue.setItemLabelGenerator(Issue::getIssueNumber); - artist.setItems(artists); - artist.setItemLabelGenerator(Artist::getName); - workType.setItems(workTypes); - workType.setItemLabelGenerator(Worktype::getName); - add(issue, artist, workType, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setIssueWork(IssueWork issueWork) { - binder.setBean(issueWork); - } - - public abstract static class IssueWorkFormEvent extends ComponentEvent { - private IssueWork issueWork; - - protected IssueWorkFormEvent(IssueWorkForm source, IssueWork issueWork) { - super(source, false); - this.issueWork = issueWork; - } - - public IssueWork getIssueWork() { - return issueWork; - } - } - - public static class SaveEvent extends IssueWorkFormEvent { - SaveEvent(IssueWorkForm source, IssueWork issueWork) { - super(source, issueWork); - } - } - - public static class DeleteEvent extends IssueWorkFormEvent { - DeleteEvent(IssueWorkForm source, IssueWork issueWork) { - super(source, issueWork); - } - } - - public static class CloseEvent extends IssueWorkFormEvent { - CloseEvent(IssueWorkForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueWorkView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueWorkView.java deleted file mode 100644 index 3bc267d..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueWorkView.java +++ /dev/null @@ -1,118 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import de.thpeetz.kontor.comics.data.Issue; -import de.thpeetz.kontor.comics.data.IssueWork; -import lombok.Getter; -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.comics.services.ComicService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = ComicConstants.ISSUEWORK_ROUTE, layout = MainLayout.class) -@PageTitle("IssueWork | Comics | Kontor") -public class IssueWorkView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(IssueWork.class); - @Getter - IssueWorkForm form; - ComicService service; - - public IssueWorkView(ComicService service) { - this.service = service; - addClassName("issueWork-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("issue-grid"); - grid.setSizeFull(); - grid.setColumns("issue.fullTitle", "artist.name", "workType.name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editIssueWork(event.getValue())); - } - - private void configureForm() { - form = new IssueWorkForm(service.findAllComics(null), service.findAllArtists(null), - service.findAllWorktypes(null)); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveIssueWork); - form.addDeleteListener(this::deleteIssueWork); - form.addCloseListener(e -> closeEditor()); - } - - private void saveIssueWork(IssueWorkForm.SaveEvent event) { - service.saveIssueWork(event.getIssueWork()); - updateList(); - closeEditor(); - } - - private void deleteIssueWork(IssueWorkForm.DeleteEvent event) { - service.deleteIssueWork(event.getIssueWork()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - Button addIssueButton = new Button("Add IssueWork"); - addIssueButton.addClickListener(click -> addIssueWork()); - - HorizontalLayout toolbar = new HorizontalLayout(addIssueButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editIssueWork(IssueWork issueWork) { - if (issueWork == null) { - closeEditor(); - } else { - form.setIssueWork(issueWork); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setIssueWork(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addIssueWork() { - grid.asSingleSelect().clear(); - editIssueWork(new IssueWork()); - } - - public void updateList() { - grid.setItems(service.findAllIssueWorks()); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/PublisherForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/PublisherForm.java deleted file mode 100644 index 6b1c866..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/PublisherForm.java +++ /dev/null @@ -1,106 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.combobox.*; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.comics.data.Publisher; -import lombok.*; - -import java.util.*; - -public class PublisherForm extends FormLayout { - public TextField name = new TextField("Name"); - public TextField weblink = new TextField("Link"); - ComboBox parentCompany = new ComboBox<>("Parent Company"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Publisher.class); - - public PublisherForm(List publishers) { - addClassName("publisher-form"); - binder.bindInstanceFields(this); - - parentCompany.setItems(publishers); - parentCompany.setItemLabelGenerator(Publisher::getName); - add(name, weblink, parentCompany, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setPublisher(Publisher publisher) { - binder.setBean(publisher); - } - - @Getter - public abstract static class PublisherFormEvent extends ComponentEvent { - private final Publisher publisher; - - protected PublisherFormEvent(PublisherForm source, Publisher publisher) { - super(source, false); - this.publisher = publisher; - } - - } - - public static class SaveEvent extends PublisherFormEvent { - SaveEvent(PublisherForm source, Publisher publisher) { - super(source, publisher); - } - } - - public static class DeleteEvent extends PublisherFormEvent { - DeleteEvent(PublisherForm source, Publisher publisher) { - super(source, publisher); - } - } - - public static class CloseEvent extends PublisherFormEvent { - CloseEvent(PublisherForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/PublisherView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/PublisherView.java deleted file mode 100644 index cf1eae8..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/PublisherView.java +++ /dev/null @@ -1,148 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import com.vaadin.flow.component.button.*; -import de.thpeetz.kontor.comics.data.*; -import de.thpeetz.kontor.common.views.*; -import lombok.*; -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.comics.services.ComicService; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = ComicConstants.PUBLISHER_ROUTE, layout = MainLayout.class) -@PageTitle("Publisher | Comics | Kontor") -public class PublisherView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(Publisher.class, false); - Grid.Column idColumn = grid.addColumn(Publisher::getId) - .setHeader("ID").setResizable(true).setSortable(true); - Grid.Column createdColumn = grid.addColumn(Publisher::getCreatedDate) - .setHeader("Erstellt").setResizable(true).setSortable(true); - Grid.Column modifiedColumn = grid.addColumn(Publisher::getLastModifiedDate) - .setHeader("Geändert").setResizable(true).setSortable(true); - Grid.Column nameColumn = grid.addColumn(Publisher::getName) - .setHeader("Titel").setResizable(true).setSortable(true); - Grid.Column parentCompanyColumn = grid.addColumn(Publisher::getParentCompanyName) - .setHeader("Parent Company").setResizable(true).setSortable(true); - Grid.Column imprintColumn = grid.addComponentColumn(publisher -> StatusIcon.create(publisher.getParentCompany() != null)) - .setHeader("Imprint").setWidth("6rem").setSortable(true); - Grid.Column weblinkColumn = grid.addColumn(Publisher::getWeblink) - .setHeader("Link").setResizable(true).setSortable(true); - TextField filterText = new TextField(); - @Getter - PublisherForm form; - - ComicService service; - - public PublisherView(ComicService service) { - this.service = service; - addClassName("publisher-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("publisher-grid"); - grid.setSizeFull(); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editPublisher(event.getValue())); - } - - private void configureForm() { - form = new PublisherForm(service.findAllPublishers(null)); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::savePublisher); - form.addDeleteListener(this::deletePublisher); - form.addCloseListener(e -> closeEditor()); - } - - private void savePublisher(PublisherForm.SaveEvent event) { - service.savePublisher(event.getPublisher()); - updateList(); - closeEditor(); - } - - private void deletePublisher(PublisherForm.DeleteEvent event) { - service.deletePublisher(event.getPublisher()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addPublisherButton = new Button("Add publisher"); - addPublisherButton.addClickListener(click -> addPublisher()); - - Button menuButton = new Button("Show/Hide Columns"); - menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); - columnToggleContextMenu.addColumnToggleItem(idColumn); - columnToggleContextMenu.addColumnToggleItem(createdColumn); - columnToggleContextMenu.addColumnToggleItem(modifiedColumn); - columnToggleContextMenu.addColumnToggleItem(nameColumn); - columnToggleContextMenu.addColumnToggleItem(parentCompanyColumn); - columnToggleContextMenu.addColumnToggleItem(imprintColumn); - columnToggleContextMenu.addColumnToggleItem(weblinkColumn); - HorizontalLayout toolbar = new HorizontalLayout(filterText, addPublisherButton, menuButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editPublisher(Publisher publisher) { - if (publisher == null) { - closeEditor(); - } else { - form.setPublisher(publisher); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setPublisher(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addPublisher() { - grid.asSingleSelect().clear(); - editPublisher(new Publisher()); - } - - public void updateList() { - grid.setItems(service.findAllPublishers(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/StoryArcForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/StoryArcForm.java deleted file mode 100644 index 786a792..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/StoryArcForm.java +++ /dev/null @@ -1,108 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.StoryArc; - -import java.util.List; - -public class StoryArcForm extends FormLayout { - - ComboBox comic = new ComboBox<>("Comic"); - TextField name = new TextField("Story Arc Name"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(StoryArc.class); - - public StoryArcForm(List comics) { - addClassName("storyarc-form"); - binder.bindInstanceFields(this); - - comic.setItems(comics); - comic.setItemLabelGenerator(Comic::getTitle); - add(comic, name, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setStoryArc(StoryArc storyArc) { - binder.setBean(storyArc); - } - - public abstract static class StoryArcFormEvent extends ComponentEvent { - private StoryArc storyArc; - - protected StoryArcFormEvent(StoryArcForm source, StoryArc storyArc) { - super(source, false); - this.storyArc = storyArc; - } - - public StoryArc getStoryArc() { - return storyArc; - } - } - - public static class SaveEvent extends StoryArcFormEvent { - SaveEvent(StoryArcForm source, StoryArc storyArc) { - super(source, storyArc); - } - } - - public static class DeleteEvent extends StoryArcFormEvent { - DeleteEvent(StoryArcForm source, StoryArc storyArc) { - super(source, storyArc); - } - } - - public static class CloseEvent extends StoryArcFormEvent { - CloseEvent(StoryArcForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/StoryArcView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/StoryArcView.java deleted file mode 100644 index 6044383..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/StoryArcView.java +++ /dev/null @@ -1,130 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.StoryArc; -import de.thpeetz.kontor.comics.services.ComicService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.PermitAll; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = ComicConstants.STORYARC_ROTE, layout = MainLayout.class) -@PageTitle("StoryArc | Comics | Kontor") -public class StoryArcView extends VerticalLayout { - - Grid grid = new Grid<>(StoryArc.class); - ComboBox comicFilter = new ComboBox<>("Comic"); - StoryArcForm form; - ComicService service; - - public StoryArcView(ComicService service) { - this.service = service; - addClassName("storyarc-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - StoryArcForm getForm() { - return form; - } - - public Grid getGrid() { - return grid; - } - - private void configureGrid() { - grid.addClassName("storyarc-grid"); - grid.setSizeFull(); - grid.setColumns("comic.title", "name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editStoryArc(event.getValue())); - } - - private void configureForm() { - form = new StoryArcForm(service.findAllComics(null)); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveStoryArc); - form.addDeleteListener(this::deleteStoryArc); - form.addCloseListener(e -> closeEditor()); - } - - private void saveStoryArc(StoryArcForm.SaveEvent event) { - service.saveStoryArc(event.getStoryArc()); - updateList(); - closeEditor(); - } - - private void deleteStoryArc(StoryArcForm.DeleteEvent event) { - service.deleteStoryArc(event.getStoryArc()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - comicFilter.setItems(service.findAllComics(null)); - comicFilter.setItemLabelGenerator(Comic::getTitle); - comicFilter.addValueChangeListener(e -> updateList()); - comicFilter.setClearButtonVisible(true); - - Button addStoryArcButton = new Button("Add StoryArc", click -> addStoryArc()); - - HorizontalLayout toolbar = new HorizontalLayout(comicFilter, addStoryArcButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editStoryArc(StoryArc storyArc) { - if (storyArc == null) { - closeEditor(); - } else { - form.setStoryArc(storyArc); - form.setVisible(true); - addClassName("editing"); - } - } - - public void closeEditor() { - form.setStoryArc(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addStoryArc() { - grid.asSingleSelect().clear(); - editStoryArc(new StoryArc()); - } - - private void updateList() { - grid.setItems(service.findAllStoryArcsForComic(comicFilter.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/TradePaperBackForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/TradePaperBackForm.java deleted file mode 100644 index 8a1b477..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/TradePaperBackForm.java +++ /dev/null @@ -1,109 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.TradePaperback; - -public class TradePaperBackForm extends FormLayout { - TextField name = new TextField("Name"); - ComboBox comic = new ComboBox<>("Comic"); - TextField issueStart = new TextField("Issue Start"); - TextField issueEnd = new TextField("Issue End"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(TradePaperback.class); - - public TradePaperBackForm(List comics) { - addClassName("tradepaperback-form"); - binder.bindInstanceFields(this); - - comic.setItems(comics); - comic.setItemLabelGenerator(Comic::getTitle); - add(name, comic, issueStart, issueEnd, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setTradePaperBack(TradePaperback tradepaperback) { - binder.setBean(tradepaperback); - } - - public abstract static class TradePaperBackFormEvent extends ComponentEvent { - private TradePaperback tradepaperback; - - protected TradePaperBackFormEvent(TradePaperBackForm source, TradePaperback tradepaperback) { - super(source, false); - this.tradepaperback = tradepaperback; - } - - public TradePaperback getTradePaperBack() { - return tradepaperback; - } - } - - public static class SaveEvent extends TradePaperBackFormEvent { - SaveEvent(TradePaperBackForm source, TradePaperback tradepaperback) { - super(source, tradepaperback); - } - } - - public static class DeleteEvent extends TradePaperBackFormEvent { - DeleteEvent(TradePaperBackForm source, TradePaperback tradepaperback) { - super(source, tradepaperback); - } - } - - public static class CloseEvent extends TradePaperBackFormEvent { - CloseEvent(TradePaperBackForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/TradePaperbackView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/TradePaperbackView.java deleted file mode 100644 index 0215234..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/TradePaperbackView.java +++ /dev/null @@ -1,129 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.comics.data.TradePaperback; -import de.thpeetz.kontor.comics.services.ComicService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = ComicConstants.TPB_ROUTE, layout = MainLayout.class) -@PageTitle("TradePaperBack | Comics | Kontor") -public class TradePaperbackView extends VerticalLayout { - - Grid grid = new Grid<>(TradePaperback.class); - TextField filterText = new TextField(); - TradePaperBackForm form; - ComicService service; - - public TradePaperbackView(ComicService service) { - this.service = service; - addClassName("tradepaperback-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - public Grid getGrid() { - return grid; - } - - private void configureGrid() { - grid.addClassName("tradepaperback-grid"); - grid.setSizeFull(); - grid.setColumns("name", "comic.title", "issueStart", "issueEnd"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editTradePaperBack(event.getValue())); - } - - public TradePaperBackForm getForm() { - return form; - } - - private void configureForm() { - form = new TradePaperBackForm(service.findAllComics(null)); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveTradePaperBack); - form.addDeleteListener(this::deleteTradePaperBack); - form.addCloseListener(e -> closeEditor()); - } - - private void saveTradePaperBack(TradePaperBackForm.SaveEvent event) { - service.saveTradePaperBack(event.getTradePaperBack()); - updateList(); - closeEditor(); - } - - private void deleteTradePaperBack(TradePaperBackForm.DeleteEvent event) { - service.deleteTradePaperBack(event.getTradePaperBack()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addTradePaperBackButton = new Button("Add TradePaperBack"); - addTradePaperBackButton.addClickListener(click -> addTradePaperBack()); - - HorizontalLayout toolbar = new HorizontalLayout(filterText, addTradePaperBackButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editTradePaperBack(TradePaperback tradepaperback) { - if (tradepaperback == null) { - closeEditor(); - } else { - form.setTradePaperBack(tradepaperback); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setTradePaperBack(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addTradePaperBack() { - grid.asSingleSelect().clear(); - editTradePaperBack(new TradePaperback()); - } - - public void updateList() { - grid.setItems(service.findAllTradePaperbacks(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/VolumeForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/VolumeForm.java deleted file mode 100644 index 9b333a9..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/VolumeForm.java +++ /dev/null @@ -1,109 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.StoryArc; -import de.thpeetz.kontor.comics.data.Volume; - -public class VolumeForm extends FormLayout { - - ComboBox comic = new ComboBox<>("Comic"); - public TextField name = new TextField("Name"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Volume.class); - - public VolumeForm(List comics) { - addClassName("volume-form"); - binder.bindInstanceFields(this); - - comic.setItems(comics); - comic.setItemLabelGenerator(Comic::getTitle); - add(comic, name, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setVolume(Volume volume) { - binder.setBean(volume); - } - - public abstract static class VolumeFormEvent extends ComponentEvent { - private Volume volume; - - protected VolumeFormEvent(VolumeForm source, Volume volume) { - super(source, false); - this.volume = volume; - } - - public Volume getVolume() { - return volume; - } - } - - public static class SaveEvent extends VolumeFormEvent { - SaveEvent(VolumeForm source, Volume volume) { - super(source, volume); - } - } - - public static class DeleteEvent extends VolumeFormEvent { - DeleteEvent(VolumeForm source, Volume volume) { - super(source, volume); - } - } - - public static class CloseEvent extends VolumeFormEvent { - CloseEvent(VolumeForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/VolumeView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/VolumeView.java deleted file mode 100644 index 47a2201..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/VolumeView.java +++ /dev/null @@ -1,130 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.Volume; -import de.thpeetz.kontor.comics.services.ComicService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.PermitAll; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = ComicConstants.VOLUME_ROUTE, layout = MainLayout.class) -@PageTitle("Volume | Comics | Kontor") -public class VolumeView extends VerticalLayout { - - Grid grid = new Grid<>(Volume.class); - ComboBox comicFilter = new ComboBox<>("Comic"); - VolumeForm form; - ComicService service; - - public VolumeView(ComicService service) { - this.service = service; - addClassName("volume-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - VolumeForm getForm() { - return form; - } - - public Grid getGrid() { - return grid; - } - - private void configureGrid() { - grid.addClassName("volume-grid"); - grid.setSizeFull(); - grid.setColumns("comic.title", "name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editVolume(event.getValue())); - } - - private void configureForm() { - form = new VolumeForm(service.findAllComics(null)); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveVolume); - form.addDeleteListener(this::deleteVolume); - form.addCloseListener(e -> closeEditor()); - } - - private void saveVolume(VolumeForm.SaveEvent event) { - service.saveVolume(event.getVolume()); - updateList(); - closeEditor(); - } - - private void deleteVolume(VolumeForm.DeleteEvent event) { - service.deleteVolume(event.getVolume()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - comicFilter.setItems(service.findAllComics(null)); - comicFilter.setItemLabelGenerator(Comic::getTitle); - comicFilter.addValueChangeListener(e -> updateList()); - comicFilter.setClearButtonVisible(true); - - Button addVolumeButton = new Button("Add Volume", click -> addVolume()); - - HorizontalLayout toolbar = new HorizontalLayout(comicFilter, addVolumeButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editVolume(Volume volume) { - if (volume == null) { - closeEditor(); - } else { - form.setVolume(volume); - form.setVisible(true); - addClassName("editing"); - } - } - - public void closeEditor() { - form.setVolume(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addVolume() { - grid.asSingleSelect().clear(); - editVolume(new Volume()); - } - - private void updateList() { - grid.setItems(service.findAllVolumesForComic(comicFilter.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/WorktypeForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/WorktypeForm.java deleted file mode 100644 index 0965229..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/WorktypeForm.java +++ /dev/null @@ -1,121 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.comics.data.ComicWork; -import de.thpeetz.kontor.comics.data.Worktype; - -public class WorktypeForm extends FormLayout { - - private static final Logger log = LoggerFactory.getLogger(WorktypeForm.class); - - TextField name = new TextField("Name"); - Grid comicWorks = new Grid<>(ComicWork.class); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Worktype.class); - - public WorktypeForm() { - addClassName("worktype-form"); - binder.bindInstanceFields(this); - - comicWorks.setColumns("comic.title", "artist.name"); - comicWorks.getColumnByKey("comic.title").setHeader("Comic"); - comicWorks.getColumnByKey("artist.name").setHeader("Artist"); - comicWorks.getColumns().forEach(col -> col.setAutoWidth(true)); - - add(name, comicWorks, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setWorktype(Worktype worktype) { - binder.setBean(worktype); - } - - public void setComicWorks(List works) { - log.info("Setting comic works: {}", works); - this.comicWorks.setItems(works); - } - - public abstract static class WorktypeFormEvent extends ComponentEvent { - private Worktype worktype; - - protected WorktypeFormEvent(WorktypeForm source, Worktype worktype) { - super(source, false); - this.worktype = worktype; - } - - public Worktype getWorktype() { - return worktype; - } - } - - public static class SaveEvent extends WorktypeFormEvent { - SaveEvent(WorktypeForm source, Worktype worktype) { - super(source, worktype); - } - } - - public static class DeleteEvent extends WorktypeFormEvent { - DeleteEvent(WorktypeForm source, Worktype worktype) { - super(source, worktype); - } - } - - public static class CloseEvent extends WorktypeFormEvent { - CloseEvent(WorktypeForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/WorktypeView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/WorktypeView.java deleted file mode 100644 index b744e09..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/WorktypeView.java +++ /dev/null @@ -1,125 +0,0 @@ -package de.thpeetz.kontor.comics.views; - -import lombok.*; -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.comics.data.Worktype; -import de.thpeetz.kontor.comics.services.ComicService; -import de.thpeetz.kontor.common.views.MainLayout; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = ComicConstants.WORKTYPE_ROUTE, layout = MainLayout.class) -@PageTitle("Worktype | Comics | Kontor") -public class WorktypeView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(Worktype.class); - TextField filterText = new TextField(); - @Getter - WorktypeForm form; - ComicService service; - - public WorktypeView(ComicService service) { - this.service = service; - addClassName("worktype-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("worktype-grid"); - grid.setSizeFull(); - grid.setColumns("name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editWorktype(event.getValue())); - } - - private void configureForm() { - form = new WorktypeForm(); - form.setWidth("45em"); - form.setVisible(false); - form.addSaveListener(this::saveWorktype); - form.addDeleteListener(this::deleteWorktype); - form.addCloseListener(e -> closeEditor()); - } - - private void saveWorktype(WorktypeForm.SaveEvent event) { - service.saveWorktype(event.getWorktype()); - updateList(); - closeEditor(); - } - - private void deleteWorktype(WorktypeForm.DeleteEvent event) { - service.deleteWorktype(event.getWorktype()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addWorktypeButton = new Button("Add worktype"); - addWorktypeButton.addClickListener(click -> addWorktype()); - - HorizontalLayout toolbar = new HorizontalLayout(filterText, addWorktypeButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editWorktype(Worktype worktype) { - if (worktype == null) { - closeEditor(); - } else { - form.setWorktype(worktype); - form.setComicWorks(worktype.getComicWorks()); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setWorktype(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addWorktype() { - grid.asSingleSelect().clear(); - editWorktype(new Worktype()); - } - - public void updateList() { - grid.setItems(service.findAllWorktypes(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/data/AbstractEntity.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/data/AbstractEntity.java deleted file mode 100644 index 182dd45..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/data/AbstractEntity.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.thpeetz.kontor.common.data; - -import jakarta.persistence.*; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; - -import java.util.Date; - -@Slf4j -@Getter -@Setter -@EqualsAndHashCode -@MappedSuperclass -@EntityListeners(AuditingEntityListener.class) -public abstract class AbstractEntity { - - @Id - @GeneratedValue(strategy = GenerationType.UUID) - private String id; - - @Version - private int version; - - @CreatedDate - private Date createdDate; - - @LastModifiedDate - private Date lastModifiedDate; - - public void updateVersion(String value) { - if (value == null) { - log.info("value not given"); - return; - } - if (version != Integer.valueOf(value).intValue()) { - log.info("update version"); - version = Integer.valueOf(value).intValue(); - } - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/data/AbstractLinkEntity.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/data/AbstractLinkEntity.java deleted file mode 100644 index 7dfdf50..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/data/AbstractLinkEntity.java +++ /dev/null @@ -1,55 +0,0 @@ -package de.thpeetz.kontor.common.data; - -import jakarta.annotation.Nullable; -import jakarta.persistence.*; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; - -import java.util.Date; - -@Slf4j -@Getter -@Setter -@EqualsAndHashCode -@MappedSuperclass -@EntityListeners(AuditingEntityListener.class) -public abstract class AbstractLinkEntity { - - @Id - @GeneratedValue(strategy = GenerationType.UUID) - private String id; - - @Version - private int version; - - @CreatedDate - private Date createdDate; - - @LastModifiedDate - private Date lastModifiedDate; - - @Nullable - private String url; - - private boolean review; - - private boolean shouldDownload; - - @Nullable - private String title; - - @Nullable - private String cloudLink; - - @Nullable - private String fileName; - - @Nullable - private String path; - -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/AvatarMenuBar.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/AvatarMenuBar.java deleted file mode 100644 index 39459ef..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/AvatarMenuBar.java +++ /dev/null @@ -1,52 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import com.vaadin.flow.component.avatar.Avatar; -import com.vaadin.flow.component.contextmenu.MenuItem; -import com.vaadin.flow.component.contextmenu.SubMenu; -import com.vaadin.flow.component.html.Div; -import com.vaadin.flow.component.menubar.MenuBar; -import com.vaadin.flow.component.menubar.MenuBarVariant; -import com.vaadin.flow.router.Route; - -import com.vaadin.flow.router.Router; -import de.thpeetz.kontor.admin.services.AdminService; -import de.thpeetz.kontor.admin.views.UserProfileView; -import de.thpeetz.kontor.security.SecurityService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; - -@Slf4j -@Route("avatar-menu-bar") -public class AvatarMenuBar extends Div { - - private final SecurityService securityService; - - final AdminService adminService; - - public AvatarMenuBar(SecurityService securityService, AdminService adminService) { - this.adminService = adminService; - this.securityService = securityService; - - Avatar avatar = new Avatar(); - securityService.getAuthenticatedUser().ifPresent(user -> { - log.info("AdminService: {}", adminService); - if (user != null) { - String userName = user.getUsername(); - String fullName = adminService.getProfileFullName(userName); - avatar.setName(fullName); - } - }); - // avatar.setImage(pictureUrl); - MenuBar menuBar = new MenuBar(); - menuBar.addThemeVariants(MenuBarVariant.LUMO_TERTIARY_INLINE); - MenuItem menuItem = menuBar.addItem(avatar); - SubMenu subMenu = menuItem.getSubMenu(); - MenuItem logoutMenuItem = subMenu.addItem("Log out"); - logoutMenuItem.addClickListener(e -> securityService.logout()); - MenuItem profileItem = subMenu.addItem("Profile"); - profileItem.addClickListener(e -> profileItem.getUI().ifPresent(ui -> ui.navigate(UserProfileView.class))); - subMenu.addItem("Settings"); - subMenu.addItem("Help"); - add(menuBar); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/ColumnToggleContextMenu.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/ColumnToggleContextMenu.java deleted file mode 100644 index f2bd74e..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/ColumnToggleContextMenu.java +++ /dev/null @@ -1,32 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.contextmenu.ContextMenu; -import com.vaadin.flow.component.contextmenu.MenuItem; -import com.vaadin.flow.component.grid.Grid; - -public class ColumnToggleContextMenu extends ContextMenu { - public ColumnToggleContextMenu(Component target) { - super(target); - setOpenOnClick(true); - } - - public void addColumnToggleItem(Grid.Column column) { - String label = column.getHeaderText(); - MenuItem menuItem = this.addItem(label, e -> { - column.setVisible(e.getSource().isChecked()); - }); - menuItem.setCheckable(true); - menuItem.setChecked(column.isVisible()); - menuItem.setKeepOpen(true); - } - - public void addColumnToggleItem(String label, Grid.Column column) { - MenuItem menuItem = this.addItem(label, e -> { - column.setVisible(e.getSource().isChecked()); - }); - menuItem.setCheckable(true); - menuItem.setChecked(column.isVisible()); - menuItem.setKeepOpen(true); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/ComicIssueField.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/ComicIssueField.java deleted file mode 100644 index 36ec905..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/ComicIssueField.java +++ /dev/null @@ -1,63 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import com.vaadin.flow.component.Unit; -import com.vaadin.flow.component.customfield.CustomField; -import com.vaadin.flow.component.select.Select; -import lombok.extern.slf4j.Slf4j; - -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.Issue; - -import java.util.List; - -@Slf4j -public class ComicIssueField extends CustomField { - - public final Select comic = new Select<>(); - public final Select issue = new Select<>(); - - public ComicIssueField(String caption) { - comic.setEnabled(false); - comic.setWidth(9, Unit.EM); - comic.setItemLabelGenerator(Comic::getTitle); - comic.addValueChangeListener(e -> { - updateIssues(); - }); - issue.setEnabled(false); - issue.setWidth(9, Unit.EM); - issue.setItemLabelGenerator(Issue::getIssueNumber); - add(comic, issue); - } - - @Override - protected Issue generateModelValue() { - log.info("ComicIssueField.generateModelValue: {}", issue.getValue()); - return issue.getValue(); - } - - @Override - protected void setPresentationValue(Issue newPresentationValue) { - log.info("ComicIssueField.setPresentationValue({})", newPresentationValue); - if (newPresentationValue == null) return; - comic.setValue(newPresentationValue.getComic()); - log.info("setPresentationValue: set Comic select = {}", comic.getValue()); - issue.setValue(newPresentationValue); - } - - public void setComics(List comics) { - log.info("ComicIssueField.setComics"); - comic.setItems(comics); - comic.setEnabled(true); - } - - private void updateIssues() { - log.info("ComicIssueField.updateIssues"); - if (comic.getValue() == null) { - issue.setValue(null); - issue.setEnabled(false); - return; - } - issue.setItems(comic.getValue().getIssues()); - issue.setEnabled(true); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/FilterOption.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/FilterOption.java deleted file mode 100644 index 757d4ed..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/FilterOption.java +++ /dev/null @@ -1,21 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@ToString -public class FilterOption { - @Getter - @Setter - private String name; - - @Getter - @Setter - private Boolean value; - - public FilterOption(String name, Boolean value) { - this.name = name; - this.value = value; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/KontorLayoutUtil.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/KontorLayoutUtil.java deleted file mode 100644 index 3a07cbb..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/KontorLayoutUtil.java +++ /dev/null @@ -1,97 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import com.vaadin.flow.component.applayout.AppLayout; -import com.vaadin.flow.component.applayout.AppLayout.Section; -import com.vaadin.flow.component.applayout.DrawerToggle; -import com.vaadin.flow.component.html.H1; -import com.vaadin.flow.component.html.H2; -import com.vaadin.flow.component.orderedlayout.FlexComponent; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.Scroller; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.sidenav.SideNav; -import com.vaadin.flow.router.RouterLink; -import com.vaadin.flow.theme.lumo.LumoUtility; - -import de.thpeetz.kontor.admin.AdminConstants; -import de.thpeetz.kontor.admin.services.AdminService; -import de.thpeetz.kontor.bookshelf.BookshelfConstants; -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.security.SecurityService; -import de.thpeetz.kontor.tysc.TyscConstants; -import lombok.*; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class KontorLayoutUtil { - - private final AppLayout appLayout; - @Setter - private HorizontalLayout secondaryNavigation; - - private final AdminService adminService; - - private final SecurityService securityService; - - public KontorLayoutUtil(AppLayout layout, AdminService adminService, SecurityService securityService) { - this.adminService = adminService; - this.securityService = securityService; - this.appLayout = layout; - } - - public void createHeader(String titleName) { - appLayout.addToDrawer(createTitle(), getScroller()); - appLayout.addToNavbar(getHeader(titleName)); - appLayout.setPrimarySection(Section.DRAWER); - } - - private H1 createTitle() { - H1 appTitle = new H1(new RouterLink("Kontor", MainView.class)); - appTitle.getStyle().set("font-size", "var(--lumo-font-size-l)") - .set("line-height", "var(--lumo-size-l)") - .set("margin", "0 var(--lumo-space-m)"); - return appTitle; - } - - private Scroller getScroller() { - Scroller scroller = new Scroller(getPrimaryNavigation()); - scroller.setClassName(LumoUtility.Padding.SMALL); - return scroller; - } - - private VerticalLayout getHeader(String header) { - DrawerToggle toggle = new DrawerToggle(); - H2 viewTitle = new H2(header); - viewTitle.addClassNames(LumoUtility.FontSize.LARGE, LumoUtility.Margin.NONE); - HorizontalLayout subViews = this.secondaryNavigation; - - AvatarMenuBar avatar = new AvatarMenuBar(securityService, adminService); - HorizontalLayout wrapper = new HorizontalLayout(toggle, viewTitle, avatar); - wrapper.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER); - wrapper.expand(viewTitle); - wrapper.setWidthFull(); - wrapper.setSpacing(false); - - VerticalLayout viewHeader = new VerticalLayout(wrapper, subViews); - viewHeader.setPadding(false); - viewHeader.setSpacing(false); - return viewHeader; - } - - private SideNav getPrimaryNavigation() { - SideNav sideNav = new SideNav(); - sideNav.addItem(ComicConstants.getComicsNavigation()); - sideNav.addItem(TyscConstants.getTyscNavigation()); - sideNav.addItem(BookshelfConstants.getBookshelfNavigation()); - securityService.getAuthenticatedUser().ifPresent(user -> { - log.info("User {} found", user.getUsername()); - boolean isAdmin = user.getAuthorities().stream() - .anyMatch(grantedAuthority -> "ROLE_ADMIN".equals(grantedAuthority.getAuthority())); - log.info("User {} hat Admin-Rechte: {}", user, isAdmin); - if (isAdmin) { - sideNav.addItem(AdminConstants.getAdminNavigation()); - } - }); - return sideNav; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/MainLayout.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/MainLayout.java deleted file mode 100644 index 95d60cc..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/MainLayout.java +++ /dev/null @@ -1,102 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import com.vaadin.flow.component.applayout.AppLayout; -import com.vaadin.flow.component.applayout.DrawerToggle; -import com.vaadin.flow.component.html.H1; -import com.vaadin.flow.component.html.H2; -import com.vaadin.flow.component.icon.VaadinIcon; -import com.vaadin.flow.component.orderedlayout.FlexComponent; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.Scroller; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.sidenav.SideNav; -import com.vaadin.flow.component.sidenav.SideNavItem; -import com.vaadin.flow.router.RouterLink; -import com.vaadin.flow.theme.lumo.LumoUtility; - -import de.thpeetz.kontor.admin.AdminConstants; -import de.thpeetz.kontor.admin.services.AdminService; -import de.thpeetz.kontor.bookshelf.BookshelfConstants; -import de.thpeetz.kontor.comics.ComicConstants; -import de.thpeetz.kontor.data.views.DataManagementView; -import de.thpeetz.kontor.mailclient.views.EmailView; -import de.thpeetz.kontor.media.MediaConstants; -import de.thpeetz.kontor.security.SecurityService; -import de.thpeetz.kontor.tysc.TyscConstants; -import lombok.extern.slf4j.Slf4j; - -import java.util.ArrayList; - -@Slf4j -public class MainLayout extends AppLayout { - - private final AdminService adminService; - - private final SecurityService securityService; - - public MainLayout(AdminService adminService, SecurityService securityService) { - this.adminService = adminService; - this.securityService = securityService; - - createHeader("Kontor"); - createDrawer(); - } - - public void createDrawer() { - H1 appTitle = new H1(new RouterLink("Kontor", MainView.class)); - appTitle.getStyle().set("font-size", "var(--lumo-font-size-l)") - .set("line-height", "var(--lumo-size-l)") - .set("margin", "0 var(--lumo-space-m)"); - Scroller scroller = new Scroller(getPrimaryNavigation()); - scroller.setClassName(LumoUtility.Padding.SMALL); - addToDrawer(appTitle, scroller); - } - - public void createHeader(String titleName) { - DrawerToggle toggle = new DrawerToggle(); - H2 viewTitle = new H2(titleName); - viewTitle.addClassNames(LumoUtility.FontSize.LARGE, LumoUtility.Margin.NONE); - - AvatarMenuBar avatar = new AvatarMenuBar(securityService, adminService); - HorizontalLayout wrapper = new HorizontalLayout(toggle, viewTitle, avatar); - wrapper.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER); - wrapper.expand(viewTitle); - wrapper.setWidthFull(); - wrapper.setSpacing(false); - - VerticalLayout viewHeader = new VerticalLayout(wrapper); - viewHeader.setPadding(false); - viewHeader.setSpacing(false); - - addToNavbar(viewHeader); - setPrimarySection(Section.DRAWER); - } - - private SideNav getPrimaryNavigation() { - SideNav sideNav = new SideNav(); - ArrayList roles = new ArrayList<>(); - securityService.getAuthenticatedUser().ifPresent(user -> { - log.info("Get roles for user {}", user.getUsername()); - user.getAuthorities().forEach(grantedAuthority -> { - roles.add(grantedAuthority.getAuthority()); - }); - log.info("user {} has roles: {}", user, roles); - }); - sideNav.addItem(ComicConstants.getComicsNavigation()); - sideNav.addItem(TyscConstants.getTyscNavigation()); - sideNav.addItem(BookshelfConstants.getBookshelfNavigation()); - sideNav.addItem(MediaConstants.getMediaNavigation(roles)); - sideNav.addItem(new SideNavItem("Emails", EmailView.class)); - sideNav.addItem(new SideNavItem("Data Management", DataManagementView.class, VaadinIcon.DATABASE.create())); - securityService.getAuthenticatedUser().ifPresent(user -> { - log.info("User {} found", user.getUsername()); - boolean isAdmin = user.getAuthorities().stream() - .anyMatch(grantedAuthority -> "ROLE_ADMIN".equals(grantedAuthority.getAuthority())); - log.info("User {} hat Admin-Rechte: {}", user, isAdmin); - if (isAdmin) { - sideNav.addItem(AdminConstants.getAdminNavigation()); - } - }); - return sideNav; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/MainView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/MainView.java deleted file mode 100644 index 08edac9..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/MainView.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.server.auth.AnonymousAllowed; -import com.vaadin.flow.spring.annotation.SpringComponent; - -@SpringComponent -@Scope("prototype") -@AnonymousAllowed -@Route(value = "/", layout = MainLayout.class) -@PageTitle("Kontor") -public class MainView extends VerticalLayout { - -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilter.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilter.java deleted file mode 100644 index 7eb97e5..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilter.java +++ /dev/null @@ -1,36 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@ToString -public class SearchFilter { - - @Getter - @Setter - private String searchTerm; - - @Getter - private List filterOptions = new LinkedList<>(); - - private final Map filterMap = new HashMap<>(); - - public SearchFilter() { - - } - - public void addFilter(FilterOption option) { - filterOptions.add(option); - filterMap.put(option.getName(), option); - } - - public FilterOption getFilter(String optionName) { - return filterMap.get(optionName); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilterField.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilterField.java deleted file mode 100644 index 2d37df0..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SearchFilterField.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import com.vaadin.flow.component.combobox.MultiSelectComboBox; -import com.vaadin.flow.component.combobox.MultiSelectComboBox.AutoExpandMode; -import com.vaadin.flow.component.customfield.CustomField; -import com.vaadin.flow.component.textfield.TextField; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class SearchFilterField extends CustomField { - - private final TextField searchField = new TextField(); - private final MultiSelectComboBox filterField = new MultiSelectComboBox<>(); - private final List filterOptions = new LinkedList<>(); - - public SearchFilterField() { - searchField.setPlaceholder("Search"); - searchField.setClearButtonVisible(true); - filterField.setPlaceholder("Filter"); - filterField.setClearButtonVisible(true); - filterField.setItemLabelGenerator(FilterOption::getName); - filterField.setAutoExpand(AutoExpandMode.BOTH); - add(searchField, filterField); - } - - @Override - protected SearchFilter generateModelValue() { - SearchFilter filter = new SearchFilter(); - if (searchField.getValue() != null) { - filter.setSearchTerm(searchField.getValue()); - } - Set filterOptions = filterField.getValue(); - for (FilterOption filterOption : filterOptions) { - filter.addFilter(filterOption); - } - log.info("use searchfilter: {}", filter); - return filter; - } - - @Override - protected void setPresentationValue(SearchFilter searchFilter) { - log.info("display filter: {}", searchFilter); - if (searchFilter == null) return; - searchField.setValue(searchFilter.getSearchTerm()); - } - - public void addFilter(String optionName) { - FilterOption filterOption = new FilterOption(optionName, true); - filterOptions.add(filterOption); - filterField.setItems(filterOptions); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SeparateMainLayout.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SeparateMainLayout.java deleted file mode 100644 index 3ea163f..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/SeparateMainLayout.java +++ /dev/null @@ -1,25 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import com.vaadin.flow.component.applayout.AppLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.theme.lumo.LumoUtility; - -import de.thpeetz.kontor.admin.services.AdminService; -import de.thpeetz.kontor.security.SecurityService; - -public class SeparateMainLayout extends AppLayout { - - public SeparateMainLayout(AdminService adminService, SecurityService securityService) { - - KontorLayoutUtil layout = new KontorLayoutUtil(this, adminService, securityService); - layout.setSecondaryNavigation(getSecondaryNavigation()); - layout.createHeader("Kontor"); - } - - private HorizontalLayout getSecondaryNavigation() { - HorizontalLayout navigation = new HorizontalLayout(); - navigation.addClassNames(LumoUtility.JustifyContent.CENTER, LumoUtility.Gap.SMALL, LumoUtility.Height.MEDIUM); - return navigation; - } - -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/StatusIcon.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/StatusIcon.java deleted file mode 100644 index 4e058c6..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/StatusIcon.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import com.vaadin.flow.component.icon.Icon; -import com.vaadin.flow.component.icon.VaadinIcon; - -public class StatusIcon { - public static Icon create(boolean status) { - Icon icon; - if (status) { - icon = VaadinIcon.CHECK.create(); - icon.getElement().getThemeList().add("badge success"); - } else { - icon = VaadinIcon.CLOSE_SMALL.create(); - icon.getElement().getThemeList().add("badge error"); - } - icon.getStyle().set("padding", "var(--lumo-space-xs"); - return icon; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/YearMonthField.java b/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/YearMonthField.java deleted file mode 100644 index edc228a..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/common/views/YearMonthField.java +++ /dev/null @@ -1,54 +0,0 @@ -package de.thpeetz.kontor.common.views; - -import com.vaadin.flow.component.Unit; -import com.vaadin.flow.component.customfield.CustomField; -import com.vaadin.flow.component.select.Select; -import lombok.extern.slf4j.Slf4j; - -import java.time.LocalDate; -import java.time.Month; -import java.time.YearMonth; -import java.time.ZoneId; -import java.time.format.TextStyle; -import java.util.List; -import java.util.Locale; -import java.util.stream.IntStream; - -@Slf4j -public class YearMonthField extends CustomField { - - private final Select year = new Select<>();; - private final Select month = new Select<>(); - - public YearMonthField() { - LocalDate now = LocalDate.now(ZoneId.systemDefault()); - List selectableYears = IntStream.range(1970, now.getYear()).boxed().toList(); - year.setItems(selectableYears); - year.setWidth(6, Unit.EM); - month.setItems(Month.values()); - month.setItemLabelGenerator(m -> m.getDisplayName(TextStyle.FULL, Locale.getDefault())); - month.setWidth(9, Unit.EM); - add(year, month); - } - - @Override - protected YearMonth generateModelValue() { - if (year.getValue() != null && month.getValue() != null) { - int yearValue = year.getValue(); - int monthValue = month.getValue().getValue(); - YearMonth result = YearMonth.of(yearValue, monthValue); - log.debug("YearMonthField.generateModelValue() = {}", result); - return result; - } else { - log.debug("YearMonthField.generateModelValue() = null"); - return null; - } - } - - @Override - protected void setPresentationValue(YearMonth yearMonth) { - if (yearMonth == null) return; - year.setValue(yearMonth.getYear()); - month.setValue(yearMonth.getMonth()); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/constants/AdminConstants.java b/kontor-spring/src/main/java/de/thpeetz/kontor/constants/AdminConstants.java new file mode 100644 index 0000000..2882fb2 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/constants/AdminConstants.java @@ -0,0 +1,56 @@ +package de.thpeetz.kontor.constants; + +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.sidenav.SideNavItem; +import com.vaadin.flow.router.RouterLink; + +import de.thpeetz.kontor.views.admin.AssignmentView; +import de.thpeetz.kontor.views.admin.PermissionView; +import de.thpeetz.kontor.views.admin.ProfileView; +import de.thpeetz.kontor.views.comics.ComicWorkView; +import de.thpeetz.kontor.views.comics.IssueWorkView; +import de.thpeetz.kontor.views.media.MediaActorFileView; + +public class AdminConstants { + + private AdminConstants() { + // private constructor to hide the implicit public one + } + + public static final String ADMIN_TITLE = "Verwaltung"; + public static final String AUTHORIZATION = "Berechtigungen"; + public static final String ASSIGNMENT_ROUTE = "/admin/assignment"; + public static final String DATA = "Daten"; + public static final String METADATA_ROUTE = "admin/metadata"; + public static final String PERMISSION = "Berechtigungen"; + public static final String PERMISSION_ROUTE = "/admin/permission"; + public static final String PROFILE = "Benutzer"; + public static final String PROFILE_ROUTE = "/admin/profile"; + public static final String ADMIN = "admin"; + public static final String ADMIN_ROUTE = "/admin"; + + public static RouterLink getProfileNavigation() { + return new RouterLink(PROFILE, ProfileView.class); + } + + public static RouterLink getPermissionNavigation() { + return new RouterLink(PERMISSION, PermissionView.class); + } + + public static RouterLink getAuthorizationNavigation() { + return new RouterLink(AUTHORIZATION, AssignmentView.class); + } + + public static SideNavItem getAdminNavigation() { + SideNavItem administration = new SideNavItem(ADMIN_TITLE, PROFILE_ROUTE, VaadinIcon.GROUP.create()); + administration.addItem(new SideNavItem(PROFILE, PROFILE_ROUTE, VaadinIcon.USERS.create())); + administration.addItem(new SideNavItem(PERMISSION, PermissionView.class)); + SideNavItem data = new SideNavItem(DATA, ASSIGNMENT_ROUTE, VaadinIcon.DATABASE.create()); + data.addItem(new SideNavItem(ComicConstants.COMICWORK, ComicWorkView.class)); + data.addItem(new SideNavItem(ComicConstants.ISSUEWORK, IssueWorkView.class)); + data.addItem(new SideNavItem(MediaConstants.MEDIAACTORFILE, MediaActorFileView.class)); + data.addItem(new SideNavItem(AUTHORIZATION, AssignmentView.class)); + administration.addItem(data); + return administration; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/constants/BookshelfConstants.java b/kontor-spring/src/main/java/de/thpeetz/kontor/constants/BookshelfConstants.java new file mode 100644 index 0000000..aacb136 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/constants/BookshelfConstants.java @@ -0,0 +1,52 @@ +package de.thpeetz.kontor.constants; + +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.sidenav.SideNavItem; +import com.vaadin.flow.router.RouterLink; + +import de.thpeetz.kontor.views.bookshelf.ArticleView; +import de.thpeetz.kontor.views.bookshelf.AuthorView; +import de.thpeetz.kontor.views.bookshelf.BookView; +import de.thpeetz.kontor.views.bookshelf.BookshelfPublisherView; + +public class BookshelfConstants { + + public static final String AUTHOR = "Author"; + public static final String ARTICLE = "Article"; + public static final String BOOK = "Book"; + public static final String BOOKSHELF = "Bookshelf"; + public static final String PUBLISHER = "Publisher"; + public static final String PUBLISHER_ROUTE = "bookshelf/publisher"; + public static final String AUTHOR_ROUTE = "bookshelf/author"; + public static final String BOOK_ROUTE = "bookshelf/book"; + public static final String ARTICLE_ROUTE = "bookshelf/article"; + + public static RouterLink getPublisherLink() { + return new RouterLink(PUBLISHER, BookshelfPublisherView.class); + } + + public static RouterLink getAuthorLink() { + return new RouterLink(AUTHOR, AuthorView.class); + } + + public static RouterLink getBookLink() { + return new RouterLink(BOOK, BookView.class); + } + + public static RouterLink getArticleLink() { + return new RouterLink(ARTICLE, ArticleView.class); + } + + public static SideNavItem getBookshelfNavigation() { + SideNavItem bookshelf = new SideNavItem(BOOKSHELF, BookView.class, VaadinIcon.OPEN_BOOK.create()); + bookshelf.addItem(new SideNavItem(BOOK, BookView.class)); + bookshelf.addItem(new SideNavItem(PUBLISHER, BookshelfPublisherView.class)); + bookshelf.addItem(new SideNavItem(AUTHOR, AuthorView.class)); + bookshelf.addItem(new SideNavItem(ARTICLE, ArticleView.class)); + return bookshelf; + } + + private BookshelfConstants() { + // private constructor to hide the implicit public one + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/constants/ComicConstants.java b/kontor-spring/src/main/java/de/thpeetz/kontor/constants/ComicConstants.java new file mode 100644 index 0000000..15a5150 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/constants/ComicConstants.java @@ -0,0 +1,101 @@ +package de.thpeetz.kontor.constants; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.sidenav.SideNavItem; +import com.vaadin.flow.router.RouterLink; + +import de.thpeetz.kontor.views.comics.ArtistView; +import de.thpeetz.kontor.views.comics.ComicView; +import de.thpeetz.kontor.views.comics.ComicWorkView; +import de.thpeetz.kontor.views.comics.IssueView; +import de.thpeetz.kontor.views.comics.IssueWorkView; +import de.thpeetz.kontor.views.comics.PublisherView; +import de.thpeetz.kontor.views.comics.StoryArcView; +import de.thpeetz.kontor.views.comics.TradePaperbackView; +import de.thpeetz.kontor.views.comics.VolumeView; +import de.thpeetz.kontor.views.comics.WorktypeView; + +/** + * The {@code ComicConstants} class contains constant values related to comics. + */ +public class ComicConstants { + + public static final String COMICS = "Comics"; + public static final String COMICS_ROUTE = "comics/comic"; + public static final String PUBLISHER = "Publisher"; + public static final String PUBLISHER_ROUTE = "comics/publisher"; + public static final String COMICWORK = "ComicWork"; + public static final String ISSUEWORK = "IssueWork"; + public static final String COMICWORK_ROUTE = "comics/comicwork"; + public static final String ISSUEWORK_ROUTE = "comics/issuework"; + public static final String WORKTYPE = "Worktype"; + public static final String WORKTYPE_ROUTE = "comics/worktype"; + public static final String ARTIST = "Artist"; + public static final String ARTIST_ROUTE = "comics/artist"; + public static final String TPB = "TradePaperback"; + public static final String TPB_ROUTE = "comics/tradepaperback"; + public static final String STORYARC = "Story Arc"; + public static final String STORYARC_ROTE = "comics/storyarc"; + public static final String ISSUE = "Issue"; + public static final String ISSUE_ROUTE = "comics/issue"; + public static final String VOLUME = "Volume"; + public static final String VOLUME_ROUTE = "comics/volume"; + + public static RouterLink getArtistLink() { + return new RouterLink(ARTIST, ArtistView.class); + } + + public static RouterLink getComicLink() { + return new RouterLink(COMICS, ComicView.class); + } + + public static RouterLink getPublisherLink() { + return new RouterLink(PUBLISHER, PublisherView.class); + } + + public static RouterLink getComicWorkLink() { + return new RouterLink(COMICWORK, ComicWorkView.class); + } + + public static RouterLink getIssueWorkLink() { + return new RouterLink(ISSUEWORK, IssueWorkView.class); + } + + public static RouterLink getIssueLink() { + return new RouterLink(ISSUE, IssueView.class); + } + + public static RouterLink getTradePaperbackLink() { + return new RouterLink(TPB, TradePaperbackView.class); + } + + public static Component getStoryArcLink() { + return new RouterLink(STORYARC, StoryArcView.class); + } + + public static RouterLink getWorktypeLink() { + return new RouterLink(WORKTYPE, WorktypeView.class); + } + + public static RouterLink getVolumeLink() { + return new RouterLink(VOLUME, VolumeView.class); + } + + public static SideNavItem getComicsNavigation() { + SideNavItem comics = new SideNavItem(COMICS, COMICS_ROUTE, VaadinIcon.RECORDS.create()); + comics.addItem(new SideNavItem(ARTIST, ArtistView.class)); + comics.addItem(new SideNavItem(COMICS, ComicView.class)); + comics.addItem(new SideNavItem(PUBLISHER, PublisherView.class)); + comics.addItem(new SideNavItem(ISSUE, IssueView.class)); + comics.addItem(new SideNavItem(TPB, TradePaperbackView.class)); + comics.addItem(new SideNavItem(STORYARC, StoryArcView.class)); + comics.addItem(new SideNavItem(VOLUME, VolumeView.class)); + comics.addItem(new SideNavItem(WORKTYPE, WorktypeView.class)); + return comics; + } + + private ComicConstants() { + // private constructor to hide the implicit public one + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/constants/MediaConstants.java b/kontor-spring/src/main/java/de/thpeetz/kontor/constants/MediaConstants.java new file mode 100644 index 0000000..6edcd0e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/constants/MediaConstants.java @@ -0,0 +1,52 @@ +package de.thpeetz.kontor.constants; + +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.sidenav.SideNavItem; + +import de.thpeetz.kontor.views.media.MediaActorView; +import de.thpeetz.kontor.views.media.MediaArticleView; +import de.thpeetz.kontor.views.media.MediaFileView; +import de.thpeetz.kontor.views.media.MediaLofiView; +import de.thpeetz.kontor.views.media.MediaVideoView; + +import java.util.ArrayList; + +public class MediaConstants { + + public static final String MEDIA = "Media"; + public static final String MEDIAFILE_ROUTE = "media/mediafile"; + public static final String MEDIAVIDEO_ROUTE = "media/mediavideo"; + public static final String MEDIALOFI_ROUTE = "media/medialofi"; + public static final String MEDIAARTICLE_ROUTE = "media/mediaarticle"; + public static final String MEDIA_ROLE = "ROLE_MEDIA"; + public static final String MEDIAACTOR_ROUTE = "media/mediaactor"; + public static final String MEDIAACTORFILE_ROUTE = "media/mediaactorfile"; + public static final String MEDIAACTORFILE = "Media Actor Files"; + private static final String MEDIAFILE = "Media Files"; + private static final String MEDIAVIDEO = "Media Videos"; + private static final String MEDIALOFI = "Media Lofi"; + private static final String MEDIAARTICLE = "Media Article"; + private static final String MEDIAACTOR = "Media Actor"; + + public static final String URL = "url"; + public static final String LINKTITLE = "linkTitle"; + public static final String LOFI_ID = "lofi_id"; + public static final String FILE_ID = "file_id"; + public static final String VIDEO_ID = "video_id"; + + public static SideNavItem getMediaNavigation(ArrayList roles) { + SideNavItem media = new SideNavItem(MEDIA, MEDIAFILE_ROUTE, VaadinIcon.VIMEO.create()); + media.addItem(new SideNavItem(MEDIAVIDEO, MediaVideoView.class)); + media.addItem(new SideNavItem(MEDIALOFI, MediaLofiView.class)); + media.addItem(new SideNavItem(MEDIAARTICLE, MediaArticleView.class)); + if (roles.contains(MEDIA_ROLE)) { + media.addItem(new SideNavItem(MEDIAFILE, MediaFileView.class)); + media.addItem(new SideNavItem(MEDIAACTOR, MediaActorView.class)); + } + return media; + } + + private MediaConstants() { + // private constructor to hide the implicit public one + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/constants/TyscConstants.java b/kontor-spring/src/main/java/de/thpeetz/kontor/constants/TyscConstants.java new file mode 100644 index 0000000..42ec5bb --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/constants/TyscConstants.java @@ -0,0 +1,88 @@ +package de.thpeetz.kontor.constants; + +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.sidenav.SideNavItem; +import com.vaadin.flow.router.RouterLink; + +import de.thpeetz.kontor.views.tysc.CardSetView; +import de.thpeetz.kontor.views.tysc.CardView; +import de.thpeetz.kontor.views.tysc.PlayerView; +import de.thpeetz.kontor.views.tysc.PositionView; +import de.thpeetz.kontor.views.tysc.RoosterView; +import de.thpeetz.kontor.views.tysc.SportView; +import de.thpeetz.kontor.views.tysc.TeamView; +import de.thpeetz.kontor.views.tysc.VendorView; + +/** + * The {@code TyscConstants} class contains constant values related to tysc. + */ +public class TyscConstants { + + public static final String TYSC = "TradeYourSportsCards"; + public static final String TYSC_ROLE = "ROLE_TYSC"; + public static final String VENDOR = "Vendor"; + public static final String VENDOR_ROUTE = "tysc/vendor"; + public static final String CARDSET = "Card Set"; + public static final String CARDSET_ROUTE = "tysc/cardset"; + public static final String CARD = "Card"; + public static final String CARD_ROUTE = "tysc/card"; + public static final String SPORT = "Sport"; + public static final String SPORT_ROUTE = "tysc/sport"; + public static final String TEAM = "Team"; + public static final String TEAM_ROUTE = "tysc/team"; + public static final String POSITION = "Position"; + public static final String POSITION_ROUTE = "tysc/position"; + public static final String PLAYER = "Player"; + public static final String PLAYER_ROUTE = "tysc/player"; + public static final String ROOSTER = "Rooster"; + public static final String ROOSTER_ROUTE = "tysc/rooster"; + + public static RouterLink getSportLink() { + return new RouterLink(SPORT, SportView.class); + } + + public static RouterLink getTeamLink() { + return new RouterLink(TEAM, TeamView.class); + } + + public static RouterLink getPlayerLink() { + return new RouterLink(PLAYER, PlayerView.class); + } + + public static RouterLink getPositionLink() { + return new RouterLink(POSITION, PositionView.class); + } + + public static RouterLink getRoosterLink() { + return new RouterLink(ROOSTER, RoosterView.class); + } + + public static RouterLink getVendorLink() { + return new RouterLink(VENDOR, VendorView.class); + } + + public static RouterLink getCardSetLink() { + return new RouterLink(CARDSET, CardSetView.class); + } + + public static RouterLink getCardLink() { + return new RouterLink(CARD, CardView.class); + } + + public static SideNavItem getTyscNavigation() { + SideNavItem tysc = new SideNavItem(TYSC, VENDOR_ROUTE, VaadinIcon.ARCHIVE.create()); + tysc.addItem(new SideNavItem(SPORT, SportView.class)); + tysc.addItem(new SideNavItem(TEAM, TeamView.class)); + tysc.addItem(new SideNavItem(PLAYER, PlayerView.class)); + tysc.addItem(new SideNavItem(POSITION, PositionView.class)); + tysc.addItem(new SideNavItem(ROOSTER, RoosterView.class)); + tysc.addItem(new SideNavItem(CARDSET, CardSetView.class)); + tysc.addItem(new SideNavItem(CARD, CardView.class)); + tysc.addItem(new SideNavItem(VENDOR, VendorView.class)); + return tysc; + } + + private TyscConstants() { + // private constructor to hide the implicit public one + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/admin/Assignment.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/admin/Assignment.java new file mode 100644 index 0000000..1951028 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/admin/Assignment.java @@ -0,0 +1,34 @@ +package de.thpeetz.kontor.data.admin; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Entity +public class Assignment extends AbstractEntity { + + @ManyToOne + @JoinColumn(name = "profile_id") + @NotNull + private Profile profile; + + @ManyToOne + @JoinColumn(name = "permission_id") + @NotNull + private Permission permission; + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("Assignment{"); + sb.append("profile=").append(profile.getUserName()); + sb.append(", permission=").append(permission.getName()); + sb.append('}'); + return sb.toString(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/admin/Permission.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/admin/Permission.java new file mode 100644 index 0000000..3c77b10 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/admin/Permission.java @@ -0,0 +1,31 @@ +package de.thpeetz.kontor.data.admin; + +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.OneToMany; +import jakarta.validation.constraints.NotEmpty; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +import javax.annotation.Nullable; + +import de.thpeetz.kontor.data.common.AbstractEntity; + +import java.util.List; + +@Slf4j +@Getter +@Setter +@ToString +@Entity +public class Permission extends AbstractEntity { + + @NotEmpty + private String name; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "permission") + @Nullable + private List assignments; +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/admin/Profile.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/admin/Profile.java new file mode 100644 index 0000000..00f88fb --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/admin/Profile.java @@ -0,0 +1,59 @@ +package de.thpeetz.kontor.data.admin; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotEmpty; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +import javax.annotation.Nullable; + +import de.thpeetz.kontor.data.common.AbstractEntity; + +import java.util.LinkedList; +import java.util.List; + +@Slf4j +@Getter +@Setter +@ToString +@Entity +@Table(indexes = @Index(columnList = "userName"), uniqueConstraints = @UniqueConstraint(columnNames = {"userName"})) +public class Profile extends AbstractEntity { + + private String firstName; + + private String lastName; + + @NotEmpty + private String userName; + + private String email; + + private String password; + + private boolean enabled; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "profile") + @Nullable + private List assignments = new LinkedList<>(); + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "profile") + @Nullable + private List tokens = new LinkedList<>(); + + public String getFullName() { + StringBuilder fullNameBuilder = new StringBuilder(); + if (firstName != null) { + fullNameBuilder.append(firstName); + } + if (lastName != null) { + if (!fullNameBuilder.isEmpty()) { + fullNameBuilder.append(" "); + } + fullNameBuilder.append(lastName); + } + return fullNameBuilder.toString(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/admin/Token.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/admin/Token.java new file mode 100644 index 0000000..6fa77cc --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/admin/Token.java @@ -0,0 +1,38 @@ +package de.thpeetz.kontor.data.admin; + +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; +import java.util.Date; + +import de.thpeetz.kontor.data.common.AbstractEntity; + +@Slf4j +@Getter +@Setter +@ToString +@Entity +@Table(indexes = @Index(columnList = "token"), uniqueConstraints = @UniqueConstraint(columnNames = {"token"})) +public class Token extends AbstractEntity { + + private String token; + + private String name; + + private Date lastUsedDate; + + private boolean enabled; + + @ManyToOne + @JoinColumn(name="profile_id") + @NotNull + private Profile profile; +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/Article.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/Article.java new file mode 100644 index 0000000..ed37e68 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/Article.java @@ -0,0 +1,27 @@ +package de.thpeetz.kontor.data.bookshelf; + +import java.util.LinkedList; +import java.util.List; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotEmpty; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@Entity +@Table(indexes = @Index(columnList = "title"), uniqueConstraints = @UniqueConstraint(columnNames = {"title"})) +public class Article extends AbstractEntity { + + @NotEmpty + private String title; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "article") + @Nullable + private List authors = new LinkedList<>(); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/ArticleAuthor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/ArticleAuthor.java new file mode 100644 index 0000000..df9118e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/ArticleAuthor.java @@ -0,0 +1,29 @@ +package de.thpeetz.kontor.data.bookshelf; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Entity +@Table(indexes = @Index(columnList = "author_id, article_id"), uniqueConstraints = @UniqueConstraint(columnNames = {"author_id", "article_id"})) +public class ArticleAuthor extends AbstractEntity { + + @ManyToOne + @JoinColumn(name = "author_id") + @NotNull + private Author author; + + @ManyToOne + @JoinColumn(name = "article_id") + @NotNull + private Article article; +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/Author.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/Author.java new file mode 100644 index 0000000..caf4e1e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/Author.java @@ -0,0 +1,44 @@ +package de.thpeetz.kontor.data.bookshelf; + +import java.util.LinkedList; +import java.util.List; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Index; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotEmpty; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@Entity +@Table(indexes = { + @Index(columnList = "firstName, lastName"), + @Index(columnList = "lastName, firstName") +}, uniqueConstraints = { + @UniqueConstraint(columnNames = { "firstName", "lastName" }) +}) +public class Author extends AbstractEntity { + + @NotEmpty + private String firstName; + + @NotEmpty + private String lastName; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "author") + @Nullable + private List bookAuthors = new LinkedList<>(); + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "author") + @Nullable + private List articleAuthors = new LinkedList<>(); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/Book.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/Book.java new file mode 100644 index 0000000..469125c --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/Book.java @@ -0,0 +1,42 @@ +package de.thpeetz.kontor.data.bookshelf; + +import java.util.LinkedList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@Entity +@Table(indexes = @Index(columnList = "title, isbn"), uniqueConstraints = @UniqueConstraint(columnNames = {"isbn"})) +public class Book extends AbstractEntity { + + @NotEmpty + private String title; + + @NotEmpty + private String isbn; + + @Nullable + private int year; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "book") + @Nullable + private List authors = new LinkedList<>(); + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "publisher_id") + @NotNull + @JsonIgnoreProperties({ "books" }) + private BookshelfPublisher publisher; +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/BookAuthor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/BookAuthor.java new file mode 100644 index 0000000..1ce09e9 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/BookAuthor.java @@ -0,0 +1,29 @@ +package de.thpeetz.kontor.data.bookshelf; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Entity +@Table(indexes = @Index(columnList = "author_id, book_id"), uniqueConstraints = @UniqueConstraint(columnNames = {"author_id", "book_id"})) +public class BookAuthor extends AbstractEntity { + + @ManyToOne + @JoinColumn(name = "author_id") + @NotNull + private Author author; + + @ManyToOne + @JoinColumn(name = "book_id") + @NotNull + private Book book; +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/BookshelfPublisher.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/BookshelfPublisher.java new file mode 100644 index 0000000..fddede6 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/bookshelf/BookshelfPublisher.java @@ -0,0 +1,32 @@ +package de.thpeetz.kontor.data.bookshelf; + +import java.util.LinkedList; +import java.util.List; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Index; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotEmpty; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@Entity +@Table(indexes = @Index(columnList = "name"), uniqueConstraints = @UniqueConstraint(columnNames = { "name" })) +public class BookshelfPublisher extends AbstractEntity { + + @NotEmpty + private String name; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "publisher", orphanRemoval = true) + @Nullable + List books = new LinkedList<>(); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Artist.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Artist.java new file mode 100644 index 0000000..932257e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Artist.java @@ -0,0 +1,50 @@ +package de.thpeetz.kontor.data.comics; + +import java.util.LinkedList; +import java.util.List; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import io.micrometer.common.lang.Nullable; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.OneToMany; +import jakarta.validation.constraints.NotEmpty; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +/** + * Represents an artist in the system. + */ +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Slf4j +@Entity +public class Artist extends AbstractEntity { + + @NotEmpty + @Column(unique = true) + private String name; + + private String weblink; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "artist", cascade = CascadeType.REFRESH, orphanRemoval = true) + @Nullable + List comicWorks = new LinkedList<>(); + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "artist", cascade = CascadeType.REFRESH, orphanRemoval = true) + @Nullable + List issueWorks = new LinkedList<>(); + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("Artist{"); + sb.append("name='").append(name).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Comic.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Comic.java new file mode 100644 index 0000000..28bc7b7 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Comic.java @@ -0,0 +1,83 @@ +package de.thpeetz.kontor.data.comics; + +import java.util.LinkedList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +/** + * Represents a comic entity. + */ +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +public class Comic extends AbstractEntity { + + @NotEmpty + @Column(unique = true) + private String title; + + @ManyToOne + @JoinColumn(name = "publisher_id") + @NotNull + @JsonIgnoreProperties({ "comics" }) + private Publisher publisher; + + private Boolean currentOrder = false; + + private Boolean completed = false; + + @Nullable + private String weblink; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true) + @Nullable + List comicWorks; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true) + @Nullable + private List issues = new LinkedList<>(); + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true) + @Nullable + private List storyArcs = new LinkedList<>(); + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true) + @Nullable + private List tradePaperbacks = new LinkedList<>(); + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true) + @Nullable + private List volumes = new LinkedList<>(); + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("Comic{"); + sb.append("title='").append(title).append('\''); + sb.append(", publisher=").append(publisher); + sb.append(", currentOrder=").append(currentOrder); + sb.append(", completed=").append(completed); + sb.append('}'); + return sb.toString(); + } + + public String getPublisherName() { + return this.publisher.getName(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/ComicWork.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/ComicWork.java new file mode 100644 index 0000000..b8ddfb7 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/ComicWork.java @@ -0,0 +1,48 @@ +package de.thpeetz.kontor.data.comics; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +@Table(indexes = {@Index(columnList = "comic_id, artist_id, workType_id") }, + uniqueConstraints = @UniqueConstraint(columnNames = {"comic_id", "artist_id", "workType_id" }) +) +public class ComicWork extends AbstractEntity { + + @ManyToOne + @JoinColumn(name = "comic_id") + @NotNull + private Comic comic; + + @ManyToOne + @JoinColumn(name = "artist_id") + @NotNull + private Artist artist; + + @ManyToOne + @JoinColumn(name = "workType_id") + @NotNull + private Worktype workType; + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("ComicWork{"); + sb.append("comic=").append(comic); + sb.append(", artist=").append(artist); + sb.append(", workType=").append(workType); + sb.append('}'); + return sb.toString(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Issue.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Issue.java new file mode 100644 index 0000000..baa7718 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Issue.java @@ -0,0 +1,108 @@ +package de.thpeetz.kontor.data.comics; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import io.hypersistence.utils.hibernate.type.basic.YearMonthDateType; +import jakarta.annotation.Nullable; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.Type; + +import java.time.YearMonth; +import java.util.*; + +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +public class Issue extends AbstractEntity { + + @ManyToOne + @JoinColumn(name = "comic_id") + @NotNull + @JsonIgnoreProperties({ "issues" }) + private Comic comic; + + @ManyToOne + @JoinColumn(name = "volume_id") + @JsonIgnoreProperties({ "issues" }) + @Nullable + private Volume volume; + + @ManyToOne + @JoinColumn(name = "storyArc_id") + @JsonIgnoreProperties({ "issues" }) + @Nullable + private StoryArc storyArc; + + @NotEmpty + private String issueNumber; + + @Nullable + private String title; + + @Nullable + @Type(YearMonthDateType.class) + @Column(name = "published_on", columnDefinition = "date") + private YearMonth publishedOn; + + private Boolean isRead; + + private Boolean inStock; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "issue", cascade = CascadeType.REFRESH, orphanRemoval = true) + @Nullable + List issueWorks; + + public String getComicTitle() { + return comic.getTitle(); + } + + public String getVolumeName() { + if (volume != null) { + return volume.getName(); + } + return null; + } + + public String getFullTitle() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(this.getComic().getTitle()); + stringBuilder.append(" #"); + stringBuilder.append(this.getIssueNumber()); + if (this.title !=null && !this.title.isEmpty()) { + stringBuilder.append(": "); + stringBuilder.append(this.title); + } + return stringBuilder.toString(); + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + result.append("Issue{"); + result.append("comic="); + result.append(comic); + result.append(", volume="); + result.append(volume); + result.append(", storyArc="); + result.append(storyArc); + result.append(", issueNumber='"); + result.append(issueNumber); + result.append(", title='"); + result.append(title); + result.append(", publishedOn="); + result.append(publishedOn); + result.append(", isRead="); + result.append(isRead); + result.append(", inStock="); + result.append(inStock); + result.append("}"); + return result.toString(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/IssueWork.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/IssueWork.java new file mode 100644 index 0000000..1cec635 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/IssueWork.java @@ -0,0 +1,48 @@ +package de.thpeetz.kontor.data.comics; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +@Table(indexes = {@Index(columnList = "issue_id, artist_id, workType_id") }, + uniqueConstraints = @UniqueConstraint(columnNames = {"issue_id", "artist_id", "workType_id" }) +) +public class IssueWork extends AbstractEntity { + + @ManyToOne + @JoinColumn(name = "issue_id") + @NotNull + private Issue issue; + + @ManyToOne + @JoinColumn(name = "artist_id") + @NotNull + private Artist artist; + + @ManyToOne + @JoinColumn(name = "workType_id") + @NotNull + private Worktype workType; + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("IssueWork{"); + sb.append("issue=").append(issue); + sb.append(", artist=").append(artist); + sb.append(", workType=").append(workType); + sb.append('}'); + return sb.toString(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Publisher.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Publisher.java new file mode 100644 index 0000000..1a21731 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Publisher.java @@ -0,0 +1,64 @@ +package de.thpeetz.kontor.data.comics; + +import java.util.LinkedList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.Column; +import jakarta.persistence.OneToMany; +import jakarta.persistence.ManyToOne; +import jakarta.validation.constraints.*; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +public class Publisher extends AbstractEntity { + + @NotEmpty + @Column(unique = true) + private String name; + + private String weblink; + + @JsonBackReference + @ManyToOne + @JoinColumn(name = "parent_publisher_id") + @Nullable + @JsonIgnoreProperties({ "comics" }) + private Publisher parentCompany; + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "parentCompany", cascade = CascadeType.ALL, orphanRemoval = true) + @Nullable + private List imprints = new LinkedList<>(); + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "publisher", cascade = CascadeType.ALL, orphanRemoval = true) + @Nullable + private List comics = new LinkedList<>(); + + public String getParentCompanyName() { + if (parentCompany != null) { + return parentCompany.name; + } + return null; + } + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("Publisher{"); + sb.append("name='").append(name).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/StoryArc.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/StoryArc.java new file mode 100644 index 0000000..565a267 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/StoryArc.java @@ -0,0 +1,47 @@ +package de.thpeetz.kontor.data.comics; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToMany; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.*; + +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper = false) +@Entity +public class StoryArc extends AbstractEntity { + + @NotEmpty + private String name; + + @ManyToOne + @JoinColumn(name = "comic_id") + @NotNull + @JsonIgnoreProperties({ "storyArcs" }) + private Comic comic; + + @ManyToOne + @JoinColumn(name = "volume_id") + @JsonIgnoreProperties({ "storyArcs" }) + @Nullable + private Volume volume; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "storyArc", cascade = CascadeType.REMOVE, orphanRemoval = true) + @Nullable + private List issues = new LinkedList<>(); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/TradePaperback.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/TradePaperback.java new file mode 100644 index 0000000..14f3e67 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/TradePaperback.java @@ -0,0 +1,32 @@ +package de.thpeetz.kontor.data.comics; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper = false) +@Entity +public class TradePaperback extends AbstractEntity { + + @NotEmpty + private String name; + + @ManyToOne + @JoinColumn(name = "comic_id") + @NotNull + private Comic comic; + + private Integer issueStart; + + private Integer issueEnd; +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Volume.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Volume.java new file mode 100644 index 0000000..fae65aa --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Volume.java @@ -0,0 +1,55 @@ +package de.thpeetz.kontor.data.comics; + +import java.util.LinkedList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.*; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +public class Volume extends AbstractEntity { + + @NotEmpty + private String name; + + @ManyToOne + @JoinColumn(name = "comic_id") + @NotNull + @JsonIgnoreProperties({ "volumes" }) + private Comic comic; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "volume", cascade = CascadeType.REMOVE, orphanRemoval = true) + @Nullable + private List storyArcs = new LinkedList<>(); + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "volume", cascade = CascadeType.REMOVE, orphanRemoval = true) + @Nullable + private List issues = new LinkedList<>(); + + @Override + public String toString() { + StringBuilder result = new StringBuilder("Volume{"); + result.append("name="); + result.append(name); + result.append("comic=Comic{title="); + result.append(comic.getTitle()); + result.append("}}"); + return result.toString(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Worktype.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Worktype.java new file mode 100644 index 0000000..56e3356 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/comics/Worktype.java @@ -0,0 +1,47 @@ +package de.thpeetz.kontor.data.comics; + +import java.util.LinkedList; +import java.util.List; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import io.micrometer.common.lang.Nullable; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.OneToMany; +import jakarta.validation.constraints.NotEmpty; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +/** + * Represents a work type in the application. + * This class extends the AbstractEntity class. + */ +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +public class Worktype extends AbstractEntity { + + @NotEmpty + @Column(unique = true) + private String name; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "workType", cascade = CascadeType.REFRESH, orphanRemoval = true) + @Nullable + List comicWorks = new LinkedList<>(); + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "workType", cascade = CascadeType.REFRESH, orphanRemoval = true) + @Nullable + List issueWorks = new LinkedList<>(); + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("Worktype{"); + sb.append("name='").append(name).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/common/AbstractEntity.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/common/AbstractEntity.java new file mode 100644 index 0000000..2706102 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/common/AbstractEntity.java @@ -0,0 +1,51 @@ +package de.thpeetz.kontor.data.common; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import jakarta.persistence.EntityListeners; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.MappedSuperclass; +import jakarta.persistence.Version; + +import java.util.Date; + +@Slf4j +@Getter +@Setter +@EqualsAndHashCode +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +public abstract class AbstractEntity { + + @Id + @GeneratedValue(strategy = GenerationType.UUID) + private String id; + + @Version + private int version; + + @CreatedDate + private Date createdDate; + + @LastModifiedDate + private Date lastModifiedDate; + + public void updateVersion(String value) { + if (value == null) { + log.info("value not given"); + return; + } + if (version != Integer.valueOf(value).intValue()) { + log.info("update version"); + version = Integer.valueOf(value).intValue(); + } + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/common/AbstractLinkEntity.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/common/AbstractLinkEntity.java new file mode 100644 index 0000000..e54eb59 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/common/AbstractLinkEntity.java @@ -0,0 +1,55 @@ +package de.thpeetz.kontor.data.common; + +import jakarta.annotation.Nullable; +import jakarta.persistence.*; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.util.Date; + +@Slf4j +@Getter +@Setter +@EqualsAndHashCode +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +public abstract class AbstractLinkEntity { + + @Id + @GeneratedValue(strategy = GenerationType.UUID) + private String id; + + @Version + private int version; + + @CreatedDate + private Date createdDate; + + @LastModifiedDate + private Date lastModifiedDate; + + @Nullable + private String url; + + private boolean review; + + private boolean shouldDownload; + + @Nullable + private String title; + + @Nullable + private String cloudLink; + + @Nullable + private String fileName; + + @Nullable + private String path; + +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/mailclient/Mail.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/mailclient/Mail.java new file mode 100644 index 0000000..6da591f --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/mailclient/Mail.java @@ -0,0 +1,21 @@ +package de.thpeetz.kontor.data.mailclient; + +import jakarta.persistence.Entity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +import de.thpeetz.kontor.data.common.AbstractEntity; + +@Data +@EqualsAndHashCode(callSuper=false) +@Entity +public class Mail extends AbstractEntity { + + private String folder; + private String subject; + private String body; + private Date sentDate; + private Date receivedDate; +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/mailclient/MailAccount.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/mailclient/MailAccount.java new file mode 100644 index 0000000..82ef1a5 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/mailclient/MailAccount.java @@ -0,0 +1,29 @@ +package de.thpeetz.kontor.data.mailclient; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.persistence.Entity; +import jakarta.validation.constraints.NotEmpty; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Getter +@Setter +@Entity +public class MailAccount extends AbstractEntity { + + @NotEmpty + private String host; + + private Integer port; + + @NotEmpty + private String protocol; + + private String userName; + + private String password; + + private Boolean startTls; +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaActor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaActor.java new file mode 100644 index 0000000..afad2e3 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaActor.java @@ -0,0 +1,33 @@ +package de.thpeetz.kontor.data.media; + +import jakarta.annotation.Nullable; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotEmpty; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import java.util.LinkedList; +import java.util.List; + +import de.thpeetz.kontor.data.common.AbstractEntity; + +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Slf4j +@Entity +public class MediaActor extends AbstractEntity { + + @NotEmpty + private String name; + + @Nullable + @Column(unique = true) + private String url; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "media_actor", cascade = CascadeType.REFRESH, orphanRemoval = true) + @Nullable + List mediaActorFiles = new LinkedList<>(); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaActorFile.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaActorFile.java new file mode 100644 index 0000000..de187e6 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaActorFile.java @@ -0,0 +1,32 @@ +package de.thpeetz.kontor.data.media; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +@Table(indexes = {@Index(columnList = "media_file_id, media_actor_id") }, + uniqueConstraints = @UniqueConstraint(columnNames = {"media_file_id", "media_actor_id" }) +) +public class MediaActorFile extends AbstractEntity { + + @ManyToOne + @JoinColumn(name = "media_file_id") + @NotNull + private MediaFile media_file; + + @ManyToOne + @JoinColumn(name = "media_actor_id") + @NotNull + private MediaActor media_actor; + + public String getTitle() { + return media_file.getTitle(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaArticle.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaArticle.java new file mode 100644 index 0000000..7538393 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaArticle.java @@ -0,0 +1,28 @@ +package de.thpeetz.kontor.data.media; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotEmpty; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Getter +@Setter +@Entity +@Table(indexes = @Index(columnList = "url"), uniqueConstraints = @UniqueConstraint(columnNames = {"url"})) +public class MediaArticle extends AbstractEntity { + + @NotEmpty + private String url; + + private boolean review; + + @Nullable + private String title; +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaFile.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaFile.java new file mode 100644 index 0000000..03f771e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaFile.java @@ -0,0 +1,45 @@ +package de.thpeetz.kontor.data.media; + +import jakarta.annotation.Nullable; +import jakarta.persistence.*; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import java.util.LinkedList; +import java.util.List; + +import de.thpeetz.kontor.data.common.AbstractEntity; + +@Slf4j +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +public class MediaFile extends AbstractEntity { + + @Nullable + private String url; + + private boolean review; + + private boolean shouldDownload; + + @Nullable + @Column(length = 300) + private String title; + + @Nullable + private String cloudLink; + + @Nullable + private String fileName; + + @Nullable + private String path; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "media_file", cascade = CascadeType.REFRESH, orphanRemoval = true) + @Nullable + List mediaActorFiles = new LinkedList<>(); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaLofi.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaLofi.java new file mode 100644 index 0000000..387d6c1 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaLofi.java @@ -0,0 +1,32 @@ +package de.thpeetz.kontor.data.media; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "url" }) }) +public class MediaLofi extends AbstractEntity { + + private String url; + + private boolean review; + + private boolean shouldDownload; + + @Nullable + private String title; + + @Nullable + private String fileName; +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaVideo.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaVideo.java new file mode 100644 index 0000000..987c5a9 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/media/MediaVideo.java @@ -0,0 +1,40 @@ +package de.thpeetz.kontor.data.media; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "url" }) }) +public class MediaVideo extends AbstractEntity { + + @Nullable + private String url; + + private boolean review; + + private boolean shouldDownload; + + @Nullable + private String title; + + @Nullable + private String cloudLink; + + @Nullable + private String fileName; + + @Nullable + private String path; + +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/services/DataManagementService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/services/DataManagementService.java deleted file mode 100644 index e9df180..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/data/services/DataManagementService.java +++ /dev/null @@ -1,33 +0,0 @@ -package de.thpeetz.kontor.data.services; - -import de.thpeetz.kontor.tysc.services.SportService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; - -@Slf4j -@Service -public class DataManagementService { - - @Autowired - SportService sportService; - - public DataManagementService() { - - } - - public String getEntry(String nodeName, Map fields) { - AtomicReference status = new AtomicReference<>("unknown"); - switch (nodeName) { - case "sport": - status.set(sportService.importData(fields)); - default: - log.debug("import for {} not implemented", nodeName); - break; - } - return status.get(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Card.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Card.java new file mode 100644 index 0000000..48e80d8 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Card.java @@ -0,0 +1,62 @@ +package de.thpeetz.kontor.data.tysc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper=false) +@Entity +@Table(indexes = {@Index(columnList = "cardNumber, year")}, + uniqueConstraints = {@UniqueConstraint(columnNames = { "cardNumber", "year", "vendor_id", "cardSet_id" })} +) +public class Card extends AbstractEntity { + + private int cardNumber; + + private int year; + + @ManyToOne + @JoinColumn(name = "vendor_id") + @NotNull + @JsonIgnoreProperties({ "cards" }) + private Vendor vendor; + + @ManyToOne + @JoinColumn(name = "cardSet_id") + @NotNull + @JsonIgnoreProperties({ "cards" }) + private CardSet cardSet; + + @ManyToOne + @JoinColumn(name = "rooster_id") + @NotNull + @JsonIgnoreProperties({ "cards" }) + private Rooster rooster; + + public String getVendorName() { + return this.vendor.getName(); + } + + public String getCardSetName() { + return this.cardSet.getName(); + } + + public String getPlayerName() { + return this.rooster.getPlayer().getFullName(); + } +} + diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/CardSet.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/CardSet.java new file mode 100644 index 0000000..48bc5db --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/CardSet.java @@ -0,0 +1,45 @@ +package de.thpeetz.kontor.data.tysc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper=false) +@Entity +@Table(indexes = {@Index(columnList = "name, vendor_id")}, + uniqueConstraints = {@UniqueConstraint(columnNames = { "name", "vendor_id" })} +) +public class CardSet extends AbstractEntity { + + @NotEmpty + private String name; + + @ManyToOne() + @JoinColumn(name = "vendor_id") + @NotNull + @JsonIgnoreProperties({ "cardSets" }) + private Vendor vendor; + + private boolean parallelSet = false; + + private boolean insertSet = false; + + public String getVendorName() { + return vendor.getName(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/FieldPosition.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/FieldPosition.java new file mode 100644 index 0000000..851d933 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/FieldPosition.java @@ -0,0 +1,52 @@ +package de.thpeetz.kontor.data.tysc; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Index; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper=false) +@Entity +@Table(indexes = {@Index(columnList = "name, sport_id")}, + uniqueConstraints = { + @UniqueConstraint(columnNames = { "name", "sport_id" }), + @UniqueConstraint(columnNames = { "shortName", "sport_id" }) + } +) +public class FieldPosition extends AbstractEntity { + + @NotEmpty + private String name; + + @NotEmpty + private String shortName; + + @ManyToOne + @JoinColumn(name = "sport_id") + @NotNull + @JsonIgnoreProperties({ "positions" }) + private Sport sport; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "position") + @Nullable + private List roosters; +} \ No newline at end of file diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Player.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Player.java new file mode 100644 index 0000000..b7210b9 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Player.java @@ -0,0 +1,49 @@ +package de.thpeetz.kontor.data.tysc; + +import java.util.List; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Index; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper=false) +@Entity +@Table(indexes = { + @Index(columnList = "firstName, lastName"), + @Index(columnList = "lastName, firstName") +}, uniqueConstraints = { + @UniqueConstraint(columnNames = { "firstName", "lastName" }) +}) +public class Player extends AbstractEntity { + + @NotNull + private String firstName; + + @NotNull + private String lastName; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "player") + @Nullable + private List roosters; + + public String getFullName() { + StringBuilder fullName = new StringBuilder(); + fullName.append(this.lastName); + fullName.append(", "); + fullName.append(this.firstName); + return fullName.toString(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Rooster.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Rooster.java new file mode 100644 index 0000000..210aa13 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Rooster.java @@ -0,0 +1,49 @@ +package de.thpeetz.kontor.data.tysc; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.Index; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +@Table(indexes = { @Index(columnList = "team_id, player_id, position_id") }, uniqueConstraints = { + @UniqueConstraint(name = "uniqueRooster", columnNames = { "year", "team_id", "player_id", "position_id" }) }) +public class Rooster extends AbstractEntity { + + private int year; + + @ManyToOne + @JoinColumn(name = "team_id") + @NotNull + private Team team; + + @ManyToOne + @JoinColumn(name = "player_id") + @NotNull + private Player player; + + @ManyToOne + @JoinColumn(name = "position_id") + @NotNull + private FieldPosition position; + + @Override + public String toString() { + return "Rooster{" + + "year=" + year + + ", team=" + team.getName() + + ", player=" + player.getFullName() + + ", position=" + position.getName() + + '}'; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Sport.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Sport.java new file mode 100644 index 0000000..bdceaf4 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Sport.java @@ -0,0 +1,53 @@ +package de.thpeetz.kontor.data.tysc; + +import java.util.LinkedList; +import java.util.List; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Index; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotEmpty; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper=false) +@Entity +@Table(indexes = {@Index(columnList = "name")}, + uniqueConstraints = {@UniqueConstraint(columnNames = { "name" })} +) +public class Sport extends AbstractEntity { + + @NotEmpty + @Column(unique = true) + private String name; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "sport") + @Nullable + private List teams = new LinkedList<>(); + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "sport") + @Nullable + private List positions = new LinkedList<>(); + + public String updateName(String value) { + if (!this.getName().equals(value)) { + this.setName(value); + log.info("update name"); + return "updated " + this.getId() + " with " + value; + } + return "no changes for " + this.getId(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Team.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Team.java new file mode 100644 index 0000000..b7c0708 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Team.java @@ -0,0 +1,49 @@ +package de.thpeetz.kontor.data.tysc; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Index; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@EqualsAndHashCode(callSuper=false) +@Entity +@Table(indexes = {@Index(columnList = "name")}, + uniqueConstraints = {@UniqueConstraint(columnNames = { "name" })} +) +public class Team extends AbstractEntity { + + @NotEmpty + private String name; + + @NotEmpty + private String shortName; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "team") + @Nullable + private List roosters; + + @ManyToOne + @JoinColumn(name = "sport_id") + @NotNull + @JsonIgnoreProperties({ "teams" }) + private Sport sport; +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Vendor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Vendor.java new file mode 100644 index 0000000..c78a577 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/data/tysc/Vendor.java @@ -0,0 +1,39 @@ +package de.thpeetz.kontor.data.tysc; + +import java.util.List; + +import de.thpeetz.kontor.data.common.AbstractEntity; +import jakarta.annotation.Nullable; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Index; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import jakarta.validation.constraints.NotEmpty; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +/** + * Represents a vendor entity. + */ +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@Entity +@Table(indexes = { @Index(columnList = "name") }, uniqueConstraints = { @UniqueConstraint(columnNames = "name") }) +public class Vendor extends AbstractEntity { + + @NotEmpty + private String name; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "vendor") + @Nullable + private List cardSets; + + @Override + public String toString() { + return "Vendor{id=" + this.getId() + ", name=" + name + '}'; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/views/DataManagementView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/views/DataManagementView.java deleted file mode 100644 index 43e0675..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/data/views/DataManagementView.java +++ /dev/null @@ -1,49 +0,0 @@ -package de.thpeetz.kontor.data.views; - -import com.vaadin.flow.component.checkbox.Checkbox; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.data.services.DataManagementService; -import jakarta.annotation.security.PermitAll; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Scope; - -import java.io.File; - -@Slf4j -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = "common/import", layout = MainLayout.class) -@PageTitle("Import Data | Kontor") -public class DataManagementView extends VerticalLayout { - - DataManagementService service; - - public DataManagementView(DataManagementService service) { - this.service = service; - File uploadFolder = getUploadFolder(); - UploadArea uploadArea = new UploadArea(uploadFolder); - Checkbox pruneTables = new Checkbox("Prune Table"); - ImportArea importArea = new ImportArea(uploadFolder, pruneTables, service); - - uploadArea.getUploadField().addSucceededListener(e -> { - uploadArea.hideErrorField(); - importArea.processFiles(); - uploadArea.getUploadField().clearFileList(); - }); - - add(uploadArea, pruneTables, importArea); - } - - private File getUploadFolder() { - File folder = new File("uploaded-files"); - if (!folder.exists()) { - folder.mkdirs(); - } - return folder; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/views/ImportArea.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/views/ImportArea.java deleted file mode 100644 index 831f6a3..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/data/views/ImportArea.java +++ /dev/null @@ -1,111 +0,0 @@ -package de.thpeetz.kontor.data.views; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeType; -import com.vaadin.flow.component.checkbox.Checkbox; -import com.vaadin.flow.component.html.H4; -import com.vaadin.flow.component.html.Paragraph; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import de.thpeetz.kontor.data.services.DataManagementService; -import lombok.extern.slf4j.Slf4j; -import org.json.simple.parser.ParseException; - -import java.io.*; -import java.util.*; - -@Slf4j -public class ImportArea extends VerticalLayout { - - protected File uploadFolder; - DataManagementService service; - boolean pruneTables = false; - - public ImportArea(File uploadFolder, Checkbox pruneTablesCheckbox, DataManagementService service) { - this.uploadFolder = uploadFolder; - this.service = service; - this.pruneTables = pruneTablesCheckbox.isEnabled(); - setMargin(true); - } - - public void processFiles() { - removeAll(); - if (pruneTables) { - add(new Paragraph("prune all tables")); - } - add(new H4("Process file")); - - for (File file: uploadFolder.listFiles()) { - add(new Paragraph("reading " + file.getName())); - try { - processFile(file); - } catch (ParseException e) { - throw new RuntimeException(e); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - private void processFile(File file) throws FileNotFoundException, IOException, ParseException { - ObjectMapper objectMapper = new ObjectMapper(); - JsonNode node = objectMapper.readTree(file); - log.info("parsing: {}, {}", node.getNodeType(), node.size()); - Iterator fieldNamesIterator = node.fieldNames(); - while (fieldNamesIterator.hasNext()) { - String fieldName = fieldNamesIterator.next(); - parseRoot(node, fieldName); - } - } - - private void parseRoot(JsonNode parentNode, String field) { - JsonNode node = parentNode.get(field); - String nodeType = String.valueOf(node.getNodeType()); - if (nodeType.equals("ARRAY")) { - log.info(" {}: {}", field, node.size()); - Iterator elements = node.elements(); - while (elements.hasNext()) { - JsonNode subNode = elements.next(); - String status = parseNode(subNode, field); - add(new Paragraph(status)); - } - } else { - log.info("unknown type: {}", nodeType); - } - } - - private String parseNode(JsonNode node, String nodeName) { - Map fields = parseFields(node); - return service.getEntry(nodeName, fields); - } - - private Map parseFields(JsonNode node) { - Map fields = new HashMap<>(); - node.fieldNames().forEachRemaining(field -> { - - JsonNode value = node.get(field); - log.debug("type: {}", value.getNodeType()); - JsonNodeType nodeType = value.getNodeType(); - switch (nodeType) { - case NUMBER: - fields.put(field, String.valueOf(value.intValue())); - break; - case STRING: - String stringValue = value.textValue(); - if (stringValue.contains("\"")) { - log.debug("remove double quotes"); - String stripped = stringValue.substring(1, stringValue.length()-1); - fields.put(field, stripped); - } - fields.put(field, value.textValue()); - break; - default: - log.debug("no implementation for type {}", nodeType.name()); - } - }); - log.debug("fields: {}", fields); - return fields; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/data/views/UploadArea.java b/kontor-spring/src/main/java/de/thpeetz/kontor/data/views/UploadArea.java deleted file mode 100644 index f82efda..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/data/views/UploadArea.java +++ /dev/null @@ -1,58 +0,0 @@ -package de.thpeetz.kontor.data.views; - -import com.vaadin.flow.component.html.Span; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.upload.MultiFileReceiver; -import com.vaadin.flow.component.upload.Receiver; -import com.vaadin.flow.component.upload.Upload; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; - -@Slf4j -public class UploadArea extends VerticalLayout { - - @Getter - private final Upload uploadField; - private final Span errorField; - - public UploadArea(File uploadFolder) { - uploadField = new Upload(createFileReceiver(uploadFolder)); - uploadField.setMaxFiles(1); - uploadField.setMaxFileSize(2*1024*1024); - - errorField = new Span(); - errorField.setVisible(false); - errorField.getStyle().set("color", "red"); - - uploadField.addFailedListener(e -> showErrorMessage(e.getReason().getMessage())); - uploadField.addFileRejectedListener(e -> showErrorMessage(e.getErrorMessage())); - - add(uploadField, errorField); - } - - public void hideErrorField() { - errorField.setVisible(false); - } - - private Receiver createFileReceiver(File uploadFolder) { - return (MultiFileReceiver) (filename, mimetype) -> { - File file = new File(uploadFolder, filename); - try { - return new FileOutputStream(file); - } - catch (FileNotFoundException fnfe) { - log.info(fnfe.getStackTrace().toString()); - return null; - } - }; - } - - private void showErrorMessage(String message) { - errorField.setVisible(true); - errorField.setText(message); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/AddLinkFromQueue.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/AddLinkFromQueue.java deleted file mode 100644 index 15af258..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/AddLinkFromQueue.java +++ /dev/null @@ -1,28 +0,0 @@ -package de.thpeetz.kontor.integration.routes; - -import de.thpeetz.kontor.integration.services.AddLinkProcessor; -import de.thpeetz.kontor.media.services.MediaFileService; -import org.apache.camel.builder.RouteBuilder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class AddLinkFromQueue extends RouteBuilder { - - @Autowired - private final MediaFileService mediaFileService; - - @Autowired - public AddLinkFromQueue(MediaFileService mediaFileService) { - this.mediaFileService = mediaFileService; - } - - @Override - public void configure() throws Exception { - from("jms:queue:add_link_file") - .routeId("read-queue-add-link_file") - .log("${body}") - .process(new AddLinkProcessor(mediaFileService)) - .to("jms:queue:update_title"); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaLink.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaLink.java new file mode 100644 index 0000000..3eff640 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaLink.java @@ -0,0 +1,39 @@ +package de.thpeetz.kontor.integration.routes; + +import org.apache.camel.builder.RouteBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.integration.services.CheckLinkProcessor; +import de.thpeetz.kontor.services.MediaFileService; + +@Component +public class QueueMediaLink extends RouteBuilder { + + @Autowired + private final MediaFileService mediaFileService; + + @Autowired + public QueueMediaLink(MediaFileService mediaFileService) { + this.mediaFileService = mediaFileService; + } + + @Override + public void configure() throws Exception { + from("jms:queue:media.link") + .errorHandler(deadLetterChannel("jms:queue:DLQ") + .maximumRedeliveries(0) + .useOriginalMessage() + .onPrepareFailure(exchange -> { + exchange.getIn().setHeader("FailureReason", "processing failed"); + })) + .routeId("media.link") + .log("${body}") + .trace(true) + .process(new CheckLinkProcessor(mediaFileService)) + .choice() + .when(header(MediaConstants.FILE_ID).isNotNull()).to("jms:queue:media.link.duplicate") + .otherwise().to("jms:queue:media.link.add"); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaLinkAdd.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaLinkAdd.java new file mode 100644 index 0000000..da25839 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaLinkAdd.java @@ -0,0 +1,32 @@ +package de.thpeetz.kontor.integration.routes; + +import org.apache.camel.builder.RouteBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import de.thpeetz.kontor.integration.services.AddLinkProcessor; +import de.thpeetz.kontor.integration.services.UrlTitleProcessor; +import de.thpeetz.kontor.services.MediaFileService; + +@Component +public class QueueMediaLinkAdd extends RouteBuilder { + + @Autowired + private final MediaFileService mediaFileService; + + @Autowired + public QueueMediaLinkAdd(MediaFileService mediaFileService) { + this.mediaFileService = mediaFileService; + } + + @Override + public void configure() throws Exception { + from("jms:queue:media.link.add") + .routeId("media.link.add") + .log("${body}") + .trace(true) + .process(new UrlTitleProcessor()) + .process(new AddLinkProcessor(mediaFileService)) + .to("jms:queue:media.link.add.processed"); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaLoFi.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaLoFi.java new file mode 100644 index 0000000..f719f3e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaLoFi.java @@ -0,0 +1,40 @@ +package de.thpeetz.kontor.integration.routes; + +import org.apache.camel.builder.RouteBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.integration.services.CheckLoFiProcessor; +import de.thpeetz.kontor.services.MediaLofiService; + +@Component +public class QueueMediaLoFi extends RouteBuilder { + + @Autowired + private final MediaLofiService mediaLofiService; + + @Autowired + public QueueMediaLoFi(MediaLofiService mediaLofiService) { + this.mediaLofiService = mediaLofiService; + } + + @Override + public void configure() throws Exception { + from("jms:queue:media.lofi") + .errorHandler(deadLetterChannel("jms:queue:DLQ") + .maximumRedeliveries(0) + .useOriginalMessage() + .onPrepareFailure(exchange -> { + exchange.getIn().setHeader("FailureReason", "processing failed"); + })) + .routeId("media.lofi") + .log("${body}") + .trace(true) + .process(new CheckLoFiProcessor(mediaLofiService)) + .to("jms:queue:media.lofi.processed") + .choice() + .when(header(MediaConstants.LOFI_ID).isNotNull()).to("jms:queue:media.lofi.duplicate") + .otherwise().to("jms:queue:media.lofi.add"); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaLoFiAdd.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaLoFiAdd.java new file mode 100644 index 0000000..8687ae9 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaLoFiAdd.java @@ -0,0 +1,31 @@ +package de.thpeetz.kontor.integration.routes; + +import org.apache.camel.builder.RouteBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import de.thpeetz.kontor.integration.services.AddLofiProcessor; +import de.thpeetz.kontor.integration.services.UrlTitleProcessor; +import de.thpeetz.kontor.services.MediaLofiService; + +@Component +public class QueueMediaLoFiAdd extends RouteBuilder { + + @Autowired + private final MediaLofiService mediaLofiService; + + @Autowired + public QueueMediaLoFiAdd(MediaLofiService mediaLofiService) { + this.mediaLofiService = mediaLofiService; + } + + @Override + public void configure() throws Exception { + from("jms:queue:media.lofi.add") + .routeId("media.lofi.add") + .log("${body}") + .process(new UrlTitleProcessor()) + .process(new AddLofiProcessor(mediaLofiService)) + .to("jms:queue:media.lofi.add.processed"); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaVideo.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaVideo.java new file mode 100644 index 0000000..6c7b0cf --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaVideo.java @@ -0,0 +1,39 @@ +package de.thpeetz.kontor.integration.routes; + +import org.apache.camel.builder.RouteBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.integration.services.CheckVideoProcessor; +import de.thpeetz.kontor.services.MediaVideoService; + +@Component +public class QueueMediaVideo extends RouteBuilder { + + @Autowired + private final MediaVideoService mediaVideoService; + + @Autowired + public QueueMediaVideo(MediaVideoService mediaVideoService) { + this.mediaVideoService = mediaVideoService; + } + + @Override + public void configure() throws Exception { + from("jms:queue:media.video") + .errorHandler(deadLetterChannel("jms:queue:DLQ") + .maximumRedeliveries(0) + .useOriginalMessage() + .onPrepareFailure(exchange -> { + exchange.getIn().setHeader("FailureReason", "processing failed"); + })) + .routeId("media.video") + .log("${body}") + .trace(true) + .process(new CheckVideoProcessor(mediaVideoService)) + .choice() + .when(header(MediaConstants.VIDEO_ID).isNotNull()).to("jms:queue:media.video.duplicate") + .otherwise().to("jms:queue:media.video.add"); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaVideoAdd.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaVideoAdd.java new file mode 100644 index 0000000..d0e1393 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/QueueMediaVideoAdd.java @@ -0,0 +1,33 @@ +package de.thpeetz.kontor.integration.routes; + +import org.apache.camel.builder.RouteBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import de.thpeetz.kontor.integration.services.AddVideoProcessor; +import de.thpeetz.kontor.integration.services.UrlTitleProcessor; +import de.thpeetz.kontor.services.MediaVideoService; + +@Component +public class QueueMediaVideoAdd extends RouteBuilder { + + @SuppressWarnings("unused") + @Autowired + private final MediaVideoService mediaVideoService; + + @Autowired + public QueueMediaVideoAdd(MediaVideoService mediaVideoService) { + this.mediaVideoService = mediaVideoService; + } + + @Override + public void configure() throws Exception { + from("jms:queue:media.video.add") + .routeId("media.video.add") + .log("${body}") + .trace(true) + .process(new UrlTitleProcessor()) + .process(new AddVideoProcessor(mediaVideoService)) + .to("jms:queue:media.video.add.processed"); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/ReadQueueRoute.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/ReadQueueRoute.java deleted file mode 100644 index 115fef1..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/routes/ReadQueueRoute.java +++ /dev/null @@ -1,16 +0,0 @@ -package de.thpeetz.kontor.integration.routes; - -import org.apache.camel.builder.RouteBuilder; -import org.springframework.stereotype.Component; - -@Component -public class ReadQueueRoute extends RouteBuilder { - - @Override - public void configure() throws Exception { - from("jms:queue:KontorMediaFile") - .routeId("add-link-from-queue") - .trace(true) - .log(">>> ${body}"); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddLinkProcessor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddLinkProcessor.java index dde2673..83dc23a 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddLinkProcessor.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddLinkProcessor.java @@ -1,16 +1,14 @@ package de.thpeetz.kontor.integration.services; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import de.thpeetz.kontor.media.data.MediaFile; -import de.thpeetz.kontor.media.services.MediaFileService; +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.data.media.MediaFile; +import de.thpeetz.kontor.services.MediaFileService; import lombok.extern.slf4j.Slf4j; import org.apache.camel.Exchange; import org.apache.camel.Processor; -import org.springframework.beans.factory.annotation.Autowired; - -import java.util.HashMap; -import java.util.Map; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; @Slf4j public class AddLinkProcessor implements Processor { @@ -23,23 +21,33 @@ public class AddLinkProcessor implements Processor { @Override public void process(Exchange exchange) throws Exception { - ObjectMapper objectMapper = new ObjectMapper(); - HashMap myMap = objectMapper.readValue(exchange.getIn().getBody().toString(), new TypeReference>() {}); - String url = myMap.get("url"); - log.info("found url: {}", url); - MediaFile mediaFile = mediaFileService.findAllMediaFilesByUrl(url); - if (mediaFile == null) { - log.info("URL not found, create MediaFile"); - mediaFile = new MediaFile(); + String messageBody = exchange.getIn().getBody(String.class); + log.info("MediaFile URL to add: {}", messageBody); + String title = exchange.getIn().getHeader(MediaConstants.LINKTITLE).toString(); + + JSONParser parser = new JSONParser(); + try { + JSONObject jsonObject = (JSONObject) parser.parse(messageBody); + String url = (String) jsonObject.get(MediaConstants.URL); + MediaFile mediaFile = new MediaFile(); mediaFile.setUrl(url); + mediaFile.setPath(""); + mediaFile.setCloudLink(""); + mediaFile.setFileName(""); + mediaFile.setTitle(title); mediaFile.setReview(true); mediaFile.setShouldDownload(true); MediaFile mediaFileResult = mediaFileService.saveMediaFile(mediaFile); - log.info("created MediaFile with {}", mediaFileResult.getId()); - exchange.getMessage().getHeaders().put("mediafile_id", mediaFileResult.getId()); + if (mediaFileResult != null) { + log.info("MediaFile saved: {}", mediaFileResult.toString()); + exchange.getIn().setHeader(MediaConstants.FILE_ID, mediaFileResult.getId()); + } else { + log.info("MediaFile could not saved: {}", url); + exchange.getIn().setHeader(MediaConstants.FILE_ID, null); + } + } catch (ParseException pe) { + log.info("parse exception: {}", pe.toString()); + exchange.getIn().setHeader(MediaConstants.FILE_ID, null); } - log.info("found MediaFile: {}", mediaFile); - Map map = exchange.getMessage().getHeaders(); - log.info("Headers: {}", map); } } diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddLinkService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddLinkService.java deleted file mode 100644 index 93698e3..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddLinkService.java +++ /dev/null @@ -1,22 +0,0 @@ -package de.thpeetz.kontor.integration.services; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import java.util.HashMap; - -@Service -@Slf4j -public class AddLinkService { - - public void fromQueue(String messageBody) throws JsonProcessingException { - log.info("get body: {}", messageBody); - ObjectMapper objectMapper = new ObjectMapper(); - HashMap myMap = objectMapper.readValue(messageBody, new TypeReference>() {}); - String url = myMap.get("url"); - log.info("found url: {}", url); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddLofiProcessor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddLofiProcessor.java new file mode 100644 index 0000000..39e4d55 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddLofiProcessor.java @@ -0,0 +1,52 @@ +package de.thpeetz.kontor.integration.services; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.data.media.MediaLofi; +import de.thpeetz.kontor.services.MediaLofiService; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AddLofiProcessor implements Processor { + + private MediaLofiService mediaLofiService; + + public AddLofiProcessor(MediaLofiService medialLofiService) { + this.mediaLofiService = medialLofiService; + } + + @Override + public void process(Exchange exchange) throws Exception { + String messageBody = exchange.getIn().getBody(String.class); + log.info("LoFi URL to add: {}", messageBody); + String title = exchange.getIn().getHeader(MediaConstants.LINKTITLE).toString(); + + JSONParser parser = new JSONParser(); + try { + JSONObject jsonObject = (JSONObject) parser.parse(messageBody); + String url = (String) jsonObject.get(MediaConstants.URL); + MediaLofi mediaLofi = new MediaLofi(); + mediaLofi.setUrl(url); + mediaLofi.setTitle(title); + mediaLofi.setFileName(""); + mediaLofi.setReview(false); + mediaLofi.setShouldDownload(false); + mediaLofi = this.mediaLofiService.saveMediaLofi(mediaLofi); + if (mediaLofi != null) { + log.info("MediaLofi saved: {}", mediaLofi.toString()); + exchange.getIn().setHeader(MediaConstants.LOFI_ID, mediaLofi.getId()); + } else { + log.info("MediaLofi could not saved: {}", url); + exchange.getIn().setHeader(MediaConstants.LOFI_ID, null); + } + } catch (ParseException pe) { + log.info("parse exception: {}", pe.toString()); + exchange.getIn().setHeader(MediaConstants.LOFI_ID, null); + } + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddVideoProcessor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddVideoProcessor.java new file mode 100644 index 0000000..e8c8222 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/AddVideoProcessor.java @@ -0,0 +1,54 @@ +package de.thpeetz.kontor.integration.services; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.data.media.MediaVideo; +import de.thpeetz.kontor.services.MediaVideoService; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AddVideoProcessor implements Processor { + + private final MediaVideoService mediaVideoService; + + public AddVideoProcessor(MediaVideoService mediaVideoService) { + this.mediaVideoService = mediaVideoService; + } + + @Override + public void process(Exchange exchange) throws Exception { + String messageBody = exchange.getIn().getBody(String.class); + log.info("MediaVideo URL to add: {}", messageBody); + String title = exchange.getIn().getHeader(MediaConstants.LINKTITLE).toString(); + + JSONParser parser = new JSONParser(); + try { + JSONObject jsonObject = (JSONObject) parser.parse(messageBody); + String url = (String) jsonObject.get(MediaConstants.URL); + MediaVideo mediaVideo = new MediaVideo(); + mediaVideo.setUrl(url); + mediaVideo.setPath(""); + mediaVideo.setCloudLink(""); + mediaVideo.setFileName(""); + mediaVideo.setTitle(title); + mediaVideo.setReview(true); + mediaVideo.setShouldDownload(true); + MediaVideo mediaVideoResult = mediaVideoService.saveMediaVideo(mediaVideo); + if (mediaVideoResult != null) { + log.info("MediaVideo saved: {}", mediaVideoResult.toString()); + exchange.getIn().setHeader(MediaConstants.VIDEO_ID, mediaVideoResult.getId()); + } else { + log.info("MediaFile could not saved: {}", url); + exchange.getIn().setHeader(MediaConstants.VIDEO_ID, null); + } + } catch (ParseException pe) { + log.info("parse exception: {}", pe.toString()); + exchange.getIn().setHeader(MediaConstants.VIDEO_ID, null); + } + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/CheckLinkProcessor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/CheckLinkProcessor.java new file mode 100644 index 0000000..7d0c511 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/CheckLinkProcessor.java @@ -0,0 +1,45 @@ +package de.thpeetz.kontor.integration.services; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.data.media.MediaFile; +import de.thpeetz.kontor.services.MediaFileService; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CheckLinkProcessor implements Processor { + + private final MediaFileService mediaFileService; + + public CheckLinkProcessor(MediaFileService mediaFileService) { + this.mediaFileService = mediaFileService; + } + + @Override + public void process(Exchange exchange) throws Exception { + String messageBody = exchange.getIn().getBody(String.class); + log.info("message body: {}", messageBody); + + JSONParser parser = new JSONParser(); + try { + JSONObject jsonObject = (JSONObject) parser.parse(messageBody); + String url = (String) jsonObject.get(MediaConstants.URL); + MediaFile mediaFile = mediaFileService.findAllMediaFilesByUrl(url); + if (mediaFile != null) { + log.info("found url: {}", url); + exchange.getIn().setHeader(MediaConstants.FILE_ID, mediaFile.getId()); + } else { + log.info("url not found: {}", url); + exchange.getIn().setHeader(MediaConstants.FILE_ID, null); + } + } catch (ParseException pe) { + log.info("parse exception: {}", pe.toString()); + exchange.getIn().setHeader(MediaConstants.FILE_ID, null); + } + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/CheckLoFiProcessor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/CheckLoFiProcessor.java new file mode 100644 index 0000000..f52297b --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/CheckLoFiProcessor.java @@ -0,0 +1,45 @@ +package de.thpeetz.kontor.integration.services; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.data.media.MediaLofi; +import de.thpeetz.kontor.services.MediaLofiService; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CheckLoFiProcessor implements Processor { + + private final MediaLofiService medialLofiService; + + public CheckLoFiProcessor(MediaLofiService medialLofiService) { + this.medialLofiService = medialLofiService; + } + + @Override + public void process(Exchange exchange) throws Exception { + String messageBody = exchange.getIn().getBody(String.class); + log.info("message body: {}", messageBody); + + JSONParser parser = new JSONParser(); + try { + JSONObject jsonObject = (JSONObject) parser.parse(messageBody); + String url = (String) jsonObject.get(MediaConstants.URL); + MediaLofi mediaLofi = medialLofiService.findAllMediaLofiByUrl(url); + if (mediaLofi != null) { + log.info("found url: {}", url); + exchange.getIn().setHeader(MediaConstants.LOFI_ID, mediaLofi.getId()); + } else { + log.info("url not found: {}", url); + exchange.getIn().setHeader(MediaConstants.LOFI_ID, null); + } + } catch (ParseException pe) { + log.info("parse exception: {}", pe.toString()); + exchange.getIn().setHeader(MediaConstants.LOFI_ID, null); + } + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/CheckVideoProcessor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/CheckVideoProcessor.java new file mode 100644 index 0000000..ca67a7c --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/CheckVideoProcessor.java @@ -0,0 +1,38 @@ +package de.thpeetz.kontor.integration.services; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import de.thpeetz.kontor.services.MediaVideoService; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CheckVideoProcessor implements Processor { + + @SuppressWarnings("unused") + private final MediaVideoService mediaVideoService; + + public CheckVideoProcessor(MediaVideoService mediaVideoService) { + this.mediaVideoService = mediaVideoService; + } + + @Override + public void process(Exchange exchange) throws Exception { + String messageBody = exchange.getIn().getBody(String.class); + log.info("message body: {}", messageBody); + + JSONParser parser = new JSONParser(); + try { + JSONObject jsonObject = (JSONObject) parser.parse(messageBody); + String url = (String) jsonObject.get("url"); + log.info("found url: {}", url); + exchange.getIn().setHeader("linkId", null); + } catch (ParseException pe) { + log.info("parse exception: {}", pe.toString()); + exchange.getIn().setHeader("linkId", null); + } + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/UrlTitleProcessor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/UrlTitleProcessor.java new file mode 100644 index 0000000..5707a58 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/integration/services/UrlTitleProcessor.java @@ -0,0 +1,40 @@ +package de.thpeetz.kontor.integration.services; + +import java.io.IOException; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; + +import de.thpeetz.kontor.constants.MediaConstants; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class UrlTitleProcessor implements Processor { + + @Override + public void process(Exchange exchange) throws Exception { + String messageBody = exchange.getIn().getBody(String.class); + log.info("URL to check: {}", messageBody); + + JSONParser parser = new JSONParser(); + try { + JSONObject jsonObject = (JSONObject) parser.parse(messageBody); + String url = (String) jsonObject.get(MediaConstants.URL); + Document doc = Jsoup.connect(url).get(); + String title = doc.title(); + log.info("URL Title: {}", title); + exchange.getIn().setHeader(MediaConstants.LINKTITLE, title); + } catch (IOException io) { + log.info("IOException: {}", io.toString()); + exchange.getIn().setHeader(MediaConstants.LINKTITLE, ""); + } catch (ParseException pe) { + log.info("parse exception: {}", pe.toString()); + exchange.getIn().setHeader(MediaConstants.LINKTITLE, ""); + } + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/mailclient/data/Mail.java b/kontor-spring/src/main/java/de/thpeetz/kontor/mailclient/data/Mail.java deleted file mode 100644 index f3b80a8..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/mailclient/data/Mail.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.thpeetz.kontor.mailclient.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.Date; - -@Data -@EqualsAndHashCode(callSuper=false) -@Entity -public class Mail extends AbstractEntity { - - private String folder; - private String subject; - private String body; - private Date sentDate; - private Date receivedDate; -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/mailclient/data/MailAccount.java b/kontor-spring/src/main/java/de/thpeetz/kontor/mailclient/data/MailAccount.java deleted file mode 100644 index 840d8da..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/mailclient/data/MailAccount.java +++ /dev/null @@ -1,29 +0,0 @@ -package de.thpeetz.kontor.mailclient.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import jakarta.validation.constraints.NotEmpty; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Getter -@Setter -@Entity -public class MailAccount extends AbstractEntity { - - @NotEmpty - private String host; - - private Integer port; - - @NotEmpty - private String protocol; - - private String userName; - - private String password; - - private Boolean startTls; -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/mailclient/views/EmailView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/mailclient/views/EmailView.java deleted file mode 100644 index 4235dd1..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/mailclient/views/EmailView.java +++ /dev/null @@ -1,222 +0,0 @@ -package de.thpeetz.kontor.mailclient.views; - -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.util.List; -import java.util.Properties; - -import javax.mail.Address; -import javax.mail.Folder; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.NoSuchProviderException; -import javax.mail.Session; -import javax.mail.Store; -import javax.mail.internet.InternetAddress; - -import com.sun.mail.imap.IMAPFolder; -import com.vaadin.flow.component.Composite; -import com.vaadin.flow.component.accordion.Accordion; -import com.vaadin.flow.component.html.Paragraph; -import com.vaadin.flow.component.html.Span; -import com.vaadin.flow.component.menubar.MenuBar; -import com.vaadin.flow.component.messages.MessageList; -import com.vaadin.flow.component.messages.MessageListItem; -import com.vaadin.flow.component.orderedlayout.FlexComponent.Alignment; -import com.vaadin.flow.component.orderedlayout.FlexComponent.JustifyContentMode; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.sidenav.SideNav; -import com.vaadin.flow.component.sidenav.SideNavItem; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.router.RouteAlias; -import com.vaadin.flow.server.auth.AnonymousAllowed; -import com.vaadin.flow.theme.lumo.LumoUtility.Gap; - -import de.thpeetz.kontor.mailclient.data.MailAccount; -import de.thpeetz.kontor.admin.services.MailService; -import de.thpeetz.kontor.common.views.MainLayout; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@PageTitle("Email") -@AnonymousAllowed -@Route(value = "mail", layout = MainLayout.class) -@RouteAlias(value = "kontor/mail", layout = MainLayout.class) -public class EmailView extends Composite { - - MenuBar menuBar = new MenuBar(); - Accordion accordion = new Accordion(); - SideNav folderList = new SideNav(); - MailService mailService; - - public EmailView(MailService mailService) { - this.mailService = mailService; - configureView(); - updateFolderList(); - } - - private void updateFolderList() { - List accounts = mailService.findAllMailAccounts(); - MailAccount account = accounts.get(0); - - Properties properties = new Properties(); - properties.put(String.format("mail.%s.host", account.getProtocol()), account.getHost()); - properties.put(String.format("mail.%s.port", account.getProtocol()), account.getPort().toString()); - properties.put("mail.imap.starttls.enable", "true"); - - Session session = Session.getDefaultInstance(properties); - Store store; - try { - store = session.getStore(account.getProtocol()); - store.connect(account.getUserName(), account.getPassword()); - Folder rootFolder = store.getDefaultFolder(); - Folder[] folders = rootFolder.list(); - for (Folder value : folders) { - SideNavItem folder = addSubFolder(value); - folderList.addItem(folder); - } - log.info("{} folders found", folders.length); - Folder folder = store.getFolder("INBOX"); - IMAPFolder imapFolder = (IMAPFolder) folder; - imapFolder.open(Folder.READ_ONLY); - Message[] messages = imapFolder.getMessages(); - log.info("Folder {} opened", folder.getFullName()); - int messageCount = folder.getMessageCount(); - log.info("{} messages found", messages.length); - for (Message message : messages) { - log.info("Message {}: {}, {}, {}", message.getMessageNumber(), message.getSubject(), message.getReceivedDate(), message.getSentDate()); - //log.info("Message: {}", message.getAllRecipients()); - Address[] addresses; - printAddress(message.getRecipients(Message.RecipientType.TO)); - printAddress(message.getRecipients(Message.RecipientType.CC)); - printAddress(message.getRecipients(Message.RecipientType.BCC)); - } - store.close(); - log.info("Connection closed"); - } catch (NoSuchProviderException e) { - throw new RuntimeException(e); - } catch (MessagingException e) { - throw new RuntimeException(e); - } - } - - private void printAddress(Address[] addresses) { - if (addresses != null) { - for (Address address: addresses) { - log.info("Address {}: {}", address.getType(), address.toString()); - InternetAddress internetAddress = (InternetAddress)address; - log.info("InternetAddress {}: {}", internetAddress.getPersonal(), internetAddress.getAddress()); - } - } - } - - private SideNavItem addSubFolder(Folder mailFolder) throws MessagingException { - log.debug("addSubFolder: {}", mailFolder.getName()); - Span counter = new Span(String.valueOf(mailFolder.getMessageCount())); - counter.getElement().getThemeList().add("badge contrast pill"); - counter.getElement().setAttribute("aria-label", String.format("%d unread messages", mailFolder.getMessageCount())); - SideNavItem folder = new SideNavItem(mailFolder.getName()); - folder.setSuffixComponent(counter); - Folder[] folders = mailFolder.list(); - log.info("{} subfolders found", folders.length); - for (Folder value : folders) { - SideNavItem subFolder = addSubFolder(value); - folder.addItem(subFolder); - } - return folder; - } - - private void configureView() { - HorizontalLayout layoutMenubar = new HorizontalLayout(); - HorizontalLayout layoutRow2 = new HorizontalLayout(); - VerticalLayout layoutColumn2 = new VerticalLayout(); - VerticalLayout layoutColumn3 = new VerticalLayout(); - MessageList messageList = new MessageList(); - VerticalLayout layoutColumn4 = new VerticalLayout(); - Paragraph textMedium = new Paragraph(); - getContent().setWidth("100%"); - getContent().getStyle().set("flex-grow", "1"); - layoutMenubar.addClassName(Gap.MEDIUM); - layoutMenubar.setWidth("100%"); - layoutMenubar.setHeight("min-content"); - menuBar.setWidth("min-content"); - setMenuBarSampleData(menuBar); - layoutRow2.addClassName(Gap.MEDIUM); - layoutRow2.setWidth("100%"); - layoutRow2.getStyle().set("flex-grow", "1"); - layoutColumn2.getStyle().set("flex-grow", "1"); - accordion.setWidth("100%"); - setAccordionSampleData(accordion); - layoutColumn3.setHeightFull(); - layoutRow2.setFlexGrow(1.0, layoutColumn3); - layoutColumn3.setWidth("100%"); - layoutColumn3.getStyle().set("flex-grow", "1"); - layoutColumn3.setJustifyContentMode(JustifyContentMode.START); - layoutColumn3.setAlignItems(Alignment.START); - messageList.setWidth("100%"); - setMessageListSampleData(messageList); - layoutColumn4.setWidthFull(); - layoutColumn3.setFlexGrow(1.0, layoutColumn4); - layoutColumn4.setWidth("100%"); - layoutColumn4.getStyle().set("flex-grow", "1"); - textMedium.setText( - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); - textMedium.setWidth("100%"); - textMedium.getStyle().set("font-size", "var(--lumo-font-size-m)"); - getContent().add(layoutMenubar); - layoutMenubar.add(menuBar); - getContent().add(layoutRow2); - layoutRow2.add(layoutColumn2); - layoutColumn2.add(folderList); - layoutRow2.add(layoutColumn3); - layoutColumn3.add(messageList); - layoutColumn3.add(layoutColumn4); - layoutColumn4.add(textMedium); - } - - private void setMenuBarSampleData(MenuBar menuBar) { - menuBar.addItem("View"); - menuBar.addItem("Edit"); - menuBar.addItem("Share"); - menuBar.addItem("Move"); - } - - private void setAccordionSampleData(Accordion accordion) { - Span name = new Span("Sophia Williams"); - Span email = new Span("sophia.williams@company.com"); - Span phone = new Span("(501) 555-9128"); - VerticalLayout personalInformationLayout = new VerticalLayout(name, email, phone); - personalInformationLayout.setSpacing(false); - personalInformationLayout.setPadding(false); - accordion.add("Personal information", personalInformationLayout); - Span street = new Span("4027 Amber Lake Canyon"); - Span zipCode = new Span("72333-5884 Cozy Nook"); - Span city = new Span("Arkansas"); - VerticalLayout billingAddressLayout = new VerticalLayout(); - billingAddressLayout.setSpacing(false); - billingAddressLayout.setPadding(false); - billingAddressLayout.add(street, zipCode, city); - accordion.add("Billing address", billingAddressLayout); - Span cardBrand = new Span("Mastercard"); - Span cardNumber = new Span("1234 5678 9012 3456"); - Span expiryDate = new Span("Expires 06/21"); - VerticalLayout paymentLayout = new VerticalLayout(); - paymentLayout.setSpacing(false); - paymentLayout.setPadding(false); - paymentLayout.add(cardBrand, cardNumber, expiryDate); - accordion.add("Payment", paymentLayout); - } - - private void setMessageListSampleData(MessageList messageList) { - MessageListItem message1 = new MessageListItem("Nature does not hurry, yet everything gets accomplished.", - LocalDateTime.now().minusDays(1).toInstant(ZoneOffset.UTC), "Matt Mambo"); - message1.setUserColorIndex(1); - MessageListItem message2 = new MessageListItem( - "Using your talent, hobby or profession in a way that makes you contribute with something good to this world is truly the way to go.", - LocalDateTime.now().minusMinutes(55).toInstant(ZoneOffset.UTC), "Linsey Listy"); - message2.setUserColorIndex(2); - messageList.setItems(message1, message2); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/MediaConstants.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/MediaConstants.java deleted file mode 100644 index 76fc9bc..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/MediaConstants.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.thpeetz.kontor.media; - -import com.vaadin.flow.component.icon.VaadinIcon; -import com.vaadin.flow.component.sidenav.SideNavItem; -import de.thpeetz.kontor.media.views.MediaActorView; -import de.thpeetz.kontor.media.views.MediaArticleView; -import de.thpeetz.kontor.media.views.MediaFileView; -import de.thpeetz.kontor.media.views.MediaVideoView; - -import java.util.ArrayList; - -public class MediaConstants { - - public static final String MEDIA = "Media"; - public static final String MEDIAFILE_ROUTE = "media/mediafile"; - public static final String MEDIAVIDEO_ROUTE = "media/mediavideo"; - public static final String MEDIAARTICLE_ROUTE = "media/mediaarticle"; - public static final String MEDIA_ROLE = "ROLE_MEDIA"; - public static final String MEDIAACTOR_ROUTE = "media/mediaactor"; - public static final String MEDIAACTORFILE_ROUTE = "media/mediaactorfile"; - public static final String MEDIAACTORFILE = "Media Actor Files"; - private static final String MEDIAFILE = "Media Files"; - private static final String MEDIAVIDEO = "Media Videos"; - private static final String MEDIAARTICLE = "Media Article"; - private static final String MEDIAACTOR = "Media Actor"; - - public static SideNavItem getMediaNavigation(ArrayList roles) { - SideNavItem media = new SideNavItem(MEDIA, MEDIAFILE_ROUTE, VaadinIcon.VIMEO.create()); - media.addItem(new SideNavItem(MEDIAVIDEO, MediaVideoView.class)); - media.addItem(new SideNavItem(MEDIAARTICLE, MediaArticleView.class)); - if (roles.contains(MEDIA_ROLE)) { - media.addItem(new SideNavItem(MEDIAFILE, MediaFileView.class)); - media.addItem(new SideNavItem(MEDIAACTOR, MediaActorView.class)); - } - return media; - } - - private MediaConstants() { - // private constructor to hide the implicit public one - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/SetupModuleMedia.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/SetupModuleMedia.java deleted file mode 100644 index f6bb939..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/SetupModuleMedia.java +++ /dev/null @@ -1,29 +0,0 @@ -package de.thpeetz.kontor.media; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.stereotype.Component; - -import de.thpeetz.kontor.admin.services.AdminService; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Component -public class SetupModuleMedia implements ApplicationListener { - - boolean alreadySetup = false; - - @Autowired - private AdminService adminService; - - @Override - public void onApplicationEvent(ContextRefreshedEvent event) { - adminService.addPermission(MediaConstants.MEDIA_ROLE); - if (alreadySetup) { - log.info("SetupModuleMedia already executed, skipping"); - return; - } - log.info("Set up Media data"); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActor.java deleted file mode 100644 index 0d2e328..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActor.java +++ /dev/null @@ -1,32 +0,0 @@ -package de.thpeetz.kontor.media.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.*; -import jakarta.validation.constraints.NotEmpty; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; - -import java.util.LinkedList; -import java.util.List; - -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Slf4j -@Entity -public class MediaActor extends AbstractEntity { - - @NotEmpty - @Column(unique = true) - private String name; - - @Nullable - private String url; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "media_actor", cascade = CascadeType.REFRESH, orphanRemoval = true) - @Nullable - List mediaActorFiles = new LinkedList<>(); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActorFile.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActorFile.java deleted file mode 100644 index 0e24cd7..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActorFile.java +++ /dev/null @@ -1,34 +0,0 @@ -package de.thpeetz.kontor.media.data; - -import de.thpeetz.kontor.comics.data.Artist; -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.*; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Entity -@Table(indexes = {@Index(columnList = "media_file_id, media_actor_id") }, - uniqueConstraints = @UniqueConstraint(columnNames = {"media_file_id", "media_actor_id" }) -) -public class MediaActorFile extends AbstractEntity { - - @ManyToOne - @JoinColumn(name = "media_file_id") - @NotNull - private MediaFile media_file; - - @ManyToOne - @JoinColumn(name = "media_actor_id") - @NotNull - private MediaActor media_actor; - - public String getTitle() { - return media_file.getTitle(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaArticle.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaArticle.java deleted file mode 100644 index c664a3a..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaArticle.java +++ /dev/null @@ -1,29 +0,0 @@ -package de.thpeetz.kontor.media.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.Entity; -import jakarta.persistence.Index; -import jakarta.persistence.OneToOne; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotEmpty; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Getter -@Setter -@Entity -@Table(indexes = @Index(columnList = "url"), uniqueConstraints = @UniqueConstraint(columnNames = {"url"})) -public class MediaArticle extends AbstractEntity { - - @NotEmpty - private String url; - - private boolean review; - - @Nullable - private String title; -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaFile.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaFile.java deleted file mode 100644 index 2193690..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaFile.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.thpeetz.kontor.media.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.*; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; - -import java.util.LinkedList; -import java.util.List; - -@Slf4j -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Entity -public class MediaFile extends AbstractEntity { - - @Nullable - private String url; - - private boolean review; - - private boolean shouldDownload; - - @Nullable - private String title; - - @Nullable - private String cloudLink; - - @Nullable - private String fileName; - - @Nullable - private String path; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "media_file", cascade = CascadeType.REFRESH, orphanRemoval = true) - @Nullable - List mediaActorFiles = new LinkedList<>(); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaVideo.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaVideo.java deleted file mode 100644 index d093eb1..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaVideo.java +++ /dev/null @@ -1,40 +0,0 @@ -package de.thpeetz.kontor.media.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.Entity; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Entity -@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "url" }) }) -public class MediaVideo extends AbstractEntity { - - @Nullable - private String url; - - private boolean review; - - private boolean shouldDownload; - - @Nullable - private String title; - - @Nullable - private String cloudLink; - - @Nullable - private String fileName; - - @Nullable - private String path; - -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaActorFileRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaActorFileRepository.java deleted file mode 100644 index e680b32..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaActorFileRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.thpeetz.kontor.media.repository; - -import org.springframework.data.jpa.repository.JpaRepository; - -import de.thpeetz.kontor.media.data.MediaActorFile; - -public interface MediaActorFileRepository extends JpaRepository { -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaActorRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaActorRepository.java deleted file mode 100644 index 1cd5ff0..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaActorRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.thpeetz.kontor.media.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import de.thpeetz.kontor.media.data.MediaActor; - -import java.util.List; - -public interface MediaActorRepository extends JpaRepository { - @Query("select m from MediaActor m " + - "where lower(m.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - List findByNameIgnoreCase(String name); - - MediaActor findByName(String name); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaArticleRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaArticleRepository.java deleted file mode 100644 index 6486097..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaArticleRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.thpeetz.kontor.media.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import de.thpeetz.kontor.media.data.MediaArticle; - -import java.util.List; - -public interface MediaArticleRepository extends JpaRepository { - @Query("select m from MediaArticle m " + - "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%'))") - List search(@Param("searchTerm") String searchTerm); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaFileRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaFileRepository.java deleted file mode 100644 index ac8274d..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaFileRepository.java +++ /dev/null @@ -1,31 +0,0 @@ -package de.thpeetz.kontor.media.repository; - -import java.util.List; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import de.thpeetz.kontor.media.data.MediaFile; - -public interface MediaFileRepository extends JpaRepository { - @Query("select m from MediaFile m " + - "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%'))") - List search(@Param("searchTerm") String searchTerm); - - List findByShouldDownload(Boolean shouldDownload); - - List findByReview(Boolean review); - - List findByReviewAndShouldDownload(Boolean review, Boolean shouldDownload); - - MediaFile findByUrl(String url); - - @Query("select m from MediaFile m " + - "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%')) " + - "AND m.review=:review AND m.shouldDownload=:download") - List search( - @Param("searchTerm") String searchTerm, - @Param("review") boolean searchReview, - @Param("download") boolean searchDownload); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaVideoRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaVideoRepository.java deleted file mode 100644 index 25c72e8..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/repository/MediaVideoRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package de.thpeetz.kontor.media.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import de.thpeetz.kontor.media.data.MediaVideo; - -import java.util.List; - -public interface MediaVideoRepository extends JpaRepository { - - @Query("select m from MediaVideo m " + - "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%'))") - List search(@Param("searchTerm") String searchTerm); - -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaArticleService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaArticleService.java deleted file mode 100644 index 5f6b994..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaArticleService.java +++ /dev/null @@ -1,42 +0,0 @@ -package de.thpeetz.kontor.media.services; - -import de.thpeetz.kontor.media.data.MediaArticle; -import de.thpeetz.kontor.media.repository.MediaArticleRepository; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Slf4j -@Service -public class MediaArticleService { - - private final MediaArticleRepository mediaArticleRepository; - - public MediaArticleService(MediaArticleRepository mediaArticleRepository) { - this.mediaArticleRepository = mediaArticleRepository; - } - - public List findAllMediaArticles(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - log.info("Found {} entries", mediaArticleRepository.count()); - return mediaArticleRepository.findAll(); - } else { - List results = mediaArticleRepository.search(stringFilter); - log.info("Found {} entries", results.size()); - return results; - } - } - - public void saveMediaArticle(MediaArticle mediaArticle) { - if (mediaArticle == null) { - log.warn("MediaArticle is null. Are you sure you have connected your form to the application?"); - return; - } - mediaArticleRepository.save(mediaArticle); - } - - public void deleteMediaArticle(MediaArticle mediaArticle) { - mediaArticleRepository.delete(mediaArticle); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaFileService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaFileService.java deleted file mode 100644 index 4766da7..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaFileService.java +++ /dev/null @@ -1,138 +0,0 @@ -package de.thpeetz.kontor.media.services; - -import de.thpeetz.kontor.common.views.SearchFilter; -import de.thpeetz.kontor.media.data.MediaActor; -import de.thpeetz.kontor.media.data.MediaActorFile; -import de.thpeetz.kontor.media.data.MediaFile; -import de.thpeetz.kontor.media.repository.MediaActorFileRepository; -import de.thpeetz.kontor.media.repository.MediaActorRepository; -import de.thpeetz.kontor.media.repository.MediaFileRepository; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; - -import org.springframework.stereotype.Service; - - -@Slf4j -@Service -public class MediaFileService { - - private final MediaFileRepository mediaFileRepository; - private final MediaActorRepository mediaActorRepository; - private final MediaActorFileRepository mediaActorFileRepository; - - public MediaFileService(MediaFileRepository mediaFileRepository, MediaActorRepository mediaActorRepository, MediaActorFileRepository mediaActorFileRepository) { - this.mediaFileRepository = mediaFileRepository; - this.mediaActorRepository = mediaActorRepository; - this.mediaActorFileRepository = mediaActorFileRepository; - } - - public List findAllMediaFilesByString(String stringFilter) { - List results; - if (stringFilter == null || stringFilter.isEmpty()) { - results = mediaFileRepository.findAll(); - } else { - results = mediaFileRepository.search(stringFilter); - } - log.debug("Found " + results.size() + " entries"); - return results; - } - - public MediaFile findAllMediaFilesByUrl(String url) { - return mediaFileRepository.findByUrl(url); - } - - public List findAllMediaFiles(SearchFilter searchFilter) { - if (searchFilter == null) { - return mediaFileRepository.findAll(); - } else { - if (searchFilter.getSearchTerm() != null && searchFilter.getFilterOptions().isEmpty()) { - log.info("find MediaFiles by using searchTerm: {}", searchFilter.getSearchTerm()); - List results = mediaFileRepository.search(searchFilter.getSearchTerm()); - log.info("found {} entries", results.size()); - return results; - } - if (searchFilter.getFilterOptions().size() == 1) { - log.info("using searchFilter: {}", searchFilter); - String filter = searchFilter.getFilterOptions().get(0).getName(); - Boolean filterValue = searchFilter.getFilterOptions().get(0).getValue(); - if (filter == "Überprüfung") { - List results = mediaFileRepository.findByReview(filterValue); - log.info("found {} entries", results.size()); - return results; - } - if (filter == "Download") { - List results = mediaFileRepository.findByShouldDownload(filterValue); - log.info("found {} entries", results.size()); - return results; - } - } - if (searchFilter.getFilterOptions().size() == 2) { - log.info("using searchFilter: {}", searchFilter); - List results = mediaFileRepository.search(searchFilter.getSearchTerm(), searchFilter.getFilterOptions().get(0).getValue(), searchFilter.getFilterOptions().get(1).getValue()); - log.info("found {} entries", results.size()); - return results; - } - } - log.info("noch filter used"); - return mediaFileRepository.findAll(); - } - - public MediaFile saveMediaFile(MediaFile mediaFile) { - if (mediaFile == null) { - log.warn("MediaFile is null. Are you sure you have connected your form to the application?"); - return null; - } - return mediaFileRepository.save(mediaFile); - } - - public void deleteMediaFile(MediaFile mediaFile) { - mediaFileRepository.delete(mediaFile); - } - - public List findAllMediaActors(String stringFilter) { - List results; - if (stringFilter == null || stringFilter.isEmpty()) { - results = mediaActorRepository.findAll(); - } else { - results = mediaActorRepository.search(stringFilter); - } - log.debug("Found " + results.size() + " entries"); - return results; - } - - public void saveMediaActor(MediaActor mediaActor) { - if (mediaActor == null) { - log.warn("MediaActor is null. Are you sure you have connected your form to the application?"); - return; - } - mediaActorRepository.save(mediaActor); - } - - public void deleteMediaActor(MediaActor mediaActor) { - mediaActorRepository.delete(mediaActor); - } - - public List findAllMediaActorFiles() { - return mediaActorFileRepository.findAll(); - } - - public void saveMediaActorFile(MediaActorFile mediaActorFile) { - if (mediaActorFile == null){ - log.warn("MediaActorFile is null. Are you sure you have connected your form to the application?"); - return; - } - mediaActorFileRepository.save(mediaActorFile); - } - - public void deleteMediaActorFile(MediaActorFile mediaActorFile) { - MediaFile mediaFile = mediaActorFile.getMedia_file(); - mediaFile.getMediaActorFiles().remove(mediaActorFile); - mediaFileRepository.save(mediaFile); - MediaActor mediaActor = mediaActorFile.getMedia_actor(); - mediaActor.getMediaActorFiles().remove(mediaActorFile); - mediaActorRepository.save(mediaActor); - mediaActorFileRepository.delete(mediaActorFile); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaVideoService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaVideoService.java deleted file mode 100644 index aaff14a..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/services/MediaVideoService.java +++ /dev/null @@ -1,39 +0,0 @@ -package de.thpeetz.kontor.media.services; - -import de.thpeetz.kontor.media.data.MediaVideo; -import de.thpeetz.kontor.media.repository.MediaVideoRepository; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Slf4j -@Service -public class MediaVideoService { - - private final MediaVideoRepository mediaVideoRepository; - - public MediaVideoService(MediaVideoRepository mediaVideoRepository) { - this.mediaVideoRepository = mediaVideoRepository; - } - - public List findAllMediaVideos(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return mediaVideoRepository.findAll(); - } else { - return mediaVideoRepository.search(stringFilter); - } - } - - public void saveMediaVideo(MediaVideo mediaVideo) { - if (mediaVideo == null) { - log.warn("MediaFile is null. Are you sure you have connected your form to the application?"); - return; - } - mediaVideoRepository.save(mediaVideo); - } - - public void deleteMediaVideo(MediaVideo mediaVideo) { - mediaVideoRepository.delete(mediaVideo); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorFileForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorFileForm.java deleted file mode 100644 index ac3acb1..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorFileForm.java +++ /dev/null @@ -1,106 +0,0 @@ -package de.thpeetz.kontor.media.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; -import de.thpeetz.kontor.media.data.MediaActor; -import de.thpeetz.kontor.media.data.MediaActorFile; -import de.thpeetz.kontor.media.data.MediaFile; -import lombok.Getter; - -import java.util.List; - -public class MediaActorFileForm extends FormLayout { - ComboBox mediaFile = new ComboBox<>("Media File"); - ComboBox mediaActor = new ComboBox<>("Actor"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(MediaActorFile.class); - - public MediaActorFileForm(List mediaFiles, List actors) { - addClassName("mediaactorfile-form"); - binder.bindInstanceFields(this); - - mediaFile.setItems(mediaFiles); - mediaFile.setItemLabelGenerator(MediaFile::getTitle); - mediaActor.setItems(actors); - mediaActor.setItemLabelGenerator(MediaActor::getName); - add(mediaFile, mediaActor, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new MediaActorFileForm.DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new MediaActorFileForm.CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new MediaActorFileForm.SaveEvent(this, binder.getBean())); - } - } - - public void setMediaActorFile(MediaActorFile mediaActorFile) { - binder.setBean(mediaActorFile); - } - - public abstract static class MediaActorFileFormEvent extends ComponentEvent { - @Getter - private MediaActorFile mediaActorFile; - - protected MediaActorFileFormEvent(MediaActorFileForm source, MediaActorFile mediaActorFile) { - super(source, false); - this.mediaActorFile = mediaActorFile; - } - } - - public static class SaveEvent extends MediaActorFileForm.MediaActorFileFormEvent { - SaveEvent(MediaActorFileForm source, MediaActorFile mediaActorFile) { - super(source, mediaActorFile); - } - } - - public static class DeleteEvent extends MediaActorFileForm.MediaActorFileFormEvent { - DeleteEvent(MediaActorFileForm source, MediaActorFile mediaActorFile) { - super(source, mediaActorFile); - } - } - - public static class CloseEvent extends MediaActorFileForm.MediaActorFileFormEvent { - CloseEvent(MediaActorFileForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(MediaActorFileForm.DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(MediaActorFileForm.SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(MediaActorFileForm.CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorFileView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorFileView.java deleted file mode 100644 index f1462b6..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorFileView.java +++ /dev/null @@ -1,114 +0,0 @@ -package de.thpeetz.kontor.media.views; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.media.MediaConstants; -import de.thpeetz.kontor.media.data.MediaActorFile; -import de.thpeetz.kontor.media.services.MediaFileService; -import jakarta.annotation.security.PermitAll; -import lombok.Getter; -import org.springframework.context.annotation.Scope; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = MediaConstants.MEDIAACTORFILE_ROUTE, layout = MainLayout.class) -@PageTitle("MediaActorFile | Media | Kontor") -public class MediaActorFileView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(MediaActorFile.class); - @Getter - MediaActorFileForm form; - MediaFileService service; - - public MediaActorFileView(MediaFileService service) { - this.service = service; - addClassName("mediaactorfile-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("mediaactorfile-grid"); - grid.setSizeFull(); - grid.setColumns("id", "media_actor.name", "media_file.title"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editMediaActorFile(event.getValue())); - } - - private void configureForm() { - form = new MediaActorFileForm(service.findAllMediaFiles(null), service.findAllMediaActors(null)); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveMediaActorFile); - form.addDeleteListener(this::deleteMediaActorFile); - form.addCloseListener(e -> closeEditor()); - } - - private void saveMediaActorFile(MediaActorFileForm.SaveEvent event) { - service.saveMediaActorFile(event.getMediaActorFile()); - updateList(); - closeEditor(); - } - - private void deleteMediaActorFile(MediaActorFileForm.DeleteEvent event) { - service.deleteMediaActorFile(event.getMediaActorFile()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - Button addMediaActorFileButton = new Button("Add MediaActorFile"); - addMediaActorFileButton.addClickListener(click -> addMediaActorFile()); - - HorizontalLayout toolbar = new HorizontalLayout(addMediaActorFileButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editMediaActorFile(MediaActorFile mediaActorFile) { - if (mediaActorFile == null) { - closeEditor(); - } else { - form.setMediaActorFile(mediaActorFile); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setMediaActorFile(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addMediaActorFile() { - grid.asSingleSelect().clear(); - editMediaActorFile(new MediaActorFile()); - } - - public void updateList() { - grid.setItems(service.findAllMediaActorFiles()); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorForm.java deleted file mode 100644 index b9a7dbd..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorForm.java +++ /dev/null @@ -1,118 +0,0 @@ -package de.thpeetz.kontor.media.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; -import de.thpeetz.kontor.media.data.MediaActor; -import de.thpeetz.kontor.media.data.MediaActorFile; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; - -@Slf4j -public class MediaActorForm extends FormLayout { - - TextField name = new TextField("Name"); - TextField url = new TextField("URL"); - Grid mediaActorFiles = new Grid<>(MediaActorFile.class); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(MediaActor.class); - - public MediaActorForm() { - addClassName("media-actor-form"); - binder.bindInstanceFields(this); - - mediaActorFiles.setColumns("media_file.title"); - mediaActorFiles.getColumnByKey("media_file.title").setHeader("File Title"); - add(name, 2); - add(url, 2); - add(mediaActorFiles, 2); - add(createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new MediaActorForm.DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new MediaActorForm.CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new MediaActorForm.SaveEvent(this, binder.getBean())); - } - } - - public void setMediaActor(MediaActor mediaActor) { - binder.setBean(mediaActor); - } - - public void setMediaActorFiles(List mediaActorFiles) { - log.info("Setting mediaActorFiles: {}", mediaActorFiles); - this.mediaActorFiles.setItems(mediaActorFiles); - } - - public abstract static class MediaActorFormEvent extends ComponentEvent { - private MediaActor mediaActor; - - protected MediaActorFormEvent(MediaActorForm source, MediaActor mediaActor) { - super(source, false); - this.mediaActor = mediaActor; - } - - public MediaActor getMediaActor() { - return mediaActor; - } - } - - public static class SaveEvent extends MediaActorForm.MediaActorFormEvent { - SaveEvent(MediaActorForm source, MediaActor mediaActor) { - super(source, mediaActor); - } - } - - public static class DeleteEvent extends MediaActorForm.MediaActorFormEvent { - DeleteEvent(MediaActorForm source, MediaActor mediaActor) { - super(source, mediaActor); - } - } - - public static class CloseEvent extends MediaActorForm.MediaActorFormEvent { - CloseEvent(MediaActorForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(MediaActorForm.DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(MediaActorForm.SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(MediaActorForm.CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorView.java deleted file mode 100644 index f864dee..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorView.java +++ /dev/null @@ -1,144 +0,0 @@ -package de.thpeetz.kontor.media.views; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.common.views.ColumnToggleContextMenu; -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.media.MediaConstants; -import de.thpeetz.kontor.media.data.MediaActor; -import de.thpeetz.kontor.media.data.MediaFile; -import de.thpeetz.kontor.media.services.MediaFileService; -import jakarta.annotation.security.PermitAll; -import lombok.Getter; -import org.springframework.context.annotation.Scope; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = MediaConstants.MEDIAACTOR_ROUTE, layout = MainLayout.class) -@PageTitle("Actor | Media | Kontor") -public class MediaActorView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(MediaActor.class, false); - Grid.Column idColumn = grid.addColumn(MediaActor::getId) - .setHeader("ID").setResizable(true).setSortable(true); - Grid.Column createdColumn = grid.addColumn(MediaActor::getCreatedDate) - .setHeader("Erstellt").setResizable(true).setSortable(true); - Grid.Column modifiedColumn = grid.addColumn(MediaActor::getLastModifiedDate) - .setHeader("Geändert").setResizable(true).setSortable(true); - Grid.Column nameColumn = grid.addColumn(MediaActor::getName) - .setHeader("Name").setResizable(true).setSortable(true); - Grid.Column urlColumn = grid.addColumn(MediaActor::getUrl) - .setHeader("URL").setResizable(true).setSortable(true); - TextField filterText = new TextField(); - @Getter - MediaActorForm form; - MediaFileService service; - - public MediaActorView(MediaFileService service) { - this.service = service; - addClassName("media-actor-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("media-actor-grid"); - grid.setSizeFull(); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editMediaActor(event.getValue())); - } - - private void configureForm() { - form = new MediaActorForm(); - form.setWidth("75em"); - form.setVisible(false); - form.addSaveListener(this::saveMediaActor); - form.addDeleteListener(this::deleteMediaActor); - form.addCloseListener(e -> closeEditor()); - } - - private void saveMediaActor(MediaActorForm.SaveEvent event) { - service.saveMediaActor(event.getMediaActor()); - updateList(); - closeEditor(); - } - - private void deleteMediaActor(MediaActorForm.DeleteEvent event) { - service.deleteMediaActor(event.getMediaActor()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addMediaActorButton = new Button("Add actor"); - addMediaActorButton.addClickListener(click -> addMediaActor()); - - Button menuButton = new Button("Show/Hide Columns"); - menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); - columnToggleContextMenu.addColumnToggleItem(idColumn); - columnToggleContextMenu.addColumnToggleItem(createdColumn); - columnToggleContextMenu.addColumnToggleItem(modifiedColumn); - columnToggleContextMenu.addColumnToggleItem(nameColumn); - columnToggleContextMenu.addColumnToggleItem(urlColumn); - HorizontalLayout toolbar = new HorizontalLayout(filterText, addMediaActorButton, menuButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editMediaActor(MediaActor mediaActor) { - if (mediaActor == null) { - closeEditor(); - } else { - form.setMediaActor(mediaActor); - form.setMediaActorFiles(mediaActor.getMediaActorFiles()); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setMediaActor(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addMediaActor() { - grid.asSingleSelect().clear(); - editMediaActor(new MediaActor()); - } - - public void updateList() { - grid.setItems(service.findAllMediaActors(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaArticleForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaArticleForm.java deleted file mode 100644 index d658e4e..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaArticleForm.java +++ /dev/null @@ -1,108 +0,0 @@ -package de.thpeetz.kontor.media.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.checkbox.Checkbox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; -import de.thpeetz.kontor.media.data.MediaArticle; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class MediaArticleForm extends FormLayout { - - TextField url = new TextField("URL"); - TextField title = new TextField("Title"); - Checkbox review = new Checkbox("Review"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(MediaArticle.class); - - public MediaArticleForm() { - addClassName("mediaarticle-form"); - binder.bindInstanceFields(this); - add(url, 2); - add(title, 2); - add(review, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new MediaArticleForm.DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new MediaArticleForm.CloseEvent(this))); - - binder.addStatusChangeListener(event -> { - save.setEnabled(event.getBinder().isValid()); - }); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new MediaArticleForm.SaveEvent(this, binder.getBean())); - } - } - - public void setMediaArticle(MediaArticle mediaArticle) { - binder.setBean(mediaArticle); - } - - public abstract static class MediaArticleFormEvent extends ComponentEvent { - private MediaArticle mediaArticle; - - protected MediaArticleFormEvent(MediaArticleForm source, MediaArticle mediaArticle) { - super(source, false); - this.mediaArticle = mediaArticle; - } - - public MediaArticle getMediaArticle() { - return mediaArticle; - } - } - - public static class SaveEvent extends MediaArticleForm.MediaArticleFormEvent { - SaveEvent(MediaArticleForm source, MediaArticle mediaArticle) { - super(source, mediaArticle); - } - } - - public static class DeleteEvent extends MediaArticleForm.MediaArticleFormEvent { - DeleteEvent(MediaArticleForm source, MediaArticle mediaArticle) { - super(source, mediaArticle); - } - } - - public static class CloseEvent extends MediaArticleForm.MediaArticleFormEvent { - CloseEvent(MediaArticleForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(MediaArticleForm.DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(MediaArticleForm.SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(MediaArticleForm.CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaArticleView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaArticleView.java deleted file mode 100644 index 7728890..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaArticleView.java +++ /dev/null @@ -1,144 +0,0 @@ -package de.thpeetz.kontor.media.views; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.contextmenu.ContextMenu; -import com.vaadin.flow.component.contextmenu.MenuItem; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.icon.Icon; -import com.vaadin.flow.component.icon.VaadinIcon; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.common.views.ColumnToggleContextMenu; -import de.thpeetz.kontor.common.views.StatusIcon; -import de.thpeetz.kontor.media.MediaConstants; -import de.thpeetz.kontor.media.data.MediaArticle; -import de.thpeetz.kontor.media.services.MediaArticleService; -import jakarta.annotation.security.PermitAll; -import lombok.Getter; -import org.springframework.context.annotation.Scope; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = MediaConstants.MEDIAARTICLE_ROUTE, layout = MainLayout.class) -@PageTitle("MediaArticle | Media | Kontor") -public class MediaArticleView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(MediaArticle.class, false); - Grid.Column idColumn = grid.addColumn(MediaArticle::getId).setHeader("ID").setResizable(true); - Grid.Column urlColumn = grid.addColumn(MediaArticle::getUrl).setHeader("URL").setResizable(true).setSortable(true); - Grid.Column titleColumn = grid.addColumn(MediaArticle::getTitle).setHeader("Titel").setResizable(true).setSortable(true); - Grid.Column reviewColumn = grid.addComponentColumn(mediaArticle -> StatusIcon.create(mediaArticle.isReview())) - .setHeader("Überprüfung") - .setWidth("6rem"); - TextField searchField = new TextField(); - @Getter - MediaArticleForm form; - MediaArticleService service; - - public MediaArticleView(MediaArticleService service) { - this.service = service; - addClassName("mediaarticle-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("mediaarticle-grid"); - grid.setSizeFull(); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - idColumn.setVisible(false); - grid.asSingleSelect().addValueChangeListener(event -> editMediaArticle(event.getValue())); - } - - private void configureForm() { - form = new MediaArticleForm(); - form.setWidth("75em"); - form.setVisible(false); - form.addSaveListener(this::saveMediaArticle); - form.addDeleteListener(this::deleteMediaArticle); - form.addCloseListener(e -> closeEditor()); - } - - private void saveMediaArticle(MediaArticleForm.SaveEvent event) { - service.saveMediaArticle(event.getMediaArticle()); - updateList(); - closeEditor(); - } - - private void deleteMediaArticle(MediaArticleForm.DeleteEvent event) { - service.deleteMediaArticle(event.getMediaArticle()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - searchField.setPlaceholder("Search"); - searchField.setClearButtonVisible(true); - searchField.setPrefixComponent(new Icon(VaadinIcon.SEARCH)); - searchField.setValueChangeMode(ValueChangeMode.EAGER); - searchField.addValueChangeListener(e -> updateList()); - - Button addMediaArticleButton = new Button("Add MediaArticle"); - addMediaArticleButton.addClickListener(click -> addMediaArticle()); - - Button menuButton = new Button("Show/Hide Columns"); - menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); - columnToggleContextMenu.addColumnToggleItem(idColumn); - columnToggleContextMenu.addColumnToggleItem(urlColumn); - columnToggleContextMenu.addColumnToggleItem(titleColumn); - columnToggleContextMenu.addColumnToggleItem(reviewColumn); - HorizontalLayout toolbar = new HorizontalLayout(searchField, addMediaArticleButton, menuButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editMediaArticle(MediaArticle mediaArticle) { - if (mediaArticle == null) { - closeEditor(); - } else { - form.setMediaArticle(mediaArticle); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setMediaArticle(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addMediaArticle() { - grid.asSingleSelect().clear(); - editMediaArticle(new MediaArticle()); - } - - public void updateList() { - grid.setItems(service.findAllMediaArticles(searchField.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaFileForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaFileForm.java deleted file mode 100644 index 4b4b469..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaFileForm.java +++ /dev/null @@ -1,128 +0,0 @@ -package de.thpeetz.kontor.media.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.checkbox.Checkbox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; -import de.thpeetz.kontor.media.data.MediaActorFile; -import de.thpeetz.kontor.media.data.MediaFile; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; - -@Slf4j -public class MediaFileForm extends FormLayout { - - TextField id = new TextField("ID"); - TextField url = new TextField("URL"); - TextField title = new TextField("Title"); - TextField fileName = new TextField("Dateiname"); - TextField cloudLink = new TextField("Cloud Link"); - Checkbox review = new Checkbox("Review"); - Checkbox shouldDownload = new Checkbox("Download"); - Grid mediaActorFiles = new Grid<>(MediaActorFile.class); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(MediaFile.class); - - public MediaFileForm() { - addClassName("mediafile-form"); - binder.bindInstanceFields(this); - id.setReadOnly(true); - - mediaActorFiles.setColumns("media_actor.name"); - mediaActorFiles.getColumnByKey("media_actor.name").setHeader("Actor"); - - add(id, 2); - add(url, 2); - add(title, 2); - add(fileName, 2); - add(cloudLink, 2); - add(review, shouldDownload); - add(mediaActorFiles, 2); - add(createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(event -> save.setEnabled(event.getBinder().isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setMediaFile(MediaFile mediaFile) { - binder.setBean(mediaFile); - } - - public void setMediaActorFiles(List actorFiles) { - mediaActorFiles.setItems(actorFiles); - } - - @Getter - public abstract static class MediaFileFormEvent extends ComponentEvent { - private final MediaFile mediaFile; - - protected MediaFileFormEvent(MediaFileForm source, MediaFile mediaFile) { - super(source, false); - this.mediaFile = mediaFile; - } - - } - - public static class SaveEvent extends MediaFileFormEvent { - SaveEvent(MediaFileForm source, MediaFile mediaFile) { - super(source, mediaFile); - } - } - - public static class DeleteEvent extends MediaFileFormEvent { - DeleteEvent(MediaFileForm source, MediaFile mediaFile) { - super(source, mediaFile); - } - } - - public static class CloseEvent extends MediaFileFormEvent { - CloseEvent(MediaFileForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaFileView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaFileView.java deleted file mode 100644 index 54bc040..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaFileView.java +++ /dev/null @@ -1,158 +0,0 @@ -package de.thpeetz.kontor.media.views; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; -import de.thpeetz.kontor.common.views.*; -import de.thpeetz.kontor.media.data.MediaFile; -import de.thpeetz.kontor.media.services.MediaFileService; -import jakarta.annotation.security.RolesAllowed; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Scope; - -@Slf4j -@SpringComponent -@Scope("prototype") -@RolesAllowed("MEDIA") -@Route(value = "media/mediafile", layout = MainLayout.class) -@PageTitle("MediaFile | Media | Kontor") -public class MediaFileView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(MediaFile.class, false); - Grid.Column idColumn = grid.addColumn(MediaFile::getId) - .setHeader("ID").setResizable(true).setSortable(true); - Grid.Column createdColumn = grid.addColumn(MediaFile::getCreatedDate) - .setHeader("Erstellt").setResizable(true).setSortable(true); - Grid.Column modifiedColumn = grid.addColumn(MediaFile::getLastModifiedDate) - .setHeader("Geändert").setResizable(true).setSortable(true); - Grid.Column urlColumn = grid.addColumn(MediaFile::getUrl) - .setHeader("URL").setResizable(true).setSortable(true); - Grid.Column titleColumn = grid.addColumn(MediaFile::getTitle) - .setHeader("Titel").setResizable(true).setSortable(true); - Grid.Column fileNameColumn = grid.addColumn(MediaFile::getFileName) - .setHeader("Dateiname").setResizable(true).setSortable(true); - Grid.Column cloudLinkColumn = grid.addColumn(MediaFile::getCloudLink) - .setHeader("Cloud Link").setResizable(true).setSortable(true); - Grid.Column reviewColumn = grid.addComponentColumn(mediafile -> StatusIcon.create(mediafile.isReview())). - setHeader("Überprüfung").setWidth("6rem").setSortable(true); - Grid.Column shouldDownloadColumn = grid.addComponentColumn(mediafile -> StatusIcon.create(mediafile.isShouldDownload())). - setHeader("Download?").setWidth("6rem").setSortable(true); - SearchFilterField searchFilterField = new SearchFilterField(); - @Getter - MediaFileForm form; - MediaFileService service; - - public MediaFileView(MediaFileService service) { - this.service = service; - addClassName("mediafile-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("mediafile-grid"); - grid.setSizeFull(); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - //idColumn.setVisible(false); - grid.asSingleSelect().addValueChangeListener(event -> editMediaFile(event.getValue())); - } - - private void configureForm() { - form = new MediaFileForm(); - form.setWidth("75em"); - form.setVisible(false); - form.addSaveListener(this::saveMediaFile); - form.addDeleteListener(this::deleteMediaFile); - form.addCloseListener(e -> closeEditor()); - } - - private void saveMediaFile(MediaFileForm.SaveEvent event) { - service.saveMediaFile(event.getMediaFile()); - updateList(); - closeEditor(); - } - - private void deleteMediaFile(MediaFileForm.DeleteEvent event) { - service.deleteMediaFile(event.getMediaFile()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - searchFilterField.addFilter("Überprüfung"); - searchFilterField.addFilter("Download"); - searchFilterField.addValueChangeListener(e -> updateList()); - - Button addMediaFileButton = new Button("Add MediaFile"); - addMediaFileButton.addClickListener(click -> addMediaFile()); - - Button menuButton = new Button("Show/Hide Columns"); - menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); - columnToggleContextMenu.addColumnToggleItem(idColumn); - columnToggleContextMenu.addColumnToggleItem(createdColumn); - columnToggleContextMenu.addColumnToggleItem(modifiedColumn); - columnToggleContextMenu.addColumnToggleItem(urlColumn); - columnToggleContextMenu.addColumnToggleItem(titleColumn); - columnToggleContextMenu.addColumnToggleItem(fileNameColumn); - columnToggleContextMenu.addColumnToggleItem(cloudLinkColumn); - columnToggleContextMenu.addColumnToggleItem(reviewColumn); - columnToggleContextMenu.addColumnToggleItem(shouldDownloadColumn); - HorizontalLayout toolbar = new HorizontalLayout(searchFilterField, addMediaFileButton, menuButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editMediaFile(MediaFile mediaFile) { - if (mediaFile == null) { - closeEditor(); - } else { - form.setMediaFile(mediaFile); - if (mediaFile.getMediaActorFiles() == null) { - log.info("no MediaActorFiles"); - } else { - log.info("MediaActorFiles size: {}", mediaFile.getMediaActorFiles().size()); - } - form.setMediaActorFiles(mediaFile.getMediaActorFiles()); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setMediaFile(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addMediaFile() { - grid.asSingleSelect().clear(); - editMediaFile(new MediaFile()); - } - - public void updateList() { - log.info("searchFilterField: {}", searchFilterField.getValue()); - grid.setItems(service.findAllMediaFiles(searchFilterField.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaVideoForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaVideoForm.java deleted file mode 100644 index dbc8d47..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaVideoForm.java +++ /dev/null @@ -1,113 +0,0 @@ -package de.thpeetz.kontor.media.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.checkbox.Checkbox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; -import de.thpeetz.kontor.media.data.MediaVideo; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class MediaVideoForm extends FormLayout { - - TextField url = new TextField("URL"); - TextField title = new TextField("Title"); - TextField fileName = new TextField("Dateiname"); - TextField cloudLink = new TextField("Cloud Link"); - Checkbox review = new Checkbox("Review"); - Checkbox shouldDownload = new Checkbox("Download"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(MediaVideo.class); - - public MediaVideoForm() { - addClassName("mediavideo-form"); - binder.bindInstanceFields(this); - add(url, 2); - add(title, 2); - add(fileName, 2); - add(cloudLink, 2); - add(review, shouldDownload, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(event -> { - save.setEnabled(event.getBinder().isValid()); - }); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setMediaVideo(MediaVideo mediaVideo) { - binder.setBean(mediaVideo); - } - - public abstract static class MediaVideoFormEvent extends ComponentEvent { - private MediaVideo mediaVideo; - - protected MediaVideoFormEvent(MediaVideoForm source, MediaVideo mediaVideo) { - super(source, false); - this.mediaVideo = mediaVideo; - } - - public MediaVideo getMediaVideo() { - return mediaVideo; - } - } - - public static class SaveEvent extends MediaVideoFormEvent { - SaveEvent(MediaVideoForm source, MediaVideo mediaVideo) { - super(source, mediaVideo); - } - } - - public static class DeleteEvent extends MediaVideoFormEvent { - DeleteEvent(MediaVideoForm source, MediaVideo mediaVideo) { - super(source, mediaVideo); - } - } - - public static class CloseEvent extends MediaVideoFormEvent { - CloseEvent(MediaVideoForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaVideoView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaVideoView.java deleted file mode 100644 index 37f5554..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaVideoView.java +++ /dev/null @@ -1,151 +0,0 @@ -package de.thpeetz.kontor.media.views; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.contextmenu.ContextMenu; -import com.vaadin.flow.component.contextmenu.MenuItem; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.icon.Icon; -import com.vaadin.flow.component.icon.VaadinIcon; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.common.views.ColumnToggleContextMenu; -import de.thpeetz.kontor.common.views.StatusIcon; -import de.thpeetz.kontor.media.MediaConstants; -import de.thpeetz.kontor.media.data.MediaVideo; -import de.thpeetz.kontor.media.services.MediaVideoService; -import jakarta.annotation.security.PermitAll; -import lombok.Getter; -import org.springframework.context.annotation.Scope; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = MediaConstants.MEDIAVIDEO_ROUTE, layout = MainLayout.class) -@PageTitle("MediaVideo | Media | Kontor") -public class MediaVideoView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(MediaVideo.class, false); - Grid.Column idColumn = grid.addColumn(MediaVideo::getId).setHeader("ID").setResizable(true); - Grid.Column urlColumn = grid.addColumn(MediaVideo::getUrl).setHeader("URL").setResizable(true).setSortable(true); - Grid.Column titleColumn = grid.addColumn(MediaVideo::getTitle).setHeader("Titel").setResizable(true).setSortable(true); - Grid.Column fileNameColumn = grid.addColumn(MediaVideo::getFileName).setHeader("Dateiname").setResizable(true).setSortable(true); - Grid.Column cloudLinkColumn = grid.addColumn(MediaVideo::getCloudLink).setHeader("Cloud Link").setResizable(true).setSortable(true); - Grid.Column reviewColumn = grid.addComponentColumn(mediaVideo -> StatusIcon.create(mediaVideo.isReview())) - .setHeader("Überprüfung") - .setWidth("6rem"); - Grid.Column shouldDownloadColumn = grid.addComponentColumn(mediaVideo -> StatusIcon.create(mediaVideo.isShouldDownload())) - .setHeader("Download?") - .setWidth("6rem"); - TextField searchField = new TextField(); - @Getter - MediaVideoForm form; - MediaVideoService service; - - public MediaVideoView(MediaVideoService service) { - this.service = service; - addClassName("mediavideo-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("mediavideo-grid"); - grid.setSizeFull(); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - idColumn.setVisible(false); - grid.asSingleSelect().addValueChangeListener(event -> editMediaVideo(event.getValue())); - } - - private void configureForm() { - form = new MediaVideoForm(); - form.setWidth("75em"); - form.setVisible(false); - form.addSaveListener(this::saveMediaVideo); - form.addDeleteListener(this::deleteMediaVideo); - form.addCloseListener(e -> closeEditor()); - } - - private void saveMediaVideo(MediaVideoForm.SaveEvent event) { - service.saveMediaVideo(event.getMediaVideo()); - updateList(); - closeEditor(); - } - - private void deleteMediaVideo(MediaVideoForm.DeleteEvent event) { - service.deleteMediaVideo(event.getMediaVideo()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - searchField.setPlaceholder("Search"); - searchField.setClearButtonVisible(true); - searchField.setPrefixComponent(new Icon(VaadinIcon.SEARCH)); - searchField.setValueChangeMode(ValueChangeMode.EAGER); - searchField.addValueChangeListener(e -> updateList()); - - Button addMediaVideoButton = new Button("Add MediaVideo"); - addMediaVideoButton.addClickListener(click -> addMediaVideo()); - - Button menuButton = new Button("Show/Hide Columns"); - menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); - columnToggleContextMenu.addColumnToggleItem(idColumn); - columnToggleContextMenu.addColumnToggleItem(urlColumn); - columnToggleContextMenu.addColumnToggleItem(titleColumn); - columnToggleContextMenu.addColumnToggleItem(fileNameColumn); - columnToggleContextMenu.addColumnToggleItem(cloudLinkColumn); - columnToggleContextMenu.addColumnToggleItem(reviewColumn); - columnToggleContextMenu.addColumnToggleItem(shouldDownloadColumn); - HorizontalLayout toolbar = new HorizontalLayout(searchField, addMediaVideoButton, menuButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editMediaVideo(MediaVideo mediaVideo) { - if (mediaVideo == null) { - closeEditor(); - } else { - form.setMediaVideo(mediaVideo); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setMediaVideo(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addMediaVideo() { - grid.asSingleSelect().clear(); - editMediaVideo(new MediaVideo()); - } - - public void updateList() { - grid.setItems(service.findAllMediaVideos(searchField.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/properties/MailProperties.java b/kontor-spring/src/main/java/de/thpeetz/kontor/properties/MailProperties.java new file mode 100644 index 0000000..ba6dc46 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/properties/MailProperties.java @@ -0,0 +1,78 @@ +package de.thpeetz.kontor.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "mail") +public class MailProperties { + + private String protocol; + private String host; + private Integer port; + private String userName; + private String password; + private Boolean startTls; + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public Boolean getStartTls() { + return startTls; + } + + public void setStartTls(Boolean startTls) { + this.startTls = startTls; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("MailProperties{"); + sb.append("protocol='").append(protocol).append('\''); + sb.append(", host='").append(host).append('\''); + sb.append(", port=").append(port); + sb.append(", starttls=").append(startTls); + sb.append(", userName='").append(userName).append('\''); + sb.append(", password='").append(password).append('\''); + sb.append('}'); + return sb.toString(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/admin/AssignmentRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/admin/AssignmentRepository.java new file mode 100644 index 0000000..ae0d8d0 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/admin/AssignmentRepository.java @@ -0,0 +1,16 @@ +package de.thpeetz.kontor.repository.admin; + +import de.thpeetz.kontor.data.admin.Assignment; +import de.thpeetz.kontor.data.admin.Permission; +import de.thpeetz.kontor.data.admin.Profile; + +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface AssignmentRepository extends JpaRepository { + + List findByProfile(Profile profile); + + List findByPermission(Permission permission); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/admin/MailAccountRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/admin/MailAccountRepository.java new file mode 100644 index 0000000..cd17de2 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/admin/MailAccountRepository.java @@ -0,0 +1,9 @@ +package de.thpeetz.kontor.repository.admin; + +import org.springframework.data.jpa.repository.JpaRepository; + +import de.thpeetz.kontor.data.mailclient.MailAccount; + + +public interface MailAccountRepository extends JpaRepository { +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/admin/PermissionRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/admin/PermissionRepository.java new file mode 100644 index 0000000..a9d660e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/admin/PermissionRepository.java @@ -0,0 +1,20 @@ +package de.thpeetz.kontor.repository.admin; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.admin.Permission; + +import java.util.List; + +public interface PermissionRepository extends JpaRepository { + + @Query("select p from Permission p " + + "where lower(p.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + @Query("select p from Permission p " + + "where lower(p.name) like lower(:name) ") + Permission findByName(@Param("name") String name); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/admin/ProfileRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/admin/ProfileRepository.java new file mode 100644 index 0000000..a4d1769 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/admin/ProfileRepository.java @@ -0,0 +1,18 @@ +package de.thpeetz.kontor.repository.admin; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.admin.Profile; + +import java.util.List; + +public interface ProfileRepository extends JpaRepository { + + @Query("select p from Profile p " + + "where lower(p.lastName) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + Profile findByUserName(String userName); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/ArticleAuthorRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/ArticleAuthorRepository.java new file mode 100644 index 0000000..5bb4b05 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/ArticleAuthorRepository.java @@ -0,0 +1,16 @@ +package de.thpeetz.kontor.repository.bookshelf; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; + +import de.thpeetz.kontor.data.bookshelf.Article; +import de.thpeetz.kontor.data.bookshelf.ArticleAuthor; +import de.thpeetz.kontor.data.bookshelf.Author; + +public interface ArticleAuthorRepository extends JpaRepository { + + List findByAuthor(Author author); + + List findByArticle(Article article); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/ArticleRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/ArticleRepository.java new file mode 100644 index 0000000..42561d2 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/ArticleRepository.java @@ -0,0 +1,18 @@ +package de.thpeetz.kontor.repository.bookshelf; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.bookshelf.Article; + +public interface ArticleRepository extends JpaRepository { + + @Query("select a from Article a " + + "where lower(a.title) like lower(concat('%', :searchTerm, '%'))") + List
    search(@Param("searchTerm") String searchTerm); + + List
    findByTitle(String title); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/AuthorRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/AuthorRepository.java new file mode 100644 index 0000000..01471a5 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/AuthorRepository.java @@ -0,0 +1,20 @@ +package de.thpeetz.kontor.repository.bookshelf; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.bookshelf.Author; + +public interface AuthorRepository extends JpaRepository { + + @Query("select a from Author a " + + "where lower(a.firstName) like lower(concat('%', :searchTerm, '%')) " + + "or lower(a.lastName) like lower(concat('%', :searchTerm, '%'))") + List search(@Param("searchTerm") String searchTerm); + + Author findByFirstNameAndLastName(String firstName, String lastName); + +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/BookAuthorRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/BookAuthorRepository.java new file mode 100644 index 0000000..a62294f --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/BookAuthorRepository.java @@ -0,0 +1,16 @@ +package de.thpeetz.kontor.repository.bookshelf; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; + +import de.thpeetz.kontor.data.bookshelf.Author; +import de.thpeetz.kontor.data.bookshelf.Book; +import de.thpeetz.kontor.data.bookshelf.BookAuthor; + +public interface BookAuthorRepository extends JpaRepository { + + List findByAuthor(Author author); + + List findByBook(Book book); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/BookRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/BookRepository.java new file mode 100644 index 0000000..1f0192e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/BookRepository.java @@ -0,0 +1,23 @@ +package de.thpeetz.kontor.repository.bookshelf; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.bookshelf.Book; + +import java.util.List; + +public interface BookRepository extends JpaRepository { + + @Query("select b from Book b " + + "where lower(b.title) like lower(concat('%', :searchTerm, '%')) " + + "or lower(b.isbn) like lower(concat('%', :searchTerm, '%'))") + List search(@Param("searchTerm") String searchTerm); + + List findByTitle(String name); + + List findByTitleIgnoreCase(String name); + + List findByIsbn(String isbn); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/BookshelfPublisherRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/BookshelfPublisherRepository.java new file mode 100644 index 0000000..afd4710 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/bookshelf/BookshelfPublisherRepository.java @@ -0,0 +1,20 @@ +package de.thpeetz.kontor.repository.bookshelf; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.bookshelf.BookshelfPublisher; + +public interface BookshelfPublisherRepository extends JpaRepository { + + @Query("select p from BookshelfPublisher p " + + "where lower(p.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + BookshelfPublisher findByName(String name); + + List findByNameIgnoreCase(String name); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/ArtistRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/ArtistRepository.java new file mode 100644 index 0000000..53b6273 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/ArtistRepository.java @@ -0,0 +1,19 @@ +package de.thpeetz.kontor.repository.comics; + +import java.util.List; + +import de.thpeetz.kontor.data.comics.Artist; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface ArtistRepository extends JpaRepository { + @Query("select a from Artist a " + + "where lower(a.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + List findByNameIgnoreCase(String name); + + Artist findByName(String name); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/ComicRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/ComicRepository.java new file mode 100644 index 0000000..98d7dbc --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/ComicRepository.java @@ -0,0 +1,41 @@ +package de.thpeetz.kontor.repository.comics; + +import java.util.List; + +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.Publisher; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface ComicRepository extends JpaRepository { + @Query("select c from Comic c " + + "where lower(c.title) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + @Query("select c from Comic c " + + "where lower(c.title) like lower(concat('%', :searchTerm, '%')) " + + "AND c.currentOrder=:currentOrder AND c.completed=:completed") + List search(@Param("searchTerm") String searchTerm, Boolean currentOrder, Boolean completed); + + Comic findByTitleAndPublisher(String title, Publisher publisher); + + List findByTitle(String title); + + List findByTitleIgnoreCase(String title); + + List findByCurrentOrderAndCompleted(Boolean currentOrder, Boolean completed); + + List findByCurrentOrder(Boolean currentOrder); + + List findByCompleted(Boolean completed); + + @Query("select c from Comic c " + + "where lower(c.title) like lower(concat('%', :searchTerm, '%')) AND c.currentOrder=:currentOrder") + List searchAndFilterByCurrentOrder(String searchTerm, Boolean currentOrder); + + @Query("select c from Comic c " + + "where lower(c.title) like lower(concat('%', :searchTerm, '%')) AND c.completed=:completed") + List searchAndFilterByCompleted(String searchTerm, Boolean completed); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/ComicWorkRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/ComicWorkRepository.java new file mode 100644 index 0000000..4028fea --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/ComicWorkRepository.java @@ -0,0 +1,20 @@ +package de.thpeetz.kontor.repository.comics; + +import java.util.List; + +import de.thpeetz.kontor.data.comics.Artist; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.ComicWork; +import de.thpeetz.kontor.data.comics.Worktype; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +public interface ComicWorkRepository extends JpaRepository { + + @Query("SELECT c from ComicWork c where c.comic = ?1 and c.artist = ?2 and c.workType = ?3") + ComicWork findbyComicAndArtistAndWorktype(Comic comic, Artist artist, Worktype worktype); + + @Query("select c from ComicWork c where c.comic = ?1") + List findByComic(Comic comic); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/IssueRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/IssueRepository.java new file mode 100644 index 0000000..28cd4d1 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/IssueRepository.java @@ -0,0 +1,20 @@ +package de.thpeetz.kontor.repository.comics; + +import java.util.List; + +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.Issue; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface IssueRepository extends JpaRepository { + @Query("select i from Issue i " + + "where lower(i.issueNumber) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + List findByComic(Comic comic); + + Issue findByComicAndIssueNumber(Comic comic, String issueNumber); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/IssueWorkRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/IssueWorkRepository.java new file mode 100644 index 0000000..425fda7 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/IssueWorkRepository.java @@ -0,0 +1,19 @@ +package de.thpeetz.kontor.repository.comics; + +import de.thpeetz.kontor.data.comics.Artist; +import de.thpeetz.kontor.data.comics.Issue; +import de.thpeetz.kontor.data.comics.IssueWork; +import de.thpeetz.kontor.data.comics.Worktype; + +import org.springframework.data.jpa.repository.*; + +import java.util.*; + +public interface IssueWorkRepository extends JpaRepository { + + @Query("SELECT i from IssueWork i where i.issue = ?1 and i.artist = ?2 and i.workType = ?3") + IssueWork findbyIssueAndArtistAndWorktype(Issue issue, Artist artist, Worktype worktype); + + @Query("select i from IssueWork i where i.issue = ?1") + List findByIssue(Issue issue); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/PublisherRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/PublisherRepository.java new file mode 100644 index 0000000..38b5cc7 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/PublisherRepository.java @@ -0,0 +1,19 @@ +package de.thpeetz.kontor.repository.comics; + +import java.util.List; + +import de.thpeetz.kontor.data.comics.Publisher; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface PublisherRepository extends JpaRepository { + @Query("select p from Publisher p " + + "where lower(p.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + Publisher findByName(String name); + + List findByNameIgnoreCase(String name); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/StoryArcRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/StoryArcRepository.java new file mode 100644 index 0000000..fe32c13 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/StoryArcRepository.java @@ -0,0 +1,20 @@ +package de.thpeetz.kontor.repository.comics; + +import java.util.List; + +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.StoryArc; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface StoryArcRepository extends JpaRepository { + @Query("select s from StoryArc s " + + "where lower(s.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + StoryArc findByNameAndComic(String name, Comic comic); + + List findByComic(Comic comic); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/TradePaperbackRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/TradePaperbackRepository.java new file mode 100644 index 0000000..95b8e41 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/TradePaperbackRepository.java @@ -0,0 +1,23 @@ +package de.thpeetz.kontor.repository.comics; + +import java.util.List; + +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.TradePaperback; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface TradePaperbackRepository extends JpaRepository { + @Query("select t from TradePaperback t " + + "where lower(t.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + List findByComic(Comic comic); + + List findByNameAndComic(String name, Comic comic); + + @Query("select t from TradePaperback t where t.name = ?1 and t.comic = ?2 and t.issueStart = ?3 and t.issueEnd = ?4") + TradePaperback findByFields(String name, Comic comic, int start, int end); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/VolumeRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/VolumeRepository.java new file mode 100644 index 0000000..8297134 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/VolumeRepository.java @@ -0,0 +1,16 @@ +package de.thpeetz.kontor.repository.comics; + +import java.util.List; + +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.Volume; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface VolumeRepository extends JpaRepository { + + List findByName(String name); + + List findByComic(Comic comic); + +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/WorktypeRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/WorktypeRepository.java new file mode 100644 index 0000000..dff8e52 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/comics/WorktypeRepository.java @@ -0,0 +1,20 @@ +package de.thpeetz.kontor.repository.comics; + +import java.util.List; + +import de.thpeetz.kontor.data.comics.Worktype; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface WorktypeRepository extends JpaRepository { + @Query("select w from Worktype w " + + "where lower(w.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + + Worktype findByName(String name); + + List findByNameIgnoreCase(String name); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaActorFileRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaActorFileRepository.java new file mode 100644 index 0000000..9538774 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaActorFileRepository.java @@ -0,0 +1,8 @@ +package de.thpeetz.kontor.repository.media; + +import org.springframework.data.jpa.repository.JpaRepository; + +import de.thpeetz.kontor.data.media.MediaActorFile; + +public interface MediaActorFileRepository extends JpaRepository { +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaActorRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaActorRepository.java new file mode 100644 index 0000000..9ed6a06 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaActorRepository.java @@ -0,0 +1,19 @@ +package de.thpeetz.kontor.repository.media; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.media.MediaActor; + +import java.util.List; + +public interface MediaActorRepository extends JpaRepository { + @Query("select m from MediaActor m " + + "where lower(m.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + List findByNameIgnoreCase(String name); + + MediaActor findByName(String name); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaArticleRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaArticleRepository.java new file mode 100644 index 0000000..c1d92d7 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaArticleRepository.java @@ -0,0 +1,15 @@ +package de.thpeetz.kontor.repository.media; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.media.MediaArticle; + +import java.util.List; + +public interface MediaArticleRepository extends JpaRepository { + @Query("select m from MediaArticle m " + + "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%'))") + List search(@Param("searchTerm") String searchTerm); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaFileRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaFileRepository.java new file mode 100644 index 0000000..252e3d9 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaFileRepository.java @@ -0,0 +1,31 @@ +package de.thpeetz.kontor.repository.media; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.media.MediaFile; + +public interface MediaFileRepository extends JpaRepository { + @Query("select m from MediaFile m " + + "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%'))") + List search(@Param("searchTerm") String searchTerm); + + List findByShouldDownload(Boolean shouldDownload); + + List findByReview(Boolean review); + + List findByReviewAndShouldDownload(Boolean review, Boolean shouldDownload); + + MediaFile findByUrl(String url); + + @Query("select m from MediaFile m " + + "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%')) " + + "AND m.review=:review AND m.shouldDownload=:download") + List search( + @Param("searchTerm") String searchTerm, + @Param("review") boolean searchReview, + @Param("download") boolean searchDownload); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaLofiRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaLofiRepository.java new file mode 100644 index 0000000..fddd77d --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaLofiRepository.java @@ -0,0 +1,33 @@ +package de.thpeetz.kontor.repository.media; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.media.MediaLofi; + +public interface MediaLofiRepository extends JpaRepository { + + @Query("select m from MediaLofi m " + + "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%'))") + List search(@Param("searchTerm") String searchTerm); + + List findByShouldDownload(Boolean shouldDownload); + + List findByReview(Boolean review); + + List findByReviewAndShouldDownload(Boolean review, Boolean shouldDownload); + + MediaLofi findByUrl(String url); + + @Query("select m from MediaLofi m " + + "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%')) " + + + "AND m.review=:review AND m.shouldDownload=:download") + List search( + @Param("searchTerm") String searchTerm, + @Param("review") boolean searchReview, + @Param("download") boolean searchDownload); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaVideoRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaVideoRepository.java new file mode 100644 index 0000000..1b87c7d --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/media/MediaVideoRepository.java @@ -0,0 +1,17 @@ +package de.thpeetz.kontor.repository.media; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.media.MediaVideo; + +import java.util.List; + +public interface MediaVideoRepository extends JpaRepository { + + @Query("select m from MediaVideo m " + + "where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%'))") + List search(@Param("searchTerm") String searchTerm); + +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/CardRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/CardRepository.java new file mode 100644 index 0000000..3735e41 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/CardRepository.java @@ -0,0 +1,22 @@ +package de.thpeetz.kontor.repository.tysc; + +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.tysc.Card; +import de.thpeetz.kontor.data.tysc.CardSet; +import de.thpeetz.kontor.data.tysc.Rooster; +import de.thpeetz.kontor.data.tysc.Vendor; + +public interface CardRepository extends JpaRepository { + + @Query("SELECT c FROM Card c WHERE c.vendor = ?1 AND c.cardSet = ?2 and c.rooster = ?3 and c.cardNumber = ?4 and c.year = ?5") + Card search(Vendor vendor, CardSet cardset, Rooster rooster, int cardNumber, int year); + + @Query("select c from Card c " + + "where str(c.cardNumber) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); +} + diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/CardSetRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/CardSetRepository.java new file mode 100644 index 0000000..f8b063b --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/CardSetRepository.java @@ -0,0 +1,21 @@ +package de.thpeetz.kontor.repository.tysc; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.tysc.CardSet; +import de.thpeetz.kontor.data.tysc.Vendor; + +public interface CardSetRepository extends JpaRepository { + + List findByName(String name); + + CardSet findByNameAndVendor(String name, Vendor vendor); + + @Query("select c from CardSet c " + + "where lower(c.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/FieldPositionRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/FieldPositionRepository.java new file mode 100644 index 0000000..e152b9d --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/FieldPositionRepository.java @@ -0,0 +1,25 @@ +package de.thpeetz.kontor.repository.tysc; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.tysc.FieldPosition; +import de.thpeetz.kontor.data.tysc.Sport; + +public interface FieldPositionRepository extends JpaRepository { + + @Query("select p from FieldPosition p " + + "where lower(p.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + List findBySport(Sport sport); + + FieldPosition findByShortName(String searchTerm); + + List findByShortNameIgnoreCase(String shortName); + + FieldPosition findByShortNameAndSport(String shortName, Sport sport); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/PlayerRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/PlayerRepository.java new file mode 100644 index 0000000..1f41c44 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/PlayerRepository.java @@ -0,0 +1,19 @@ +package de.thpeetz.kontor.repository.tysc; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.tysc.Player; + +public interface PlayerRepository extends JpaRepository { + + @Query("select p from Player p " + + "where lower(p.firstName) like lower(concat('%', :searchTerm, '%')) " + + "or lower(p.lastName) like lower(concat('%', :searchTerm, '%'))") + List search(@Param("searchTerm") String searchTerm); + + Player findByFirstNameAndLastName(String firstName, String lastName); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/RoosterRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/RoosterRepository.java new file mode 100644 index 0000000..2bbf4c0 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/RoosterRepository.java @@ -0,0 +1,16 @@ +package de.thpeetz.kontor.repository.tysc; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import de.thpeetz.kontor.data.tysc.FieldPosition; +import de.thpeetz.kontor.data.tysc.Player; +import de.thpeetz.kontor.data.tysc.Rooster; +import de.thpeetz.kontor.data.tysc.Team; + +public interface RoosterRepository extends JpaRepository{ + + @Query("SELECT r FROM Rooster r WHERE r.player = ?1 AND r.team = ?2 AND r.position = ?3 AND r.year = ?4") + Rooster findByReferences(Player player, Team team, FieldPosition position, int year); +} + diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/SportRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/SportRepository.java new file mode 100644 index 0000000..8c32c46 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/SportRepository.java @@ -0,0 +1,19 @@ +package de.thpeetz.kontor.repository.tysc; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.tysc.Sport; + +public interface SportRepository extends JpaRepository { + @Query("select s from Sport s " + + "where lower(s.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + Sport findByName(String name); + + List findByNameIgnoreCase(String name); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/TeamRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/TeamRepository.java new file mode 100644 index 0000000..d9f68a1 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/TeamRepository.java @@ -0,0 +1,29 @@ +package de.thpeetz.kontor.repository.tysc; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.tysc.Team; + +/** + * The repository interface for managing teams. + */ +public interface TeamRepository extends JpaRepository { + + /** + * Searches for teams based on a search term. + * + * @param searchTerm the search term to match against team names + * @return a list of teams matching the search term + */ + @Query("select t from Team t " + + "where lower(t.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + Team findByName(String name); + + List findByNameIgnoreCase(String name); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/VendorRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/VendorRepository.java new file mode 100644 index 0000000..d7a6b00 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/repository/tysc/VendorRepository.java @@ -0,0 +1,19 @@ +package de.thpeetz.kontor.repository.tysc; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import de.thpeetz.kontor.data.tysc.Vendor; + +public interface VendorRepository extends JpaRepository { + + @Query("select v from Vendor v where lower(v.name) like lower(concat('%', :searchTerm, '%')) ") + List search(@Param("searchTerm") String searchTerm); + + Vendor findByName(String name); + + List findByNameIgnoreCase(String name); +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/security/SecurityConfig.java b/kontor-spring/src/main/java/de/thpeetz/kontor/security/SecurityConfig.java index 0bb55a2..120ac5c 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/security/SecurityConfig.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/security/SecurityConfig.java @@ -2,8 +2,8 @@ package de.thpeetz.kontor.security; import com.vaadin.flow.spring.security.VaadinWebSecurity; -import de.thpeetz.kontor.admin.services.KontorUserDetailsService; -import de.thpeetz.kontor.admin.views.LoginView; +import de.thpeetz.kontor.services.KontorUserDetailsService; +import de.thpeetz.kontor.views.admin.LoginView; import java.util.Base64; diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/security/SecurityService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/security/SecurityService.java index 4d17d31..2e5e8fb 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/security/SecurityService.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/security/SecurityService.java @@ -13,7 +13,7 @@ import com.vaadin.flow.server.VaadinServletRequest; import com.vaadin.flow.server.VaadinServletResponse; import com.vaadin.flow.spring.security.AuthenticationContext; -import de.thpeetz.kontor.admin.services.KontorUserDetailsService; +import de.thpeetz.kontor.services.KontorUserDetailsService; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/services/AdminService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/services/AdminService.java new file mode 100644 index 0000000..dda25e6 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/services/AdminService.java @@ -0,0 +1,112 @@ +package de.thpeetz.kontor.services; + +import java.util.Collection; +import java.util.List; + +import de.thpeetz.kontor.data.admin.Assignment; +import de.thpeetz.kontor.data.admin.Permission; +import de.thpeetz.kontor.data.admin.Profile; +import de.thpeetz.kontor.repository.admin.AssignmentRepository; +import de.thpeetz.kontor.repository.admin.PermissionRepository; +import de.thpeetz.kontor.repository.admin.ProfileRepository; + +import org.springframework.stereotype.Service; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +public class AdminService { + + + private final ProfileRepository profileRepository; + private final PermissionRepository permissionRepository; + private final AssignmentRepository assignmentRepository; + + public AdminService(ProfileRepository profileRepository, + PermissionRepository permissionRepository, + AssignmentRepository assignmentRepository) { + this.profileRepository = profileRepository; + this.permissionRepository = permissionRepository; + this.assignmentRepository = assignmentRepository; + } + + public List findAllProfiles() { return profileRepository.findAll(); } + + public Profile getProfile(String userName) { + log.debug("get Profile {}", userName); + return profileRepository.findByUserName(userName); + } + + public List findAllPermissions() { return permissionRepository.findAll(); } + + public Collection findAllPermissions(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return permissionRepository.findAll(); + } else { + return permissionRepository.search(stringFilter); + } + } + + public Permission addPermission(String permissionName) { + Permission permission = permissionRepository.findByName(permissionName); + if (permission == null) { + log.info("Permission {} was not found, will create it.", permissionName); + permission = new Permission(); + permission.setName(permissionName); + permissionRepository.save(permission); + } + return permission; + } + + public void savePermission(Permission permission) { + if (permission == null) { + log.warn("Permission is null. Can't save it."); + } + log.info("savePermission: permission={}", permission); + permissionRepository.save(permission); + } + + public void deletePermission(Permission permission) { + if (permission == null) { + log.warn("Permission is null. Can't delete it."); + return; + } + log.info("deletePermission: permission={}", permission); + permissionRepository.delete(permission); + } + + public List findAllAssignments() { + return assignmentRepository.findAll(); + } + + public void saveAssignment(Assignment assignment) { + if (assignment == null) { + log.warn("Assignment is null. Can't save it."); + return; + } + log.info("saveAssignment: assignment={}", assignment); + assignmentRepository.save(assignment); + } + + public void deleteAssignment(Assignment assignment) { + if (assignment == null) { + log.warn("Assignment is null. Can't delete it."); + return; + } + log.info("deleteAssignment: assignment={}", assignment); + assignmentRepository.delete(assignment); + } + + public String getProfileFullName(String userName) { + log.debug("get Fullname für Profile {}", userName); + Profile profile = profileRepository.findByUserName(userName); + if (profile == null) { + log.info("keinen Eintrag für {} gefunden", userName); + return userName; + } else { + log.info("Voller Name des Profile {}: {}", userName, profile.getFullName()); + return profile.getFullName(); + } + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/services/BookshelfService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/services/BookshelfService.java new file mode 100644 index 0000000..9c1c676 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/services/BookshelfService.java @@ -0,0 +1,130 @@ +package de.thpeetz.kontor.services; + +import java.util.List; + +import de.thpeetz.kontor.data.bookshelf.Article; +import de.thpeetz.kontor.data.bookshelf.Author; +import de.thpeetz.kontor.data.bookshelf.Book; +import de.thpeetz.kontor.data.bookshelf.BookshelfPublisher; +import de.thpeetz.kontor.repository.bookshelf.ArticleAuthorRepository; +import de.thpeetz.kontor.repository.bookshelf.ArticleRepository; +import de.thpeetz.kontor.repository.bookshelf.AuthorRepository; +import de.thpeetz.kontor.repository.bookshelf.BookAuthorRepository; +import de.thpeetz.kontor.repository.bookshelf.BookRepository; +import de.thpeetz.kontor.repository.bookshelf.BookshelfPublisherRepository; + +import org.springframework.stereotype.Service; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +public class BookshelfService { + + private final AuthorRepository authorRepository; + @SuppressWarnings("unused") + private final ArticleAuthorRepository articleAuthorRepository; + private final ArticleRepository articleRepository; + private final BookRepository bookRepository; + @SuppressWarnings("unused") + private final BookAuthorRepository bookAuthorRepository; + private final BookshelfPublisherRepository publisherRepository; + + public BookshelfService(AuthorRepository authorRepository, ArticleAuthorRepository articleAuthorRepository, + ArticleRepository articleRepository, BookRepository bookRepository, + BookAuthorRepository bookAuthorRepository, BookshelfPublisherRepository publisherRepository) { + this.authorRepository = authorRepository; + this.articleAuthorRepository = articleAuthorRepository; + this.articleRepository = articleRepository; + this.bookRepository = bookRepository; + this.bookAuthorRepository = bookAuthorRepository; + this.publisherRepository = publisherRepository; + } + + public List findAllPublishers(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return publisherRepository.findAll(); + } else { + return publisherRepository.search(stringFilter); + } + } + + public BookshelfPublisher findPublisherByName(String publisherName) { + return publisherRepository.findByName(publisherName); + } + + public void deletePublisher(BookshelfPublisher publisher) { + publisherRepository.delete(publisher); + } + + public void savePublisher(BookshelfPublisher publisher) { + if (publisher == null) { + log.warn("Publisher is null. Are you sure you have connected your form to the application?"); + return; + } + publisherRepository.save(publisher); + } + + public List findAllAuthors(String filter) { + if (filter == null || filter.isEmpty()) { + return authorRepository.findAll(); + } else { + return authorRepository.search(filter); + } + } + + public void saveAuthor(Author author) { + if (author == null) { + log.warn("Author is null. Are you sure you have connected your form to the application?"); + return; + } + authorRepository.save(author); + } + + public void deleteAuthor(Author author) { + authorRepository.delete(author); + } + + public List findAllBooks(String filter) { + if (filter == null || filter.isEmpty()) { + return bookRepository.findAll(); + } else { + return bookRepository.search(filter); + } + } + + public void saveBook(Book book) { + if (book == null) { + log.warn("Book is null. Are you sure you have connected your form to the application?"); + return; + } + bookRepository.save(book); + } + + public void deleteBook(Book book) { + BookshelfPublisher publisher = book.getPublisher(); + publisher.getBooks().remove(book); + publisherRepository.save(publisher); + bookRepository.delete(book); + } + + public List
    findAllArticles(String filter) { + if (filter == null || filter.isEmpty()) { + return articleRepository.findAll(); + } else { + return articleRepository.search(filter); + } + } + + public void saveArticle(Article article) { + if (article == null) { + log.warn("Article is null, Are you sure you have connected your form to the application?"); + return; + } + articleRepository.save(article); + } + + public void deleteArticle(Article article) { + articleRepository.delete(article); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/services/CardService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/services/CardService.java new file mode 100644 index 0000000..5f7f048 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/services/CardService.java @@ -0,0 +1,93 @@ +package de.thpeetz.kontor.services; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import de.thpeetz.kontor.data.tysc.Card; +import de.thpeetz.kontor.data.tysc.CardSet; +import de.thpeetz.kontor.data.tysc.Vendor; +import de.thpeetz.kontor.repository.tysc.CardRepository; +import de.thpeetz.kontor.repository.tysc.CardSetRepository; +import de.thpeetz.kontor.repository.tysc.VendorRepository; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +public class CardService { + + private VendorRepository vendorRepository; + + private CardSetRepository cardSetRepository; + + private CardRepository cardRepository; + + public CardService(VendorRepository vendorRepository, CardSetRepository cardSetRepository, CardRepository cardRepository) { + this.vendorRepository = vendorRepository; + this.cardSetRepository = cardSetRepository; + this.cardRepository = cardRepository; + } + + public List findAllVendors(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return vendorRepository.findAll(); + } else { + return vendorRepository.search(stringFilter); + } + } + + public void deleteVendor(Vendor vendor) { + vendorRepository.delete(vendor); + } + + public Vendor saveVendor(Vendor vendor) { + if (vendor == null) { + log.warn("Vendor is null. Are you sure you have connected your form to the application?"); + return null; + } + return vendorRepository.save(vendor); + } + + public List findAllCards(String stringFilter) { + log.info("find cards with filter: {}", stringFilter); + if (stringFilter == null || stringFilter.isEmpty()) { + List cards = cardRepository.findAll(); + log.debug("found {} cards", cards.size()); + return cards; + } else { + return cardRepository.search(stringFilter); + } + } + + public void deleteCard(Card card) { + cardRepository.delete(card); + } + + public Card saveCard(Card card) { + if (card == null) { + log.warn("Card is null. Are you sure you have connected your form to the application?"); + return null; + } + return cardRepository.save(card); + } + + public List findAllCardSets(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return cardSetRepository.findAll(); + } else { + return cardSetRepository.search(stringFilter); + } + } + + public CardSet saveCardSet(CardSet cardSet) { + if (cardSet == null) { + log.warn("CardSet is null. Are you sure you have connected your form to the application?"); + return null; + } + return cardSetRepository.save(cardSet); + } + + public void deleteCardSet(CardSet cardSet) { + cardSetRepository.delete(cardSet); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/services/ComicService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/services/ComicService.java new file mode 100644 index 0000000..fcd082e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/services/ComicService.java @@ -0,0 +1,374 @@ +package de.thpeetz.kontor.services; + +import java.util.List; + +import de.thpeetz.kontor.data.comics.Artist; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.ComicWork; +import de.thpeetz.kontor.data.comics.Issue; +import de.thpeetz.kontor.data.comics.IssueWork; +import de.thpeetz.kontor.data.comics.Publisher; +import de.thpeetz.kontor.data.comics.StoryArc; +import de.thpeetz.kontor.data.comics.TradePaperback; +import de.thpeetz.kontor.data.comics.Volume; +import de.thpeetz.kontor.data.comics.Worktype; +import de.thpeetz.kontor.repository.comics.ArtistRepository; +import de.thpeetz.kontor.repository.comics.ComicRepository; +import de.thpeetz.kontor.repository.comics.ComicWorkRepository; +import de.thpeetz.kontor.repository.comics.IssueRepository; +import de.thpeetz.kontor.repository.comics.IssueWorkRepository; +import de.thpeetz.kontor.repository.comics.PublisherRepository; +import de.thpeetz.kontor.repository.comics.StoryArcRepository; +import de.thpeetz.kontor.repository.comics.TradePaperbackRepository; +import de.thpeetz.kontor.repository.comics.VolumeRepository; +import de.thpeetz.kontor.repository.comics.WorktypeRepository; +import de.thpeetz.kontor.views.common.FilterOption; +import de.thpeetz.kontor.views.common.SearchFilter; + +import org.springframework.stereotype.Service; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +public class ComicService { + + private final PublisherRepository publisherRepository; + private final ComicRepository comicRepository; + private final ArtistRepository artistRepository; + private final IssueRepository issueRepository; + private final StoryArcRepository storyArcRepository; + private final TradePaperbackRepository tradePaperbackRepository; + private final ComicWorkRepository comicWorkRepository; + private final IssueWorkRepository issueWorkRepository; + private final VolumeRepository volumeRepository; + private final WorktypeRepository worktypeRepository; + + public ComicService(PublisherRepository publisherRepository, ComicRepository comicRepository, + ArtistRepository artistRepository, IssueRepository issueRepository, StoryArcRepository storyArcRepository, + TradePaperbackRepository tradePaperbackRepository, ComicWorkRepository comicWorkRepository, IssueWorkRepository issueWorkRepository, + VolumeRepository volumeRepository, WorktypeRepository worktypeRepository) { + + this.publisherRepository = publisherRepository; + this.comicRepository = comicRepository; + this.artistRepository = artistRepository; + this.issueRepository = issueRepository; + this.storyArcRepository = storyArcRepository; + this.tradePaperbackRepository = tradePaperbackRepository; + this.comicWorkRepository = comicWorkRepository; + this.issueWorkRepository = issueWorkRepository; + this.volumeRepository = volumeRepository; + this.worktypeRepository = worktypeRepository; + } + + public List findAllPublishers(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return publisherRepository.findAll(); + } else { + return publisherRepository.search(stringFilter); + } + } + + public Publisher findPublisherByName(String publisherName) { + return publisherRepository.findByName(publisherName); + } + + public void deletePublisher(Publisher publisher) { + publisherRepository.delete(publisher); + } + + public void savePublisher(Publisher publisher) { + if (publisher == null) { + log.warn("Publisher is null. Are you sure you have connected your form to the application?"); + return; + } + publisherRepository.save(publisher); + } + + public List findAllComics(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return comicRepository.findAll(); + } else { + return comicRepository.search(stringFilter); + } + } + public List findAllComicsByFilter(SearchFilter searchFilter) { + if (searchFilter == null) return comicRepository.findAll(); + if (searchFilter.getFilterOptions().isEmpty()) return comicRepository.search(searchFilter.getSearchTerm()); + if (searchFilter.getFilterOptions().size() == 1) { + //TODO use with Java 21 + //FilterOption option = searchFilter.getFilterOptions().getFirst(); + FilterOption option = searchFilter.getFilterOptions().get(0); + if (searchFilter.getSearchTerm() != null && !searchFilter.getSearchTerm().isEmpty()) { + switch (option.getName()) { + case "Bestellung": + return comicRepository.searchAndFilterByCurrentOrder(searchFilter.getSearchTerm(), option.getValue()); + case "Abgeschlossen": + return comicRepository.searchAndFilterByCompleted(searchFilter.getSearchTerm(), option.getValue()); + } + } + switch (option.getName()) { + case "Bestellung": + return comicRepository.findByCurrentOrder(option.getValue()); + case "Abgeschlossen": + return comicRepository.findByCompleted(option.getValue()); + } + } + if (searchFilter.getFilterOptions().size() == 2) { + if (searchFilter.getSearchTerm() != null && !searchFilter.getSearchTerm().isEmpty()) { + return comicRepository.search(searchFilter.getSearchTerm(), + searchFilter.getFilter("Bestellung").getValue(), + searchFilter.getFilter("Abgeschlossen").getValue()); + } + return comicRepository.findByCurrentOrderAndCompleted(searchFilter.getFilter("Bestellung").getValue(), + searchFilter.getFilter("Abgeschlossen").getValue()); + } + return comicRepository.findAll(); + } + + + public Comic findComicByTitle(String title) { + List comics = comicRepository.findByTitle(title); + if (comics.size() == 1) { + return comics.get(0); + } + return null; + } + + public void deleteComic(Comic comic) { + Publisher publisher = comic.getPublisher(); + publisher.getComics().remove(comic); + publisherRepository.save(publisher); + comicRepository.delete(comic); + } + + public void saveComic(Comic comic) { + if (comic == null) { + log.warn("Comic is null. Are you sure you have connected your form to the application?"); + return; + } + comicRepository.save(comic); + } + + public List findAllArtists(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return artistRepository.findAll(); + } else { + return artistRepository.search(stringFilter); + } + } + + public Artist findArtistByName(String artistName) { + if (artistName == null || artistName.isEmpty()) { + return null; + } else { + return artistRepository.findByName(artistName); + } + } + + public void deleteArtist(Artist artist) { + artistRepository.delete(artist); + } + + public void saveArtist(Artist artist) { + if (artist == null) { + log.warn("Artist is null. Are you sure you have connected your form to the application?"); + return; + } + artistRepository.save(artist); + } + + public List findAllIssues() { + return issueRepository.findAll(); + } + + public List findAllIssuesForComic(Comic comic) { + if (comic == null) { + return issueRepository.findAll(); + } else { + log.info("Find issues for Comic: {}", comic); + return issueRepository.findByComic(comic); + } + } + + public void saveIssue(Issue issue) { + if (issue == null) { + log.warn("Issue is null. Are you sure you have connected your form to the application?"); + return; + } + issueRepository.save(issue); + } + + public void deleteIssue(Issue issue) { + issueRepository.delete(issue); + } + + public List findAllStoryArcs() { + return storyArcRepository.findAll(); + } + + public List findAllStoryArcsForComic(Comic comic) { + if (comic == null) { + return storyArcRepository.findAll(); + } else { + log.info("Find Story Arc for Comic: {}", comic); + return storyArcRepository.findByComic(comic); + } + } + + public void saveStoryArc(StoryArc storyArc) { + storyArcRepository.save(storyArc); + } + + public void deleteStoryArc(StoryArc storyArc) { + Comic comic = storyArc.getComic(); + comic.getStoryArcs().remove(storyArc); + comicRepository.save(comic); + storyArcRepository.delete(storyArc); + } + + public List findAllTradePaperbacks(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return tradePaperbackRepository.findAll(); + } else { + return tradePaperbackRepository.search(stringFilter); + } + } + + public void deleteTradePaperBack(TradePaperback tradepaperback) { + tradePaperbackRepository.delete(tradepaperback); + } + + public void saveTradePaperBack(TradePaperback tradepaperback) { + if (tradepaperback == null) { + log.warn("TradePaperBack is null. Are you sure you have connected your form to the application?"); + return; + } + tradePaperbackRepository.save(tradepaperback); + } + + public List findAllComicWorks() { + return comicWorkRepository.findAll(); + } + + public void saveComicWork(ComicWork comicWork) { + if (comicWork == null) { + log.warn("ComicWork is null. Are you sure you have connected your form to the application?"); + return; + } + comicWorkRepository.save(comicWork); + } + + public void deleteComicWork(ComicWork comicWork) { + Comic comic = comicWork.getComic(); + comic.getComicWorks().remove(comicWork); + comicRepository.save(comic); + Artist artist = comicWork.getArtist(); + artist.getComicWorks().remove(comicWork); + artistRepository.save(artist); + Worktype worktype = comicWork.getWorkType(); + worktype.getComicWorks().remove(comicWork); + worktypeRepository.save(worktype); + comicWorkRepository.delete(comicWork); + } + + public List findAllIssueWorks() { + return issueWorkRepository.findAll(); + } + + public void saveIssueWork(IssueWork issueWork) { + if (issueWork == null) { + log.warn("IssueWork is null. Are you sure you have connected your form to the application?"); + return; + } + issueWorkRepository.save(issueWork); + } + + public void deleteIssueWork(IssueWork issueWork) { + Issue issue = issueWork.getIssue(); + issue.getIssueWorks().remove(issueWork); + issueRepository.save(issue); + Artist artist = issueWork.getArtist(); + artist.getIssueWorks().remove(issueWork); + artistRepository.save(artist); + Worktype worktype = issueWork.getWorkType(); + worktype.getIssueWorks().remove(issueWork); + worktypeRepository.save(worktype); + issueWorkRepository.delete(issueWork); + } + + public List findAllVolumes() { + return volumeRepository.findAll(); + } + + public List findAllVolumesForComic(Comic comic) { + if (comic == null) { + return volumeRepository.findAll(); + } else { + log.info("Find Volume for Comic: {}", comic); + return volumeRepository.findByComic(comic); + } + } + + public void saveVolume(Volume volume) { + if (volume == null) { + log.warn("Volume is null. Are you sure you have connected your form to the application?"); + return; + } + volumeRepository.save(volume); + } + + public void deleteVolume(Volume volume) { + Comic comic = volume.getComic(); + comic.getVolumes().remove(volume); + comicRepository.save(comic); + volumeRepository.delete(volume); + } + + public List findAllWorktypes(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return worktypeRepository.findAll(); + } else { + return worktypeRepository.search(stringFilter); + } + } + + public Worktype findWorktypeByName(String worktypeName) { + if (worktypeName == null || worktypeName.isEmpty()) { + return null; + } else { + return worktypeRepository.findByName(worktypeName); + } + } + + public void saveWorktype(Worktype worktype) { + if (worktype == null) { + log.warn("Worktype is null. Are you sure you have connected your form to the application?"); + return; + } + worktypeRepository.save(worktype); + } + + public void deleteWorktype(Worktype worktype) { + List comicWorks = worktype.getComicWorks(); + List issueWorks = worktype.getIssueWorks(); + if (comicWorks == null) { + log.warn("reference to ComicWork is null"); + } else { + log.info("found {} references to ComicWork", comicWorks.size()); + comicWorks.forEach(comicWork -> { + comicWork.setWorkType(null); + }); + } + if (issueWorks == null) { + log.warn("reference to ComicWork is null"); + } else { + log.info("found {} references to IssueWork", issueWorks.size()); + issueWorks.forEach(issueWork -> { + issueWork.setWorkType(null); + }); + } + log.info("delete Worktype: {}", worktype); + worktypeRepository.delete(worktype); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/services/DataManagementService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/services/DataManagementService.java new file mode 100644 index 0000000..f8e519b --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/services/DataManagementService.java @@ -0,0 +1,32 @@ +package de.thpeetz.kontor.services; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +@Slf4j +@Service +public class DataManagementService { + + @Autowired + SportService sportService; + + public DataManagementService() { + + } + + public String getEntry(String nodeName, Map fields) { + AtomicReference status = new AtomicReference<>("unknown"); + switch (nodeName) { + case "sport": + status.set(sportService.importData(fields)); + default: + log.debug("import for {} not implemented", nodeName); + break; + } + return status.get(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/services/KontorUserDetailsService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/services/KontorUserDetailsService.java new file mode 100644 index 0000000..b4d04bb --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/services/KontorUserDetailsService.java @@ -0,0 +1,135 @@ +package de.thpeetz.kontor.services; + +import de.thpeetz.kontor.data.admin.Assignment; +import de.thpeetz.kontor.data.admin.Permission; +import de.thpeetz.kontor.data.admin.Profile; +import de.thpeetz.kontor.repository.admin.AssignmentRepository; +import de.thpeetz.kontor.repository.admin.PermissionRepository; +import de.thpeetz.kontor.repository.admin.ProfileRepository; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.math.BigInteger; +import java.security.SecureRandom; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@Service("userDetailsService") +public class KontorUserDetailsService implements UserDetailsService { + + private static final SecureRandom random = new SecureRandom(); + + @Autowired + private ProfileRepository profileRepository; + + @Autowired + private PermissionRepository permissionRepository; + + @Autowired + private AssignmentRepository assignmentRepository; + + public Collection findAllProfiles(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return profileRepository.findAll(); + } else { + return profileRepository.search(stringFilter); + } + } + + public void saveProfile(Profile profile) { + if (profile == null) { + log.warn("Profile is null. Can't save it."); + return; + } + log.info("saveProfile: profile={}", profile); + profileRepository.save(profile); + } + + public void saveProfile(Profile profile, List permissions) { + if (profile == null) { + log.warn("Profile is null. Can't save it."); + return; + } + log.info("First save Profile: {}", profile); + profile = profileRepository.save(profile); + List copy = permissions.stream().collect(Collectors.toList()); + List assignments = profile.getAssignments(); + if (assignments != null) { + assignments.forEach(assignment -> { + if (permissions.contains(assignment.getPermission())) { + log.info("Permission {} already assigned", assignment.getPermission()); + copy.remove(assignment.getPermission()); + } else { + log.info("Permission {} has to be removed", assignment.getPermission()); + assignmentRepository.delete(assignment); + } + }); + } + log.info("remaining roles: {}", copy); + for (Permission permission : copy) { + Assignment assignment = new Assignment(); + assignment.setProfile(profile); + assignment.setPermission(permission); + assignmentRepository.save(assignment); + } + } + + public void deleteProfile(Profile profile) { + if (profile == null) { + log.warn("Profile is null. Can't delete it."); + return; + } + log.info("deleteProfile: profile={}", profile); + profileRepository.delete(profile); + } + + @Override + public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { + + log.info("loadUserByUsername: userName={}", userName); + Profile profile = profileRepository.findByUserName(userName); + if (profile == null) { + log.info("User not found"); + return null; + } + + Collection authorities = getAuthorities(profile); + log.info("Profile {} hat Permissions: {}", userName, authorities); + return new org.springframework.security.core.userdetails.User(profile.getUserName(), profile.getPassword(), + authorities); + } + + private Collection getAuthorities(Profile profile) { + return assignmentRepository.findByProfile(profile).stream() + .map(assignment -> assignment.getPermission().getName()) + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + } + + public String getRememberedUser(String id) { + log.info("getRememberedUser: id={}", id); + return "admin"; + } + + public String rememberUser(String username) { + String randomId = new BigInteger(130, random).toString(32); + log.info("rememberUser: username={}", username); + return randomId; + } + + public void removeRememberedUser(String id) { + log.info("removeRememberedUser: id={}", id); + } + + public List findAllPermissions() { + return permissionRepository.findAll(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/services/MailService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/services/MailService.java new file mode 100644 index 0000000..1b77d82 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/services/MailService.java @@ -0,0 +1,24 @@ +package de.thpeetz.kontor.services; + +import de.thpeetz.kontor.data.mailclient.MailAccount; +import de.thpeetz.kontor.repository.admin.MailAccountRepository; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class MailService { + + private final MailAccountRepository mailAccountRepository; + + public MailService(MailAccountRepository mailAccountRepository) { + this.mailAccountRepository = mailAccountRepository; + } + + public List findAllMailAccounts() { + return mailAccountRepository.findAll(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/services/MediaArticleService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/services/MediaArticleService.java new file mode 100644 index 0000000..ba51a6c --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/services/MediaArticleService.java @@ -0,0 +1,42 @@ +package de.thpeetz.kontor.services; + +import de.thpeetz.kontor.data.media.MediaArticle; +import de.thpeetz.kontor.repository.media.MediaArticleRepository; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +public class MediaArticleService { + + private final MediaArticleRepository mediaArticleRepository; + + public MediaArticleService(MediaArticleRepository mediaArticleRepository) { + this.mediaArticleRepository = mediaArticleRepository; + } + + public List findAllMediaArticles(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + log.info("Found {} entries", mediaArticleRepository.count()); + return mediaArticleRepository.findAll(); + } else { + List results = mediaArticleRepository.search(stringFilter); + log.info("Found {} entries", results.size()); + return results; + } + } + + public void saveMediaArticle(MediaArticle mediaArticle) { + if (mediaArticle == null) { + log.warn("MediaArticle is null. Are you sure you have connected your form to the application?"); + return; + } + mediaArticleRepository.save(mediaArticle); + } + + public void deleteMediaArticle(MediaArticle mediaArticle) { + mediaArticleRepository.delete(mediaArticle); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/services/MediaFileService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/services/MediaFileService.java new file mode 100644 index 0000000..d976ff8 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/services/MediaFileService.java @@ -0,0 +1,138 @@ +package de.thpeetz.kontor.services; + +import de.thpeetz.kontor.data.media.MediaActor; +import de.thpeetz.kontor.data.media.MediaActorFile; +import de.thpeetz.kontor.data.media.MediaFile; +import de.thpeetz.kontor.repository.media.MediaActorFileRepository; +import de.thpeetz.kontor.repository.media.MediaActorRepository; +import de.thpeetz.kontor.repository.media.MediaFileRepository; +import de.thpeetz.kontor.views.common.SearchFilter; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +import org.springframework.stereotype.Service; + + +@Slf4j +@Service +public class MediaFileService { + + private final MediaFileRepository mediaFileRepository; + private final MediaActorRepository mediaActorRepository; + private final MediaActorFileRepository mediaActorFileRepository; + + public MediaFileService(MediaFileRepository mediaFileRepository, MediaActorRepository mediaActorRepository, MediaActorFileRepository mediaActorFileRepository) { + this.mediaFileRepository = mediaFileRepository; + this.mediaActorRepository = mediaActorRepository; + this.mediaActorFileRepository = mediaActorFileRepository; + } + + public List findAllMediaFilesByString(String stringFilter) { + List results; + if (stringFilter == null || stringFilter.isEmpty()) { + results = mediaFileRepository.findAll(); + } else { + results = mediaFileRepository.search(stringFilter); + } + log.debug("Found " + results.size() + " entries"); + return results; + } + + public MediaFile findAllMediaFilesByUrl(String url) { + return mediaFileRepository.findByUrl(url); + } + + public List findAllMediaFiles(SearchFilter searchFilter) { + if (searchFilter == null) { + return mediaFileRepository.findAll(); + } else { + if (searchFilter.getSearchTerm() != null && searchFilter.getFilterOptions().isEmpty()) { + log.info("find MediaFiles by using searchTerm: {}", searchFilter.getSearchTerm()); + List results = mediaFileRepository.search(searchFilter.getSearchTerm()); + log.info("found {} entries", results.size()); + return results; + } + if (searchFilter.getFilterOptions().size() == 1) { + log.info("using searchFilter: {}", searchFilter); + String filter = searchFilter.getFilterOptions().get(0).getName(); + Boolean filterValue = searchFilter.getFilterOptions().get(0).getValue(); + if (filter == "Überprüfung") { + List results = mediaFileRepository.findByReview(filterValue); + log.info("found {} entries", results.size()); + return results; + } + if (filter == "Download") { + List results = mediaFileRepository.findByShouldDownload(filterValue); + log.info("found {} entries", results.size()); + return results; + } + } + if (searchFilter.getFilterOptions().size() == 2) { + log.info("using searchFilter: {}", searchFilter); + List results = mediaFileRepository.search(searchFilter.getSearchTerm(), searchFilter.getFilterOptions().get(0).getValue(), searchFilter.getFilterOptions().get(1).getValue()); + log.info("found {} entries", results.size()); + return results; + } + } + log.info("noch filter used"); + return mediaFileRepository.findAll(); + } + + public MediaFile saveMediaFile(MediaFile mediaFile) { + if (mediaFile == null) { + log.warn("MediaFile is null. Are you sure you have connected your form to the application?"); + return null; + } + return mediaFileRepository.save(mediaFile); + } + + public void deleteMediaFile(MediaFile mediaFile) { + mediaFileRepository.delete(mediaFile); + } + + public List findAllMediaActors(String stringFilter) { + List results; + if (stringFilter == null || stringFilter.isEmpty()) { + results = mediaActorRepository.findAll(); + } else { + results = mediaActorRepository.search(stringFilter); + } + log.debug("Found " + results.size() + " entries"); + return results; + } + + public void saveMediaActor(MediaActor mediaActor) { + if (mediaActor == null) { + log.warn("MediaActor is null. Are you sure you have connected your form to the application?"); + return; + } + mediaActorRepository.save(mediaActor); + } + + public void deleteMediaActor(MediaActor mediaActor) { + mediaActorRepository.delete(mediaActor); + } + + public List findAllMediaActorFiles() { + return mediaActorFileRepository.findAll(); + } + + public void saveMediaActorFile(MediaActorFile mediaActorFile) { + if (mediaActorFile == null){ + log.warn("MediaActorFile is null. Are you sure you have connected your form to the application?"); + return; + } + mediaActorFileRepository.save(mediaActorFile); + } + + public void deleteMediaActorFile(MediaActorFile mediaActorFile) { + MediaFile mediaFile = mediaActorFile.getMedia_file(); + mediaFile.getMediaActorFiles().remove(mediaActorFile); + mediaFileRepository.save(mediaFile); + MediaActor mediaActor = mediaActorFile.getMedia_actor(); + mediaActor.getMediaActorFiles().remove(mediaActorFile); + mediaActorRepository.save(mediaActor); + mediaActorFileRepository.delete(mediaActorFile); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/services/MediaLofiService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/services/MediaLofiService.java new file mode 100644 index 0000000..adb76fb --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/services/MediaLofiService.java @@ -0,0 +1,86 @@ +package de.thpeetz.kontor.services; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import de.thpeetz.kontor.data.media.MediaLofi; +import de.thpeetz.kontor.repository.media.MediaLofiRepository; +import de.thpeetz.kontor.views.common.SearchFilter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +public class MediaLofiService { + + private final MediaLofiRepository mediaLofiRepository; + + public MediaLofiService(MediaLofiRepository mediaLofiRepository) { + this.mediaLofiRepository = mediaLofiRepository; + } + + public List findAllMediaLofisByString(String stringFilter) { + List results; + if (stringFilter == null || stringFilter.isEmpty()) { + results = mediaLofiRepository.findAll(); + } else { + results = mediaLofiRepository.search(stringFilter); + } + log.debug("Found " + results.size() + " entries"); + return results; + } + + public MediaLofi findAllMediaLofiByUrl(String url) { + return mediaLofiRepository.findByUrl(url); + } + + public List findAllMediaLofis(SearchFilter searchFilter) { + if (searchFilter == null) { + return mediaLofiRepository.findAll(); + } else { + if (searchFilter.getSearchTerm() != null && searchFilter.getFilterOptions().isEmpty()) { + log.info("find MediaFiles by using searchTerm: {}", searchFilter.getSearchTerm()); + List results = mediaLofiRepository.search(searchFilter.getSearchTerm()); + log.info("found {} entries", results.size()); + return results; + } + if (searchFilter.getFilterOptions().size() == 1) { + log.info("using searchFilter: {}", searchFilter); + String filter = searchFilter.getFilterOptions().get(0).getName(); + Boolean filterValue = searchFilter.getFilterOptions().get(0).getValue(); + if (filter == "Überprüfung") { + List results = mediaLofiRepository.findByReview(filterValue); + log.info("found {} entries", results.size()); + return results; + } + if (filter == "Download") { + List results = mediaLofiRepository.findByShouldDownload(filterValue); + log.info("found {} entries", results.size()); + return results; + } + } + if (searchFilter.getFilterOptions().size() == 2) { + log.info("using searchFilter: {}", searchFilter); + List results = mediaLofiRepository.search(searchFilter.getSearchTerm(), + searchFilter.getFilterOptions().get(0).getValue(), + searchFilter.getFilterOptions().get(1).getValue()); + log.info("found {} entries", results.size()); + return results; + } + } + log.info("noch filter used"); + return mediaLofiRepository.findAll(); + } + + public MediaLofi saveMediaLofi(MediaLofi mediaLofi) { + if (mediaLofi == null) { + log.warn("MediaLofi is null. Are you sure you have connected your form to the application?"); + return null; + } + return mediaLofiRepository.save(mediaLofi); + } + + public void deleteMediaLofi(MediaLofi mediaLofi) { + mediaLofiRepository.delete(mediaLofi); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/services/MediaVideoService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/services/MediaVideoService.java new file mode 100644 index 0000000..ad58949 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/services/MediaVideoService.java @@ -0,0 +1,39 @@ +package de.thpeetz.kontor.services; + +import de.thpeetz.kontor.data.media.MediaVideo; +import de.thpeetz.kontor.repository.media.MediaVideoRepository; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +public class MediaVideoService { + + private final MediaVideoRepository mediaVideoRepository; + + public MediaVideoService(MediaVideoRepository mediaVideoRepository) { + this.mediaVideoRepository = mediaVideoRepository; + } + + public List findAllMediaVideos(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return mediaVideoRepository.findAll(); + } else { + return mediaVideoRepository.search(stringFilter); + } + } + + public MediaVideo saveMediaVideo(MediaVideo mediaVideo) { + if (mediaVideo == null) { + log.warn("MediaFile is null. Are you sure you have connected your form to the application?"); + return null; + } + return mediaVideoRepository.save(mediaVideo); + } + + public void deleteMediaVideo(MediaVideo mediaVideo) { + mediaVideoRepository.delete(mediaVideo); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/services/SportService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/services/SportService.java new file mode 100644 index 0000000..37c4885 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/services/SportService.java @@ -0,0 +1,194 @@ +package de.thpeetz.kontor.services; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import de.thpeetz.kontor.data.tysc.FieldPosition; +import de.thpeetz.kontor.data.tysc.Player; +import de.thpeetz.kontor.data.tysc.Rooster; +import de.thpeetz.kontor.data.tysc.Sport; +import de.thpeetz.kontor.data.tysc.Team; +import de.thpeetz.kontor.repository.tysc.FieldPositionRepository; +import de.thpeetz.kontor.repository.tysc.PlayerRepository; +import de.thpeetz.kontor.repository.tysc.RoosterRepository; +import de.thpeetz.kontor.repository.tysc.SportRepository; +import de.thpeetz.kontor.repository.tysc.TeamRepository; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +public class SportService { + + @Autowired + private SportRepository sportRepository; + + @Autowired + private TeamRepository teamRepository; + + @Autowired + private FieldPositionRepository fieldPositionRepository; + + @Autowired + private PlayerRepository playerRepository; + + @Autowired + private RoosterRepository roosterRepository; + + public List findAllSports(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return sportRepository.findAll(); + } else { + return sportRepository.search(stringFilter); + } + } + + public void deleteSport(Sport sport) { + sportRepository.delete(sport); + } + + public Sport saveSport(Sport sport) { + if (sport == null) { + log.warn("Sport is null. Are you sure you have connected your form to the application?"); + return null; + } + return sportRepository.save(sport); + } + + public List findAllPlayers(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return playerRepository.findAll(); + } else { + return playerRepository.search(stringFilter); + } + } + + public Player savePlayer(Player player) { + if (player == null) { + log.warn("Player is null. Are you sure you have connected yout form to the application?"); + return null; + } + return playerRepository.save(player); + } + + public void deletePlayer(Player player) { + playerRepository.delete(player); + } + + public List findAllTeams(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return teamRepository.findAll(); + } else { + return teamRepository.search(stringFilter); + } + } + + public void deleteTeam(Team team) { + teamRepository.delete(team); + } + + public void saveTeam(Team team) { + if (team == null) { + log.warn("Team is null. Are you sure you have connected your form to the application?"); + return; + } + teamRepository.save(team); + } + + public List findAllPositions(String stringFilter) { + if (stringFilter == null || stringFilter.isEmpty()) { + return fieldPositionRepository.findAll(); + } else { + return fieldPositionRepository.search(stringFilter); + } + } + + public List findAllPositionsForSport(Sport sport) { + if (sport == null) { + return fieldPositionRepository.findAll(); + } else { + log.info("Find positions for Sport: {}", sport); + return fieldPositionRepository.findBySport(sport); + } + } + + public void savePosition(FieldPosition position) { + if (position == null) { + log.warn("Position is null. Are you sure you have connected your form to the application?"); + return; + } + fieldPositionRepository.save(position); + } + + public void deletePosition(FieldPosition position) { + fieldPositionRepository.delete(position); + } + + public List findAllRoosters() { + return roosterRepository.findAll(); + } + + public Rooster findRoosterByFields(Team team, Player player, FieldPosition position, Integer year) { + return roosterRepository.findByReferences(player, team, position, year); + } + + public void saveRooster(Rooster rooster) { + if (rooster == null) { + log.warn(""); + return; + } + roosterRepository.save(rooster); + } + + public void deleteRooster(Rooster rooster) { + roosterRepository.delete(rooster); + } + + public String importData(Map fields) { + AtomicReference status = new AtomicReference<>("unknown"); + String id = fields.get("id"); + Optional optional = sportRepository.findById(id); + if (optional.isEmpty()) { + log.info(" not found: {} with {}", id, fields); + status.set(id + "not found"); + Sport checkExisting = sportRepository.findByName(fields.get("name")); + if (checkExisting != null) { + log.info("entry already there with different id ({}), will be deleted", checkExisting.getId()); + deleteSport(checkExisting); + } + Sport sport = new Sport(); + sport.setId(id); + sport.setName(fields.get("name")); + sportRepository.save(sport); + } else { + optional.ifPresent( entry -> { + log.info(" found: {}", entry.getName()); + String updateStatus = updateSportFields(entry, fields); + sportRepository.save(entry); + status.set(updateStatus); + }); + } + return status.get(); + } + + private String updateSportFields(Sport sport, Map fields) { + StringBuilder status = new StringBuilder(); + for (Map.Entry entry : fields.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + switch (key) { + case "id", "created_date", "last_modified_date", "version": + break; + case "table_name": + status.append(sport.updateName(value)); + default: + log.info("field {} is unknown for table {}", key, sport.getClass().getName()); + } + } + return status.toString(); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleAdmin.java b/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleAdmin.java new file mode 100644 index 0000000..af20df8 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleAdmin.java @@ -0,0 +1,127 @@ +package de.thpeetz.kontor.setup; + +import de.thpeetz.kontor.data.admin.Assignment; +import de.thpeetz.kontor.data.admin.Permission; +import de.thpeetz.kontor.data.admin.Profile; +import de.thpeetz.kontor.data.mailclient.MailAccount; +import de.thpeetz.kontor.properties.MailProperties; +import de.thpeetz.kontor.repository.admin.AssignmentRepository; +import de.thpeetz.kontor.repository.admin.MailAccountRepository; +import de.thpeetz.kontor.repository.admin.ProfileRepository; +import de.thpeetz.kontor.services.AdminService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.List; + +@Slf4j +@Component +public class SetupModuleAdmin implements ApplicationListener { + boolean alreadySetup = false; + + @Autowired + private ProfileRepository profileRepository; + + @Autowired + private AssignmentRepository assignmentRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Autowired + private MailAccountRepository mailAccountRepository; + + @Autowired + private MailProperties mailProperties; + + @Autowired + private AdminService adminService; + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + if (alreadySetup) { + return; + } + + // Create initial roles and users + Permission adminPermission = adminService.addPermission("ROLE_ADMIN"); + Permission userPermission = adminService.addPermission("ROLE_USER"); + List profiles = profileRepository.findAll(); + if (profiles.isEmpty()) { + Profile adminProfile = initAdminUser(); + initAssignments(adminPermission, adminProfile); + initAssignments(userPermission, adminProfile); + } + log.info("MailProperties: {}", mailProperties); + initMail(mailProperties); + } + + private void initMail(MailProperties mailProperties) { + log.info("initMail: Host {} with User {}", mailProperties.getHost(), mailProperties.getUserName()); + if (mailProperties.getHost() == null || mailProperties.getHost().isEmpty()) { + return; + } + boolean addMailAccount = false; + List mailAccounts = mailAccountRepository.findAll(); + if (mailAccounts.isEmpty()) { + addMailAccount = true; + } + for (MailAccount mailAccount : mailAccounts) { + String accountUser = mailAccount.getUserName(); + String propertyUser = mailProperties.getUserName(); + String accountHost = mailAccount.getHost(); + String propertyHost = mailProperties.getHost(); + if (propertyHost.equals(accountHost) && propertyUser.equals(accountUser)) { + log.debug("already configured: {}", mailAccount); + } else { + addMailAccount = true; + } + } + if (addMailAccount) { + log.info("add Mail Account: {}", mailProperties); + MailAccount mailAccount = new MailAccount(); + mailAccount.setProtocol(mailProperties.getProtocol()); + mailAccount.setHost(mailProperties.getHost()); + mailAccount.setPort(mailProperties.getPort()); + mailAccount.setUserName(mailProperties.getUserName()); + mailAccount.setPassword(mailProperties.getPassword()); + mailAccount.setStartTls(mailProperties.getStartTls()); + mailAccountRepository.save(mailAccount); + } + } + + private void initAssignments(Permission permission, Profile profile) { + log.info("initAssignments: Permission {} for Profile {}", permission.getName(), profile.getUserName()); + Collection configuredRoles = assignmentRepository.findByProfile(profile); + if (configuredRoles.stream().anyMatch(assignment -> assignment.getPermission().getId().equals(permission.getId()))) { + log.info("Permission {} already defined", permission.getName()); + } else { + log.info("add Permission {} to Profile {}", permission.getName(), profile.getUserName()); + final Assignment assignment = new Assignment(); + assignment.setProfile(profile); + assignment.setPermission(permission); + assignmentRepository.save(assignment); + } + } + + private Profile initAdminUser() { + log.info("initAdminUser"); + Profile admin = profileRepository.findByUserName("admin"); + if (admin == null) { + log.info("Profile admin not found, will be created."); + admin = new Profile(); + admin.setFirstName("Admin"); + admin.setLastName("Administrator"); + admin.setUserName("admin"); + admin.setEmail("admin@example.org"); + admin.setPassword(passwordEncoder.encode("admin")); + profileRepository.save(admin); + } + return admin; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleBookshelf.java b/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleBookshelf.java new file mode 100644 index 0000000..028fed4 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleBookshelf.java @@ -0,0 +1,23 @@ +package de.thpeetz.kontor.setup; + +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.stereotype.Component; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +public class SetupModuleBookshelf implements ApplicationListener { + + boolean alreadySetup = false; + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + if (alreadySetup) { + log.info("SetupModuleBookshelf already executed, skipping"); + return; + } + log.info("Set up Bookshelf data"); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleComics.java b/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleComics.java new file mode 100644 index 0000000..33fc5af --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleComics.java @@ -0,0 +1,23 @@ +package de.thpeetz.kontor.setup; + +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.stereotype.Component; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +public class SetupModuleComics implements ApplicationListener { + + boolean alreadySetup = false; + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + if (alreadySetup) { + log.info("SetupModuleComics already executed, skipping"); + return; + } + log.info("Set up Comics data"); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleMedia.java b/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleMedia.java new file mode 100644 index 0000000..5cd835e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleMedia.java @@ -0,0 +1,30 @@ +package de.thpeetz.kontor.setup; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.stereotype.Component; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.services.AdminService; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +public class SetupModuleMedia implements ApplicationListener { + + boolean alreadySetup = false; + + @Autowired + private AdminService adminService; + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + adminService.addPermission(MediaConstants.MEDIA_ROLE); + if (alreadySetup) { + log.info("SetupModuleMedia already executed, skipping"); + return; + } + log.info("Set up Media data"); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleTysc.java b/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleTysc.java new file mode 100644 index 0000000..66c6936 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/setup/SetupModuleTysc.java @@ -0,0 +1,25 @@ +package de.thpeetz.kontor.setup; + + +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.stereotype.Component; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +public class SetupModuleTysc implements ApplicationListener { + + boolean alreadySetup = false; + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + if (alreadySetup) { + log.info("SetupDataLoader(TYSC) already executed, skipping"); + return; + } + log.info("Setp up TYSC data"); + alreadySetup = true; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/SetupModuleTysc.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/SetupModuleTysc.java deleted file mode 100644 index e80ad67..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/SetupModuleTysc.java +++ /dev/null @@ -1,65 +0,0 @@ -package de.thpeetz.kontor.tysc; - -import de.thpeetz.kontor.tysc.data.Card; -import de.thpeetz.kontor.tysc.data.CardSet; -import de.thpeetz.kontor.tysc.data.Player; -import de.thpeetz.kontor.tysc.data.Rooster; -import de.thpeetz.kontor.tysc.data.Sport; -import de.thpeetz.kontor.tysc.data.Team; -import de.thpeetz.kontor.tysc.data.Vendor; -import de.thpeetz.kontor.tysc.repository.CardRepository; -import de.thpeetz.kontor.tysc.repository.CardSetRepository; -import de.thpeetz.kontor.tysc.repository.FieldPositionRepository; -import de.thpeetz.kontor.tysc.repository.PlayerRepository; -import de.thpeetz.kontor.tysc.repository.RoosterRepository; -import de.thpeetz.kontor.tysc.repository.SportRepository; -import de.thpeetz.kontor.tysc.repository.TeamRepository; -import de.thpeetz.kontor.tysc.repository.VendorRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.stereotype.Component; - -import de.thpeetz.kontor.tysc.data.FieldPosition; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Component -public class SetupModuleTysc implements ApplicationListener { - - boolean alreadySetup = false; - - @Autowired - private SportRepository sportRepository; - - @Autowired - private TeamRepository teamRepository; - - @Autowired - private VendorRepository vendorRepository; - - @Autowired - private FieldPositionRepository fieldPositionRepository; - - @Autowired - private PlayerRepository playerRepository; - - @Autowired - private CardSetRepository cardSetRepository; - - @Autowired - private RoosterRepository roosterRepository; - - @Autowired - private CardRepository cardRepository; - - @Override - public void onApplicationEvent(ContextRefreshedEvent event) { - if (alreadySetup) { - log.info("SetupDataLoader(TYSC) already executed, skipping"); - return; - } - log.info("Setp up TYSC data"); - alreadySetup = true; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/TyscConstants.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/TyscConstants.java deleted file mode 100644 index cc41c93..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/TyscConstants.java +++ /dev/null @@ -1,88 +0,0 @@ -package de.thpeetz.kontor.tysc; - -import com.vaadin.flow.component.icon.VaadinIcon; -import com.vaadin.flow.component.sidenav.SideNavItem; -import com.vaadin.flow.router.RouterLink; - -import de.thpeetz.kontor.tysc.views.CardSetView; -import de.thpeetz.kontor.tysc.views.CardView; -import de.thpeetz.kontor.tysc.views.PlayerView; -import de.thpeetz.kontor.tysc.views.PositionView; -import de.thpeetz.kontor.tysc.views.RoosterView; -import de.thpeetz.kontor.tysc.views.SportView; -import de.thpeetz.kontor.tysc.views.TeamView; -import de.thpeetz.kontor.tysc.views.VendorView; - -/** - * The {@code TyscConstants} class contains constant values related to tysc. - */ -public class TyscConstants { - - public static final String TYSC = "TradeYourSportsCards"; - public static final String TYSC_ROLE = "ROLE_TYSC"; - public static final String VENDOR = "Vendor"; - public static final String VENDOR_ROUTE = "tysc/vendor"; - public static final String CARDSET = "Card Set"; - public static final String CARDSET_ROUTE = "tysc/cardset"; - public static final String CARD = "Card"; - public static final String CARD_ROUTE = "tysc/card"; - public static final String SPORT = "Sport"; - public static final String SPORT_ROUTE = "tysc/sport"; - public static final String TEAM = "Team"; - public static final String TEAM_ROUTE = "tysc/team"; - public static final String POSITION = "Position"; - public static final String POSITION_ROUTE = "tysc/position"; - public static final String PLAYER = "Player"; - public static final String PLAYER_ROUTE = "tysc/player"; - public static final String ROOSTER = "Rooster"; - public static final String ROOSTER_ROUTE = "tysc/rooster"; - - public static RouterLink getSportLink() { - return new RouterLink(SPORT, SportView.class); - } - - public static RouterLink getTeamLink() { - return new RouterLink(TEAM, TeamView.class); - } - - public static RouterLink getPlayerLink() { - return new RouterLink(PLAYER, PlayerView.class); - } - - public static RouterLink getPositionLink() { - return new RouterLink(POSITION, PositionView.class); - } - - public static RouterLink getRoosterLink() { - return new RouterLink(ROOSTER, RoosterView.class); - } - - public static RouterLink getVendorLink() { - return new RouterLink(VENDOR, VendorView.class); - } - - public static RouterLink getCardSetLink() { - return new RouterLink(CARDSET, CardSetView.class); - } - - public static RouterLink getCardLink() { - return new RouterLink(CARD, CardView.class); - } - - public static SideNavItem getTyscNavigation() { - SideNavItem tysc = new SideNavItem(TYSC, VENDOR_ROUTE, VaadinIcon.ARCHIVE.create()); - tysc.addItem(new SideNavItem(SPORT, SportView.class)); - tysc.addItem(new SideNavItem(TEAM, TeamView.class)); - tysc.addItem(new SideNavItem(PLAYER, PlayerView.class)); - tysc.addItem(new SideNavItem(POSITION, PositionView.class)); - tysc.addItem(new SideNavItem(ROOSTER, RoosterView.class)); - tysc.addItem(new SideNavItem(CARDSET, CardSetView.class)); - tysc.addItem(new SideNavItem(CARD, CardView.class)); - tysc.addItem(new SideNavItem(VENDOR, VendorView.class)); - return tysc; - } - - private TyscConstants() { - // private constructor to hide the implicit public one - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Card.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Card.java deleted file mode 100644 index 8fa3486..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Card.java +++ /dev/null @@ -1,62 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.Index; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@ToString -@EqualsAndHashCode(callSuper=false) -@Entity -@Table(indexes = {@Index(columnList = "cardNumber, year")}, - uniqueConstraints = {@UniqueConstraint(columnNames = { "cardNumber", "year", "vendor_id", "cardSet_id" })} -) -public class Card extends AbstractEntity { - - private int cardNumber; - - private int year; - - @ManyToOne - @JoinColumn(name = "vendor_id") - @NotNull - @JsonIgnoreProperties({ "cards" }) - private Vendor vendor; - - @ManyToOne - @JoinColumn(name = "cardSet_id") - @NotNull - @JsonIgnoreProperties({ "cards" }) - private CardSet cardSet; - - @ManyToOne - @JoinColumn(name = "rooster_id") - @NotNull - @JsonIgnoreProperties({ "cards" }) - private Rooster rooster; - - public String getVendorName() { - return this.vendor.getName(); - } - - public String getCardSetName() { - return this.cardSet.getName(); - } - - public String getPlayerName() { - return this.rooster.getPlayer().getFullName(); - } -} - diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/CardSet.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/CardSet.java deleted file mode 100644 index 8bd700d..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/CardSet.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.Index; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@ToString -@EqualsAndHashCode(callSuper=false) -@Entity -@Table(indexes = {@Index(columnList = "name, vendor_id")}, - uniqueConstraints = {@UniqueConstraint(columnNames = { "name", "vendor_id" })} -) -public class CardSet extends AbstractEntity { - - @NotEmpty - private String name; - - @ManyToOne() - @JoinColumn(name = "vendor_id") - @NotNull - @JsonIgnoreProperties({ "cardSets" }) - private Vendor vendor; - - private boolean parallelSet = false; - - private boolean insertSet = false; - - public String getVendorName() { - return vendor.getName(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/FieldPosition.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/FieldPosition.java deleted file mode 100644 index a806e70..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/FieldPosition.java +++ /dev/null @@ -1,52 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.Index; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@ToString -@EqualsAndHashCode(callSuper=false) -@Entity -@Table(indexes = {@Index(columnList = "name, sport_id")}, - uniqueConstraints = { - @UniqueConstraint(columnNames = { "name", "sport_id" }), - @UniqueConstraint(columnNames = { "shortName", "sport_id" }) - } -) -public class FieldPosition extends AbstractEntity { - - @NotEmpty - private String name; - - @NotEmpty - private String shortName; - - @ManyToOne - @JoinColumn(name = "sport_id") - @NotNull - @JsonIgnoreProperties({ "positions" }) - private Sport sport; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "position") - @Nullable - private List roosters; -} \ No newline at end of file diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Player.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Player.java deleted file mode 100644 index 6517959..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Player.java +++ /dev/null @@ -1,49 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import java.util.List; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.Index; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@ToString -@EqualsAndHashCode(callSuper=false) -@Entity -@Table(indexes = { - @Index(columnList = "firstName, lastName"), - @Index(columnList = "lastName, firstName") -}, uniqueConstraints = { - @UniqueConstraint(columnNames = { "firstName", "lastName" }) -}) -public class Player extends AbstractEntity { - - @NotNull - private String firstName; - - @NotNull - private String lastName; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "player") - @Nullable - private List roosters; - - public String getFullName() { - StringBuilder fullName = new StringBuilder(); - fullName.append(this.lastName); - fullName.append(", "); - fullName.append(this.firstName); - return fullName.toString(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Rooster.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Rooster.java deleted file mode 100644 index b0d3a3a..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Rooster.java +++ /dev/null @@ -1,49 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.Index; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Entity -@Table(indexes = { @Index(columnList = "team_id, player_id, position_id") }, uniqueConstraints = { - @UniqueConstraint(name = "uniqueRooster", columnNames = { "year", "team_id", "player_id", "position_id" }) }) -public class Rooster extends AbstractEntity { - - private int year; - - @ManyToOne - @JoinColumn(name = "team_id") - @NotNull - private Team team; - - @ManyToOne - @JoinColumn(name = "player_id") - @NotNull - private Player player; - - @ManyToOne - @JoinColumn(name = "position_id") - @NotNull - private FieldPosition position; - - @Override - public String toString() { - return "Rooster{" + - "year=" + year + - ", team=" + team.getName() + - ", player=" + player.getFullName() + - ", position=" + position.getName() + - '}'; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Sport.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Sport.java deleted file mode 100644 index 72635e1..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Sport.java +++ /dev/null @@ -1,53 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import java.util.LinkedList; -import java.util.List; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.Index; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotEmpty; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Getter -@Setter -@ToString -@EqualsAndHashCode(callSuper=false) -@Entity -@Table(indexes = {@Index(columnList = "name")}, - uniqueConstraints = {@UniqueConstraint(columnNames = { "name" })} -) -public class Sport extends AbstractEntity { - - @NotEmpty - @Column(unique = true) - private String name; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "sport") - @Nullable - private List teams = new LinkedList<>(); - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "sport") - @Nullable - private List positions = new LinkedList<>(); - - public String updateName(String value) { - if (!this.getName().equals(value)) { - this.setName(value); - log.info("update name"); - return "updated " + this.getId() + " with " + value; - } - return "no changes for " + this.getId(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Team.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Team.java deleted file mode 100644 index 353da78..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Team.java +++ /dev/null @@ -1,49 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.Index; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@ToString -@EqualsAndHashCode(callSuper=false) -@Entity -@Table(indexes = {@Index(columnList = "name")}, - uniqueConstraints = {@UniqueConstraint(columnNames = { "name" })} -) -public class Team extends AbstractEntity { - - @NotEmpty - private String name; - - @NotEmpty - private String shortName; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "team") - @Nullable - private List roosters; - - @ManyToOne - @JoinColumn(name = "sport_id") - @NotNull - @JsonIgnoreProperties({ "teams" }) - private Sport sport; -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Vendor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Vendor.java deleted file mode 100644 index a7a9305..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Vendor.java +++ /dev/null @@ -1,39 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import java.util.List; - -import de.thpeetz.kontor.common.data.AbstractEntity; -import jakarta.annotation.Nullable; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.Index; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import jakarta.persistence.UniqueConstraint; -import jakarta.validation.constraints.NotEmpty; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -/** - * Represents a vendor entity. - */ -@Getter -@Setter -@EqualsAndHashCode(callSuper = false) -@Entity -@Table(indexes = { @Index(columnList = "name") }, uniqueConstraints = { @UniqueConstraint(columnNames = "name") }) -public class Vendor extends AbstractEntity { - - @NotEmpty - private String name; - - @OneToMany(fetch = FetchType.EAGER, mappedBy = "vendor") - @Nullable - private List cardSets; - - @Override - public String toString() { - return "Vendor{id=" + this.getId() + ", name=" + name + '}'; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/CardRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/CardRepository.java deleted file mode 100644 index 09cfc08..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/CardRepository.java +++ /dev/null @@ -1,21 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import de.thpeetz.kontor.tysc.data.Card; -import de.thpeetz.kontor.tysc.data.CardSet; -import de.thpeetz.kontor.tysc.data.Rooster; -import de.thpeetz.kontor.tysc.data.Vendor; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface CardRepository extends JpaRepository { - - @Query("SELECT c FROM Card c WHERE c.vendor = ?1 AND c.cardSet = ?2 and c.rooster = ?3 and c.cardNumber = ?4 and c.year = ?5") - Card search(Vendor vendor, CardSet cardset, Rooster rooster, int cardNumber, int year); - - @Query("select c from Card c " + - "where str(c.cardNumber) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); -} - diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/CardSetRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/CardSetRepository.java deleted file mode 100644 index 3bf2901..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/CardSetRepository.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.CardSet; -import de.thpeetz.kontor.tysc.data.Vendor; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface CardSetRepository extends JpaRepository { - - List findByName(String name); - - CardSet findByNameAndVendor(String name, Vendor vendor); - - @Query("select c from CardSet c " + - "where lower(c.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/FieldPositionRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/FieldPositionRepository.java deleted file mode 100644 index b018173..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/FieldPositionRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.FieldPosition; -import de.thpeetz.kontor.tysc.data.Sport; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface FieldPositionRepository extends JpaRepository { - - @Query("select p from FieldPosition p " + - "where lower(p.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - List findBySport(Sport sport); - - FieldPosition findByShortName(String searchTerm); - - List findByShortNameIgnoreCase(String shortName); - - FieldPosition findByShortNameAndSport(String shortName, Sport sport); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/PlayerRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/PlayerRepository.java deleted file mode 100644 index 2f978f2..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/PlayerRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.Player; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface PlayerRepository extends JpaRepository { - - @Query("select p from Player p " + - "where lower(p.firstName) like lower(concat('%', :searchTerm, '%')) " + - "or lower(p.lastName) like lower(concat('%', :searchTerm, '%'))") - List search(@Param("searchTerm") String searchTerm); - - Player findByFirstNameAndLastName(String firstName, String lastName); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/RoosterRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/RoosterRepository.java deleted file mode 100644 index b707d6e..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/RoosterRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import de.thpeetz.kontor.tysc.data.FieldPosition; -import de.thpeetz.kontor.tysc.data.Player; -import de.thpeetz.kontor.tysc.data.Rooster; -import de.thpeetz.kontor.tysc.data.Team; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - -public interface RoosterRepository extends JpaRepository{ - - @Query("SELECT r FROM Rooster r WHERE r.player = ?1 AND r.team = ?2 AND r.position = ?3 AND r.year = ?4") - Rooster findByReferences(Player player, Team team, FieldPosition position, int year); -} - diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/SportRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/SportRepository.java deleted file mode 100644 index 3860a68..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/SportRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.Sport; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface SportRepository extends JpaRepository { - @Query("select s from Sport s " + - "where lower(s.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - Sport findByName(String name); - - List findByNameIgnoreCase(String name); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/TeamRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/TeamRepository.java deleted file mode 100644 index c0aeae8..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/TeamRepository.java +++ /dev/null @@ -1,28 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.Team; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -/** - * The repository interface for managing teams. - */ -public interface TeamRepository extends JpaRepository { - - /** - * Searches for teams based on a search term. - * - * @param searchTerm the search term to match against team names - * @return a list of teams matching the search term - */ - @Query("select t from Team t " + - "where lower(t.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - Team findByName(String name); - - List findByNameIgnoreCase(String name); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/VendorRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/VendorRepository.java deleted file mode 100644 index 3195c3c..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/repository/VendorRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.Vendor; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface VendorRepository extends JpaRepository { - - @Query("select v from Vendor v where lower(v.name) like lower(concat('%', :searchTerm, '%')) ") - List search(@Param("searchTerm") String searchTerm); - - Vendor findByName(String name); - - List findByNameIgnoreCase(String name); -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/services/CardService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/services/CardService.java deleted file mode 100644 index f91f55f..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/services/CardService.java +++ /dev/null @@ -1,93 +0,0 @@ -package de.thpeetz.kontor.tysc.services; - -import java.util.List; - -import de.thpeetz.kontor.tysc.repository.CardRepository; -import de.thpeetz.kontor.tysc.repository.CardSetRepository; -import de.thpeetz.kontor.tysc.repository.VendorRepository; -import org.springframework.stereotype.Service; - -import de.thpeetz.kontor.tysc.data.Card; -import de.thpeetz.kontor.tysc.data.CardSet; -import de.thpeetz.kontor.tysc.data.Vendor; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Service -public class CardService { - - private VendorRepository vendorRepository; - - private CardSetRepository cardSetRepository; - - private CardRepository cardRepository; - - public CardService(VendorRepository vendorRepository, CardSetRepository cardSetRepository, CardRepository cardRepository) { - this.vendorRepository = vendorRepository; - this.cardSetRepository = cardSetRepository; - this.cardRepository = cardRepository; - } - - public List findAllVendors(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return vendorRepository.findAll(); - } else { - return vendorRepository.search(stringFilter); - } - } - - public void deleteVendor(Vendor vendor) { - vendorRepository.delete(vendor); - } - - public Vendor saveVendor(Vendor vendor) { - if (vendor == null) { - log.warn("Vendor is null. Are you sure you have connected your form to the application?"); - return null; - } - return vendorRepository.save(vendor); - } - - public List findAllCards(String stringFilter) { - log.info("find cards with filter: {}", stringFilter); - if (stringFilter == null || stringFilter.isEmpty()) { - List cards = cardRepository.findAll(); - log.debug("found {} cards", cards.size()); - return cards; - } else { - return cardRepository.search(stringFilter); - } - } - - public void deleteCard(Card card) { - cardRepository.delete(card); - } - - public Card saveCard(Card card) { - if (card == null) { - log.warn("Card is null. Are you sure you have connected your form to the application?"); - return null; - } - return cardRepository.save(card); - } - - public List findAllCardSets(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return cardSetRepository.findAll(); - } else { - return cardSetRepository.search(stringFilter); - } - } - - public CardSet saveCardSet(CardSet cardSet) { - if (cardSet == null) { - log.warn("CardSet is null. Are you sure you have connected your form to the application?"); - return null; - } - return cardSetRepository.save(cardSet); - } - - public void deleteCardSet(CardSet cardSet) { - cardSetRepository.delete(cardSet); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/services/SportService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/services/SportService.java deleted file mode 100644 index 1fc7ff4..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/services/SportService.java +++ /dev/null @@ -1,194 +0,0 @@ -package de.thpeetz.kontor.tysc.services; - -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicReference; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import de.thpeetz.kontor.tysc.data.FieldPosition; -import de.thpeetz.kontor.tysc.data.Player; -import de.thpeetz.kontor.tysc.data.Rooster; -import de.thpeetz.kontor.tysc.data.Sport; -import de.thpeetz.kontor.tysc.data.Team; -import de.thpeetz.kontor.tysc.repository.FieldPositionRepository; -import de.thpeetz.kontor.tysc.repository.PlayerRepository; -import de.thpeetz.kontor.tysc.repository.RoosterRepository; -import de.thpeetz.kontor.tysc.repository.SportRepository; -import de.thpeetz.kontor.tysc.repository.TeamRepository; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Service -public class SportService { - - @Autowired - private SportRepository sportRepository; - - @Autowired - private TeamRepository teamRepository; - - @Autowired - private FieldPositionRepository fieldPositionRepository; - - @Autowired - private PlayerRepository playerRepository; - - @Autowired - private RoosterRepository roosterRepository; - - public List findAllSports(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return sportRepository.findAll(); - } else { - return sportRepository.search(stringFilter); - } - } - - public void deleteSport(Sport sport) { - sportRepository.delete(sport); - } - - public Sport saveSport(Sport sport) { - if (sport == null) { - log.warn("Sport is null. Are you sure you have connected your form to the application?"); - return null; - } - return sportRepository.save(sport); - } - - public List findAllPlayers(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return playerRepository.findAll(); - } else { - return playerRepository.search(stringFilter); - } - } - - public Player savePlayer(Player player) { - if (player == null) { - log.warn("Player is null. Are you sure you have connected yout form to the application?"); - return null; - } - return playerRepository.save(player); - } - - public void deletePlayer(Player player) { - playerRepository.delete(player); - } - - public List findAllTeams(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return teamRepository.findAll(); - } else { - return teamRepository.search(stringFilter); - } - } - - public void deleteTeam(Team team) { - teamRepository.delete(team); - } - - public void saveTeam(Team team) { - if (team == null) { - log.warn("Team is null. Are you sure you have connected your form to the application?"); - return; - } - teamRepository.save(team); - } - - public List findAllPositions(String stringFilter) { - if (stringFilter == null || stringFilter.isEmpty()) { - return fieldPositionRepository.findAll(); - } else { - return fieldPositionRepository.search(stringFilter); - } - } - - public List findAllPositionsForSport(Sport sport) { - if (sport == null) { - return fieldPositionRepository.findAll(); - } else { - log.info("Find positions for Sport: {}", sport); - return fieldPositionRepository.findBySport(sport); - } - } - - public void savePosition(FieldPosition position) { - if (position == null) { - log.warn("Position is null. Are you sure you have connected your form to the application?"); - return; - } - fieldPositionRepository.save(position); - } - - public void deletePosition(FieldPosition position) { - fieldPositionRepository.delete(position); - } - - public List findAllRoosters() { - return roosterRepository.findAll(); - } - - public Rooster findRoosterByFields(Team team, Player player, FieldPosition position, Integer year) { - return roosterRepository.findByReferences(player, team, position, year); - } - - public void saveRooster(Rooster rooster) { - if (rooster == null) { - log.warn(""); - return; - } - roosterRepository.save(rooster); - } - - public void deleteRooster(Rooster rooster) { - roosterRepository.delete(rooster); - } - - public String importData(Map fields) { - AtomicReference status = new AtomicReference<>("unknown"); - String id = fields.get("id"); - Optional optional = sportRepository.findById(id); - if (optional.isEmpty()) { - log.info(" not found: {} with {}", id, fields); - status.set(id + "not found"); - Sport checkExisting = sportRepository.findByName(fields.get("name")); - if (checkExisting != null) { - log.info("entry already there with different id ({}), will be deleted", checkExisting.getId()); - deleteSport(checkExisting); - } - Sport sport = new Sport(); - sport.setId(id); - sport.setName(fields.get("name")); - sportRepository.save(sport); - } else { - optional.ifPresent( entry -> { - log.info(" found: {}", entry.getName()); - String updateStatus = updateSportFields(entry, fields); - sportRepository.save(entry); - status.set(updateStatus); - }); - } - return status.get(); - } - - private String updateSportFields(Sport sport, Map fields) { - StringBuilder status = new StringBuilder(); - for (Map.Entry entry : fields.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - switch (key) { - case "id", "created_date", "last_modified_date", "version": - break; - case "table_name": - status.append(sport.updateName(value)); - default: - log.info("field {} is unknown for table {}", key, sport.getClass().getName()); - } - } - return status.toString(); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardForm.java deleted file mode 100644 index 0b23ff6..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardForm.java +++ /dev/null @@ -1,116 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.tysc.data.Card; -import de.thpeetz.kontor.tysc.data.Rooster; -import de.thpeetz.kontor.tysc.data.Vendor; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class CardForm extends FormLayout { - - TextField cardNumber = new TextField("CardNumber"); - TextField year = new TextField("Year"); - ComboBox vendor = new ComboBox<>("Vendor"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Card.class); - - public CardForm(List vendors) { - addClassName("card-form"); - binder.bindInstanceFields(this); - - vendor.setItems(vendors); - vendor.setItemLabelGenerator(Vendor::getName); - add(cardNumber, year, vendor, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setCard(Card card) { - binder.setBean(card); - } - - public void setRoosters(List roosters) { - log.info("Setting roosters: {}", roosters); - } - - public abstract static class CardFormEvent extends ComponentEvent { - private Card card; - - protected CardFormEvent(CardForm source, Card card) { - super(source, false); - this.card = card; - } - - public Card getCard() { - return card; - } - } - - public static class SaveEvent extends CardFormEvent { - SaveEvent(CardForm source, Card card) { - super(source, card); - } - } - - public static class DeleteEvent extends CardFormEvent { - DeleteEvent(CardForm source, Card card) { - super(source, card); - } - } - - public static class CloseEvent extends CardFormEvent { - CloseEvent(CardForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardSetForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardSetForm.java deleted file mode 100644 index d0e7e89..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardSetForm.java +++ /dev/null @@ -1,103 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.tysc.data.CardSet; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class CardSetForm extends FormLayout { - - TextField name = new TextField("Name"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(CardSet.class); - - public CardSetForm() { - addClassName("cardSet-form"); - binder.bindInstanceFields(this); - - add(name, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setCardSet(CardSet cardSet) { - binder.setBean(cardSet); - } - - public abstract static class CardSetFormEvent extends ComponentEvent { - private CardSet cardSet; - - protected CardSetFormEvent(CardSetForm source, CardSet cardSet) { - super(source, false); - this.cardSet = cardSet; - } - - public CardSet getCardSet() { - return cardSet; - } - } - - public static class SaveEvent extends CardSetFormEvent { - SaveEvent(CardSetForm source, CardSet cardSet) { - super(source, cardSet); - } - } - - public static class DeleteEvent extends CardSetFormEvent { - DeleteEvent(CardSetForm source, CardSet cardSet) { - super(source, cardSet); - } - } - - public static class CloseEvent extends CardSetFormEvent { - CloseEvent(CardSetForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardSetView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardSetView.java deleted file mode 100644 index 071e66d..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardSetView.java +++ /dev/null @@ -1,158 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import com.vaadin.flow.component.button.*; -import de.thpeetz.kontor.comics.data.*; -import de.thpeetz.kontor.common.views.*; -import lombok.*; -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.tysc.TyscConstants; -import de.thpeetz.kontor.tysc.data.CardSet; -import de.thpeetz.kontor.tysc.services.CardService; -import jakarta.annotation.security.PermitAll; - -import java.util.*; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = TyscConstants.CARDSET_ROUTE, layout = MainLayout.class) -@PageTitle("CardSet | Tysc | Kontor") -public class CardSetView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(CardSet.class, false); - Grid.Column idColumn = grid.addColumn(CardSet::getId) - .setHeader("ID").setResizable(true).setSortable(true); - Grid.Column createdColumn = grid.addColumn(CardSet::getCreatedDate) - .setHeader("Erstellt").setResizable(true).setSortable(true); - Grid.Column modifiedColumn = grid.addColumn(CardSet::getLastModifiedDate) - .setHeader("Geändert").setResizable(true).setSortable(true); - Grid.Column versionColumn = grid.addColumn(CardSet::getVersion) - .setHeader("Version").setResizable(true).setSortable(true); - Grid.Column nameColumn = grid.addColumn(CardSet::getName) - .setHeader("Comic").setResizable(true).setSortable(true); - Grid.Column vendorNameColumn = grid.addColumn(CardSet::getVendorName) - .setHeader("Hersteller").setResizable(true).setSortable(true); - Grid.Column parallelSetColumn = grid.addComponentColumn(parallelSet -> StatusIcon.create(parallelSet.isParallelSet())) - .setHeader("Parallelset?").setWidth("6rem").setSortable(true); - Grid.Column insertSetColumn = grid.addComponentColumn(insertSet -> StatusIcon.create(insertSet.isInsertSet())) - .setHeader("Parallelset?").setWidth("6rem").setSortable(true); - TextField filterText = new TextField(); - @Getter - CardSetForm form; - CardService service; - - public CardSetView(CardService service) { - this.service = service; - addClassName("cardSet-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("cardSet-grid"); - grid.setSizeFull(); - //grid.setColumns("name", "vendor.name", "parallelSet", "insertSet"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - idColumn.setVisible(false); - createdColumn.setVisible(false); - modifiedColumn.setVisible(false); - versionColumn.setVisible(false); - grid.asSingleSelect().addValueChangeListener(event -> editCardSet(event.getValue())); - } - - private void configureForm() { - form = new CardSetForm(); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveCardSet); - form.addDeleteListener(this::deleteCardSet); - form.addCloseListener(e -> closeEditor()); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addCardSetButton = new Button("Add cardSet"); - addCardSetButton.addClickListener(click -> addCardSet()); - - Button menuButton = new Button("Show/Hide Columns"); - menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); - columnToggleContextMenu.addColumnToggleItem(idColumn); - columnToggleContextMenu.addColumnToggleItem(createdColumn); - columnToggleContextMenu.addColumnToggleItem(modifiedColumn); - columnToggleContextMenu.addColumnToggleItem(versionColumn); - columnToggleContextMenu.addColumnToggleItem(nameColumn); - columnToggleContextMenu.addColumnToggleItem(vendorNameColumn); - columnToggleContextMenu.addColumnToggleItem(parallelSetColumn); - columnToggleContextMenu.addColumnToggleItem(insertSetColumn); - HorizontalLayout toolbar = new HorizontalLayout(filterText, addCardSetButton, menuButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - private void saveCardSet(CardSetForm.SaveEvent event) { - service.saveCardSet(event.getCardSet()); - updateList(); - closeEditor(); - } - - private void deleteCardSet(CardSetForm.DeleteEvent event) { - service.deleteCardSet(event.getCardSet()); - updateList(); - closeEditor(); - } - - public void editCardSet(CardSet cardSet) { - if (cardSet == null) { - closeEditor(); - } else { - form.setCardSet(cardSet); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setCardSet(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addCardSet() { - grid.asSingleSelect().clear(); - editCardSet(new CardSet()); - } - - public void updateList() { - grid.setItems(service.findAllCardSets(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardView.java deleted file mode 100644 index 7fd530c..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardView.java +++ /dev/null @@ -1,162 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.common.views.StatusIcon; -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.common.views.ColumnToggleContextMenu; -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.tysc.TyscConstants; -import de.thpeetz.kontor.tysc.data.Card; -import de.thpeetz.kontor.tysc.services.CardService; -import jakarta.annotation.security.PermitAll; -import lombok.Getter; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = TyscConstants.CARD_ROUTE, layout = MainLayout.class) -@PageTitle("Card | Tysc | Kontor") -public class CardView extends VerticalLayout { - - @Getter - Grid grid = new Grid<>(Card.class, false); - Grid.Column idColumn = grid.addColumn(Card::getId).setHeader("ID") - .setResizable(true).setSortable(true); - Grid.Column createdColumn = grid.addColumn(Card::getCreatedDate) - .setHeader("Erstellt").setResizable(true).setSortable(true); - Grid.Column modifiedColumn = grid.addColumn(Card::getLastModifiedDate) - .setHeader("Geändert").setResizable(true).setSortable(true); - Grid.Column numberColumn = grid.addColumn(Card::getCardNumber) - .setHeader("Nummer").setResizable(true).setSortable(true); - Grid.Column yearColumn = grid.addColumn(Card::getYear) - .setHeader("Jahr").setResizable(true).setSortable(true); - Grid.Column vendorColumn = grid.addColumn(Card::getVendorName) - .setHeader("Hersteller").setResizable(true).setSortable(true); - Grid.Column cardSetColumn = grid.addColumn(Card::getCardSetName) - .setHeader("Cardset").setResizable(true).setSortable(true); - Grid.Column insertSetColumn = grid.addComponentColumn(card -> StatusIcon.create(card.getCardSet().isInsertSet())) - .setHeader("Inserts").setWidth("6rem").setSortable(true); - Grid.Column parallelSetColumn = grid.addComponentColumn(card -> StatusIcon.create(card.getCardSet().isParallelSet())) - .setHeader("Parallels").setWidth("6rem").setSortable(true); - Grid.Column playerColumn = grid.addColumn(Card::getPlayerName).setHeader("Spieler").setResizable(true).setSortable(true); - TextField filterText = new TextField(); - @Getter - CardForm form; - CardService service; - - public CardView(CardService service) { - this.service = service; - addClassName("card-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - private void configureGrid() { - grid.addClassName("card-grid"); - grid.setSizeFull(); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editCard(event.getValue())); - idColumn.setVisible(false); - createdColumn.setVisible(false); - modifiedColumn.setVisible(false); - } - - private void configureForm() { - form = new CardForm(service.findAllVendors(null)); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveCard); - form.addDeleteListener(this::deleteCard); - form.addCloseListener(e -> closeEditor()); - } - - private void saveCard(CardForm.SaveEvent event) { - service.saveCard(event.getCard()); - updateList(); - closeEditor(); - } - - private void deleteCard(CardForm.DeleteEvent event) { - service.deleteCard(event.getCard()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addCardButton = new Button("Add card"); - addCardButton.addClickListener(click -> addCard()); - - Button menuButton = new Button("Show/Hide Columns"); - menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); - columnToggleContextMenu.addColumnToggleItem(idColumn); - columnToggleContextMenu.addColumnToggleItem(createdColumn); - columnToggleContextMenu.addColumnToggleItem(modifiedColumn); - columnToggleContextMenu.addColumnToggleItem(numberColumn); - columnToggleContextMenu.addColumnToggleItem(yearColumn); - columnToggleContextMenu.addColumnToggleItem(vendorColumn); - columnToggleContextMenu.addColumnToggleItem(cardSetColumn); - columnToggleContextMenu.addColumnToggleItem(insertSetColumn); - columnToggleContextMenu.addColumnToggleItem(parallelSetColumn); - columnToggleContextMenu.addColumnToggleItem(playerColumn); - HorizontalLayout toolbar = new HorizontalLayout(filterText, addCardButton, menuButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editCard(Card card) { - if (card == null) { - closeEditor(); - } else { - form.setCard(card); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setCard(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addCard() { - grid.asSingleSelect().clear(); - editCard(new Card()); - } - - public void updateList() { - grid.setItems(service.findAllCards(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/PlayerForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/PlayerForm.java deleted file mode 100644 index 9730103..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/PlayerForm.java +++ /dev/null @@ -1,116 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.tysc.data.Player; -import de.thpeetz.kontor.tysc.data.Rooster; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class PlayerForm extends FormLayout { - - TextField firstName = new TextField("First Name"); - TextField lastName = new TextField("Last Name"); - Grid roosters = new Grid<>(Rooster.class); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Player.class); - - public PlayerForm() { - addClassName("player-form"); - binder.bindInstanceFields(this); - - roosters.setColumns("team.name", "position.name", "year"); - roosters.getColumns().forEach(col -> col.setAutoWidth(true)); - add(firstName, lastName, roosters, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setPlayer(Player player) { - binder.setBean(player); - } - - public void setRoosters(List roosters) { - log.info("Setting roosters: {}", roosters); - this.roosters.setItems(roosters); - } - - public abstract static class PlayerFormEvent extends ComponentEvent { - private Player player; - - protected PlayerFormEvent(PlayerForm source, Player player) { - super(source, false); - this.player = player; - } - - public Player getPlayer() { - return player; - } - } - - public static class SaveEvent extends PlayerFormEvent { - SaveEvent(PlayerForm source, Player player) { - super(source, player); - } - } - - public static class DeleteEvent extends PlayerFormEvent { - DeleteEvent(PlayerForm source, Player player) { - super(source, player); - } - } - - public static class CloseEvent extends PlayerFormEvent { - CloseEvent(PlayerForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/PlayerView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/PlayerView.java deleted file mode 100644 index 56d9588..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/PlayerView.java +++ /dev/null @@ -1,130 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.tysc.TyscConstants; -import de.thpeetz.kontor.tysc.data.Player; -import de.thpeetz.kontor.tysc.services.SportService; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = TyscConstants.PLAYER_ROUTE, layout = MainLayout.class) -@PageTitle("Player | Tysc | Kontor") -public class PlayerView extends VerticalLayout { - - Grid grid = new Grid<>(Player.class); - TextField filterText = new TextField(); - PlayerForm form; - SportService service; - - public PlayerView(SportService service) { - this.service = service; - addClassName("player-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - public Grid getGrid() { - return grid; - } - - private void configureGrid() { - grid.addClassName("player-grid"); - grid.setSizeFull(); - grid.setColumns("firstName", "lastName"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editPlayer(event.getValue())); - } - - public PlayerForm getForm() { - return form; - } - - private void configureForm() { - form = new PlayerForm(); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::savePlayer); - form.addDeleteListener(this::deletePlayer); - form.addCloseListener(e -> closeEditor()); - } - - private void savePlayer(PlayerForm.SaveEvent event) { - service.savePlayer(event.getPlayer()); - updateList(); - closeEditor(); - } - - private void deletePlayer(PlayerForm.DeleteEvent event) { - service.deletePlayer(event.getPlayer()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addPlayerButton = new Button("Add player"); - addPlayerButton.addClickListener(click -> addPlayer()); - - HorizontalLayout toolbar = new HorizontalLayout(filterText, addPlayerButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editPlayer(Player player) { - if (player == null) { - closeEditor(); - } else { - form.setPlayer(player); - form.setRoosters(player.getRoosters()); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setPlayer(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addPlayer() { - grid.asSingleSelect().clear(); - editPlayer(new Player()); - } - - public void updateList() { - grid.setItems(service.findAllPlayers(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/PositionForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/PositionForm.java deleted file mode 100644 index f5b49bb..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/PositionForm.java +++ /dev/null @@ -1,115 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.tysc.data.FieldPosition; -import de.thpeetz.kontor.tysc.data.Rooster; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class PositionForm extends FormLayout { - - TextField name = new TextField("Name"); - Grid roosters = new Grid<>(Rooster.class); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(FieldPosition.class); - - public PositionForm() { - addClassName("position-form"); - binder.bindInstanceFields(this); - - roosters.setColumns("player.fullName", "team.name", "year"); - roosters.getColumns().forEach(col -> col.setAutoWidth(true)); - add(name, roosters, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setPosition(FieldPosition position) { - binder.setBean(position); - } - - public void setRoosters(List roosters) { - log.info("Setting roosters: {}", roosters); - this.roosters.setItems(roosters); - } - - public abstract static class PositionFormEvent extends ComponentEvent { - private FieldPosition position; - - protected PositionFormEvent(PositionForm source, FieldPosition position) { - super(source, false); - this.position = position; - } - - public FieldPosition getPosition() { - return position; - } - } - - public static class SaveEvent extends PositionFormEvent { - SaveEvent(PositionForm source, FieldPosition position) { - super(source, position); - } - } - - public static class DeleteEvent extends PositionFormEvent { - DeleteEvent(PositionForm source, FieldPosition position) { - super(source, position); - } - } - - public static class CloseEvent extends PositionFormEvent { - CloseEvent(PositionForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/PositionView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/PositionView.java deleted file mode 100644 index ad71bf0..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/PositionView.java +++ /dev/null @@ -1,130 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import de.thpeetz.kontor.tysc.data.FieldPosition; -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.tysc.TyscConstants; -import de.thpeetz.kontor.tysc.services.SportService; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = TyscConstants.POSITION_ROUTE, layout = MainLayout.class) -@PageTitle("Position | Tysc | Kontor") -public class PositionView extends VerticalLayout { - - Grid grid = new Grid<>(FieldPosition.class); - TextField filterText = new TextField(); - PositionForm form; - SportService service; - - public PositionView(SportService service) { - this.service = service; - addClassName("position-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - public Grid getGrid() { - return grid; - } - - private void configureGrid() { - grid.addClassName("position-grid"); - grid.setSizeFull(); - grid.setColumns("shortName", "name", "sport.name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editPosition(event.getValue())); - } - - public PositionForm getForm() { - return form; - } - - private void configureForm() { - form = new PositionForm(); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::savePosition); - form.addDeleteListener(this::deletePosition); - form.addCloseListener(e -> closeEditor()); - } - - private void savePosition(PositionForm.SaveEvent event) { - service.savePosition(event.getPosition()); - updateList(); - closeEditor(); - } - - private void deletePosition(PositionForm.DeleteEvent event) { - service.deletePosition(event.getPosition()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addPositionButton = new Button("Add position"); - addPositionButton.addClickListener(click -> addPosition()); - - HorizontalLayout toolbar = new HorizontalLayout(filterText, addPositionButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editPosition(FieldPosition fieldPosition) { - if (fieldPosition == null) { - closeEditor(); - } else { - form.setPosition(fieldPosition); - form.setRoosters(fieldPosition.getRoosters()); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setPosition(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addPosition() { - grid.asSingleSelect().clear(); - editPosition(new FieldPosition()); - } - - public void updateList() { - grid.setItems(service.findAllPositions(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/RoosterForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/RoosterForm.java deleted file mode 100644 index 5f9d259..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/RoosterForm.java +++ /dev/null @@ -1,117 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.combobox.ComboBox; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.IntegerField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.tysc.data.FieldPosition; -import de.thpeetz.kontor.tysc.data.Player; -import de.thpeetz.kontor.tysc.data.Rooster; -import de.thpeetz.kontor.tysc.data.Team; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class RoosterForm extends FormLayout { - IntegerField year = new IntegerField("Year"); - ComboBox team = new ComboBox<>("Team"); - ComboBox player = new ComboBox<>("Player"); - ComboBox position = new ComboBox<>("Position"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Rooster.class); - - public RoosterForm(List teams, List players, List positions) { - addClassName("rooster-form"); - binder.bindInstanceFields(this); - - team.setItems(teams); - team.setItemLabelGenerator(Team::getName); - player.setItems(players); - player.setItemLabelGenerator(Player::getFullName); - position.setItems(positions); - position.setItemLabelGenerator(FieldPosition::getName); - add(year, team, player, position, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setRooster(Rooster rooster) { - binder.setBean(rooster); - } - - public abstract static class RoosterFormEvent extends ComponentEvent { - private Rooster rooster; - - protected RoosterFormEvent(RoosterForm source, Rooster rooster) { - super(source, false); - this.rooster = rooster; - } - - public Rooster getRooster() { - return rooster; - } - } - - public static class SaveEvent extends RoosterFormEvent { - SaveEvent(RoosterForm source, Rooster rooster) { - super(source, rooster); - } - } - - public static class DeleteEvent extends RoosterFormEvent { - DeleteEvent(RoosterForm source, Rooster rooster) { - super(source, rooster); - } - } - - public static class CloseEvent extends RoosterFormEvent { - CloseEvent(RoosterForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/RoosterView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/RoosterView.java deleted file mode 100644 index 92da6eb..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/RoosterView.java +++ /dev/null @@ -1,121 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.tysc.TyscConstants; -import de.thpeetz.kontor.tysc.data.Rooster; -import de.thpeetz.kontor.tysc.services.SportService; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = TyscConstants.ROOSTER_ROUTE, layout = MainLayout.class) -@PageTitle("Rooster | Tysc | Kontor") -public class RoosterView extends VerticalLayout { - - Grid grid = new Grid<>(Rooster.class); - RoosterForm form; - SportService service; - - public RoosterView(SportService service) { - this.service = service; - addClassName("rooster-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - public Grid getGrid() { - return grid; - } - - private void configureGrid() { - grid.addClassName("rooster-grid"); - grid.setSizeFull(); - grid.setColumns("year", "team.name", "player.fullName", "position.name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editRooster(event.getValue())); - } - - public RoosterForm getForm() { - return form; - } - - private void configureForm() { - form = new RoosterForm(service.findAllTeams(null), service.findAllPlayers(null), service.findAllPositions(null)); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveRooster); - form.addDeleteListener(this::deleteRooster); - form.addCloseListener(e -> closeEditor()); - } - - private void saveRooster(RoosterForm.SaveEvent event) { - service.saveRooster(event.getRooster()); - updateList(); - closeEditor(); - } - - private void deleteRooster(RoosterForm.DeleteEvent event) { - service.deleteRooster(event.getRooster()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - Button addRoosterButton = new Button("Add Rooster"); - addRoosterButton.addClickListener(click -> addRooster()); - - HorizontalLayout toolbar = new HorizontalLayout(addRoosterButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editRooster(Rooster rooster) { - if (rooster == null) { - closeEditor(); - } else { - form.setRooster(rooster); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setRooster(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addRooster() { - grid.asSingleSelect().clear(); - editRooster(new Rooster()); - } - - public void updateList() { - grid.setItems(service.findAllRoosters()); - } -} \ No newline at end of file diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/SportForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/SportForm.java deleted file mode 100644 index 30582e1..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/SportForm.java +++ /dev/null @@ -1,103 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.tysc.data.Sport; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class SportForm extends FormLayout { - - TextField name = new TextField("Name"); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Sport.class); - - public SportForm() { - addClassName("sport-form"); - binder.bindInstanceFields(this); - - add(name, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setSport(Sport sport) { - binder.setBean(sport); - } - - public abstract static class SportFormEvent extends ComponentEvent { - private Sport sport; - - protected SportFormEvent(SportForm source, Sport sport) { - super(source, false); - this.sport = sport; - } - - public Sport getSport() { - return sport; - } - } - - public static class SaveEvent extends SportFormEvent { - SaveEvent(SportForm source, Sport sport) { - super(source, sport); - } - } - - public static class DeleteEvent extends SportFormEvent { - DeleteEvent(SportForm source, Sport sport) { - super(source, sport); - } - } - - public static class CloseEvent extends SportFormEvent { - CloseEvent(SportForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/SportView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/SportView.java deleted file mode 100644 index c6008c3..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/SportView.java +++ /dev/null @@ -1,129 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.tysc.TyscConstants; -import de.thpeetz.kontor.tysc.data.Sport; -import de.thpeetz.kontor.tysc.services.SportService; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = TyscConstants.SPORT_ROUTE, layout = MainLayout.class) -@PageTitle("Sport | Tysc | Kontor") -public class SportView extends VerticalLayout { - - Grid grid = new Grid<>(Sport.class); - TextField filterText = new TextField(); - SportForm form; - SportService service; - - public SportView(SportService service) { - this.service = service; - addClassName("sport-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - public Grid getGrid() { - return grid; - } - - private void configureGrid() { - grid.addClassName("sport-grid"); - grid.setSizeFull(); - grid.setColumns("name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editSport(event.getValue())); - } - - public SportForm getForm() { - return form; - } - - private void configureForm() { - form = new SportForm(); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveSport); - form.addDeleteListener(this::deleteSport); - form.addCloseListener(e -> closeEditor()); - } - - private void saveSport(SportForm.SaveEvent event) { - service.saveSport(event.getSport()); - updateList(); - closeEditor(); - } - - private void deleteSport(SportForm.DeleteEvent event) { - service.deleteSport(event.getSport()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addSportButton = new Button("Add sport"); - addSportButton.addClickListener(click -> addSport()); - - HorizontalLayout toolbar = new HorizontalLayout(filterText, addSportButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editSport(Sport sport) { - if (sport == null) { - closeEditor(); - } else { - form.setSport(sport); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setSport(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addSport() { - grid.asSingleSelect().clear(); - editSport(new Sport()); - } - - public void updateList() { - grid.setItems(service.findAllSports(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/TeamForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/TeamForm.java deleted file mode 100644 index 63cb56b..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/TeamForm.java +++ /dev/null @@ -1,115 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.tysc.data.Rooster; -import de.thpeetz.kontor.tysc.data.Team; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class TeamForm extends FormLayout { - - TextField name = new TextField("Name"); - Grid roosters = new Grid<>(Rooster.class); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Team.class); - - public TeamForm() { - addClassName("team-form"); - binder.bindInstanceFields(this); - - roosters.setColumns("player.fullName", "position.name", "year"); - roosters.getColumns().forEach(col -> col.setAutoWidth(true)); - add(name, roosters, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setTeam(Team team) { - binder.setBean(team); - } - - public void setRoosters(List roosters) { - log.info("Setting roosters: {}", roosters); - this.roosters.setItems(roosters); - } - - public abstract static class TeamFormEvent extends ComponentEvent { - private Team team; - - protected TeamFormEvent(TeamForm source, Team team) { - super(source, false); - this.team = team; - } - - public Team getTeam() { - return team; - } - } - - public static class SaveEvent extends TeamFormEvent { - SaveEvent(TeamForm source, Team team) { - super(source, team); - } - } - - public static class DeleteEvent extends TeamFormEvent { - DeleteEvent(TeamForm source, Team team) { - super(source, team); - } - } - - public static class CloseEvent extends TeamFormEvent { - CloseEvent(TeamForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/TeamView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/TeamView.java deleted file mode 100644 index 1e48f98..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/TeamView.java +++ /dev/null @@ -1,130 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.tysc.TyscConstants; -import de.thpeetz.kontor.tysc.data.Team; -import de.thpeetz.kontor.tysc.services.SportService; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = TyscConstants.TEAM_ROUTE, layout = MainLayout.class) -@PageTitle("Team | Tysc | Kontor") -public class TeamView extends VerticalLayout { - - Grid grid = new Grid<>(Team.class); - TextField filterText = new TextField(); - TeamForm form; - SportService service; - - public TeamView(SportService service) { - this.service = service; - addClassName("team-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - public Grid getGrid() { - return grid; - } - - private void configureGrid() { - grid.addClassName("team-grid"); - grid.setSizeFull(); - grid.setColumns("name", "shortName", "sport.name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editTeam(event.getValue())); - } - - public TeamForm getForm() { - return form; - } - - private void configureForm() { - form = new TeamForm(); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveTeam); - form.addDeleteListener(this::deleteTeam); - form.addCloseListener(e -> closeEditor()); - } - - private void saveTeam(TeamForm.SaveEvent event) { - service.saveTeam(event.getTeam()); - updateList(); - closeEditor(); - } - - private void deleteTeam(TeamForm.DeleteEvent event) { - service.deleteTeam(event.getTeam()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addTeamButton = new Button("Add team"); - addTeamButton.addClickListener(click -> addTeam()); - - HorizontalLayout toolbar = new HorizontalLayout(filterText, addTeamButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editTeam(Team team) { - if (team == null) { - closeEditor(); - } else { - form.setTeam(team); - form.setRoosters(team.getRoosters()); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setTeam(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addTeam() { - grid.asSingleSelect().clear(); - editTeam(new Team()); - } - - public void updateList() { - grid.setItems(service.findAllTeams(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/TyscLayout.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/TyscLayout.java deleted file mode 100644 index 66fb09b..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/TyscLayout.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import com.vaadin.flow.component.applayout.AppLayout; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.theme.lumo.LumoUtility; - -import de.thpeetz.kontor.admin.services.AdminService; -import de.thpeetz.kontor.common.views.KontorLayoutUtil; -import de.thpeetz.kontor.security.SecurityService; -import de.thpeetz.kontor.tysc.TyscConstants; -import lombok.extern.slf4j.Slf4j; - -/** - * Represents a custom layout for the comic view in the application. - * This layout extends the AppLayout class. - */ -@Slf4j -public class TyscLayout extends AppLayout { - - private final AdminService adminService; - - private final SecurityService securityService; - - public TyscLayout(AdminService adminService, SecurityService securityService) { - this.adminService = adminService; - this.securityService = securityService; - - KontorLayoutUtil layout = new KontorLayoutUtil(this, adminService, securityService); - layout.setSecondaryNavigation(getSecondaryNavigation()); - layout.createHeader(TyscConstants.TYSC); - } - - private HorizontalLayout getSecondaryNavigation() { - HorizontalLayout navigation = new HorizontalLayout(); - navigation.addClassNames(LumoUtility.JustifyContent.CENTER, LumoUtility.Gap.SMALL, LumoUtility.Height.MEDIUM); - navigation.add(TyscConstants.getSportLink(), TyscConstants.getTeamLink(), TyscConstants.getPositionLink(), - TyscConstants.getPlayerLink(), TyscConstants.getRoosterLink(), TyscConstants.getVendorLink(), - TyscConstants.getCardSetLink(), TyscConstants.getCardLink()); - return navigation; - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/VendorForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/VendorForm.java deleted file mode 100644 index 254b1ff..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/VendorForm.java +++ /dev/null @@ -1,115 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import java.util.List; - -import com.vaadin.flow.component.ComponentEvent; -import com.vaadin.flow.component.ComponentEventListener; -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.button.ButtonVariant; -import com.vaadin.flow.component.formlayout.FormLayout; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.BeanValidationBinder; -import com.vaadin.flow.data.binder.Binder; - -import de.thpeetz.kontor.tysc.data.Vendor; -import de.thpeetz.kontor.tysc.data.CardSet; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class VendorForm extends FormLayout { - - TextField name = new TextField("Name"); - Grid cardSets = new Grid<>(CardSet.class); - - Button save = new Button("Save"); - Button delete = new Button("Delete"); - Button close = new Button("Cancel"); - - Binder binder = new BeanValidationBinder<>(Vendor.class); - - public VendorForm() { - addClassName("vendor-form"); - binder.bindInstanceFields(this); - - cardSets.setColumns("name", "parallelSet"); - cardSets.getColumns().forEach(col -> col.setAutoWidth(true)); - add(name, cardSets, createButtonsLayout()); - } - - private HorizontalLayout createButtonsLayout() { - save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); - delete.addThemeVariants(ButtonVariant.LUMO_ERROR); - close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); - - save.addClickShortcut(Key.ENTER); - close.addClickShortcut(Key.ESCAPE); - - save.addClickListener(event -> validateAndSave()); - delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); - close.addClickListener(event -> fireEvent(new CloseEvent(this))); - - binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); - return new HorizontalLayout(save, delete, close); - } - - private void validateAndSave() { - if (binder.isValid()) { - fireEvent(new SaveEvent(this, binder.getBean())); - } - } - - public void setVendor(Vendor vendor) { - binder.setBean(vendor); - } - - public void setCardSets(List sets) { - log.info("Setting card sets: {}", sets); - this.cardSets.setItems(sets); - } - - public abstract static class VendorFormEvent extends ComponentEvent { - private Vendor vendor; - - protected VendorFormEvent(VendorForm source, Vendor vendor) { - super(source, false); - this.vendor = vendor; - } - - public Vendor getVendor() { - return vendor; - } - } - - public static class SaveEvent extends VendorFormEvent { - SaveEvent(VendorForm source, Vendor vendor) { - super(source, vendor); - } - } - - public static class DeleteEvent extends VendorFormEvent { - DeleteEvent(VendorForm source, Vendor vendor) { - super(source, vendor); - } - } - - public static class CloseEvent extends VendorFormEvent { - CloseEvent(VendorForm source) { - super(source, null); - } - } - - public void addDeleteListener(ComponentEventListener listener) { - addListener(DeleteEvent.class, listener); - } - - public void addSaveListener(ComponentEventListener listener) { - addListener(SaveEvent.class, listener); - } - - public void addCloseListener(ComponentEventListener listener) { - addListener(CloseEvent.class, listener); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/VendorView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/VendorView.java deleted file mode 100644 index 08b5d32..0000000 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/VendorView.java +++ /dev/null @@ -1,130 +0,0 @@ -package de.thpeetz.kontor.tysc.views; - -import org.springframework.context.annotation.Scope; - -import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.PageTitle; -import com.vaadin.flow.router.Route; -import com.vaadin.flow.spring.annotation.SpringComponent; - -import de.thpeetz.kontor.common.views.MainLayout; -import de.thpeetz.kontor.tysc.TyscConstants; -import de.thpeetz.kontor.tysc.data.Vendor; -import de.thpeetz.kontor.tysc.services.CardService; -import jakarta.annotation.security.PermitAll; - -@SpringComponent -@Scope("prototype") -@PermitAll -@Route(value = TyscConstants.VENDOR_ROUTE, layout = MainLayout.class) -@PageTitle("Vendor | Tysc | Kontor") -public class VendorView extends VerticalLayout { - - Grid grid = new Grid<>(Vendor.class); - TextField filterText = new TextField(); - VendorForm form; - CardService service; - - public VendorView(CardService service) { - this.service = service; - addClassName("vendor-view"); - setSizeFull(); - configureGrid(); - configureForm(); - - add(getToolbar(), getContent()); - updateList(); - } - - public Grid getGrid() { - return grid; - } - - private void configureGrid() { - grid.addClassName("vendor-grid"); - grid.setSizeFull(); - grid.setColumns("name"); - grid.getColumns().forEach(col -> col.setAutoWidth(true)); - grid.asSingleSelect().addValueChangeListener(event -> editVendor(event.getValue())); - } - - public VendorForm getForm() { - return form; - } - - private void configureForm() { - form = new VendorForm(); - form.setWidth("25em"); - form.setVisible(false); - form.addSaveListener(this::saveVendor); - form.addDeleteListener(this::deleteVendor); - form.addCloseListener(e -> closeEditor()); - } - - private void saveVendor(VendorForm.SaveEvent event) { - service.saveVendor(event.getVendor()); - updateList(); - closeEditor(); - } - - private void deleteVendor(VendorForm.DeleteEvent event) { - service.deleteVendor(event.getVendor()); - updateList(); - closeEditor(); - } - - private Component getContent() { - HorizontalLayout content = new HorizontalLayout(grid, form); - content.setFlexGrow(2, grid); - content.setFlexGrow(1, form); - content.addClassName("content"); - content.setSizeFull(); - return content; - } - - private HorizontalLayout getToolbar() { - filterText.setPlaceholder("Filter by name..."); - filterText.setClearButtonVisible(true); - filterText.setValueChangeMode(ValueChangeMode.LAZY); - filterText.addValueChangeListener(e -> updateList()); - - Button addVendorButton = new Button("Add vendor"); - addVendorButton.addClickListener(click -> addVendor()); - - HorizontalLayout toolbar = new HorizontalLayout(filterText, addVendorButton); - toolbar.addClassName("toolbar"); - return toolbar; - } - - public void editVendor(Vendor vendor) { - if (vendor == null) { - closeEditor(); - } else { - form.setVendor(vendor); - form.setCardSets(vendor.getCardSets()); - form.setVisible(true); - addClassName("editing"); - } - } - - private void closeEditor() { - form.setVendor(null); - form.setVisible(false); - removeClassName("editing"); - } - - private void addVendor() { - grid.asSingleSelect().clear(); - editVendor(new Vendor()); - } - - public void updateList() { - grid.setItems(service.findAllVendors(filterText.getValue())); - } -} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/DataManagementView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/DataManagementView.java new file mode 100644 index 0000000..12a98d7 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/DataManagementView.java @@ -0,0 +1,50 @@ +package de.thpeetz.kontor.views; + +import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.services.DataManagementService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Scope; + +import java.io.File; + +@Slf4j +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = "common/import", layout = MainLayout.class) +@PageTitle("Import Data | Kontor") +public class DataManagementView extends VerticalLayout { + + DataManagementService service; + + public DataManagementView(DataManagementService service) { + this.service = service; + File uploadFolder = getUploadFolder(); + UploadArea uploadArea = new UploadArea(uploadFolder); + Checkbox pruneTables = new Checkbox("Prune Table"); + ImportArea importArea = new ImportArea(uploadFolder, pruneTables, service); + + uploadArea.getUploadField().addSucceededListener(e -> { + uploadArea.hideErrorField(); + importArea.processFiles(); + uploadArea.getUploadField().clearFileList(); + }); + + add(uploadArea, pruneTables, importArea); + } + + private File getUploadFolder() { + File folder = new File("uploaded-files"); + if (!folder.exists()) { + folder.mkdirs(); + } + return folder; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/EmailView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/EmailView.java new file mode 100644 index 0000000..6b5ac1b --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/EmailView.java @@ -0,0 +1,222 @@ +package de.thpeetz.kontor.views; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.List; +import java.util.Properties; + +import javax.mail.Address; +import javax.mail.Folder; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.NoSuchProviderException; +import javax.mail.Session; +import javax.mail.Store; +import javax.mail.internet.InternetAddress; + +import com.sun.mail.imap.IMAPFolder; +import com.vaadin.flow.component.Composite; +import com.vaadin.flow.component.accordion.Accordion; +import com.vaadin.flow.component.html.Paragraph; +import com.vaadin.flow.component.html.Span; +import com.vaadin.flow.component.menubar.MenuBar; +import com.vaadin.flow.component.messages.MessageList; +import com.vaadin.flow.component.messages.MessageListItem; +import com.vaadin.flow.component.orderedlayout.FlexComponent.Alignment; +import com.vaadin.flow.component.orderedlayout.FlexComponent.JustifyContentMode; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.sidenav.SideNav; +import com.vaadin.flow.component.sidenav.SideNavItem; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.router.RouteAlias; +import com.vaadin.flow.server.auth.AnonymousAllowed; +import com.vaadin.flow.theme.lumo.LumoUtility.Gap; + +import de.thpeetz.kontor.data.mailclient.MailAccount; +import de.thpeetz.kontor.services.MailService; +import de.thpeetz.kontor.views.common.MainLayout; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@PageTitle("Email") +@AnonymousAllowed +@Route(value = "mail", layout = MainLayout.class) +@RouteAlias(value = "kontor/mail", layout = MainLayout.class) +public class EmailView extends Composite { + + MenuBar menuBar = new MenuBar(); + Accordion accordion = new Accordion(); + SideNav folderList = new SideNav(); + MailService mailService; + + public EmailView(MailService mailService) { + this.mailService = mailService; + configureView(); + updateFolderList(); + } + + private void updateFolderList() { + List accounts = mailService.findAllMailAccounts(); + MailAccount account = accounts.get(0); + + Properties properties = new Properties(); + properties.put(String.format("mail.%s.host", account.getProtocol()), account.getHost()); + properties.put(String.format("mail.%s.port", account.getProtocol()), account.getPort().toString()); + properties.put("mail.imap.starttls.enable", "true"); + + Session session = Session.getDefaultInstance(properties); + Store store; + try { + store = session.getStore(account.getProtocol()); + store.connect(account.getUserName(), account.getPassword()); + Folder rootFolder = store.getDefaultFolder(); + Folder[] folders = rootFolder.list(); + for (Folder value : folders) { + SideNavItem folder = addSubFolder(value); + folderList.addItem(folder); + } + log.info("{} folders found", folders.length); + Folder folder = store.getFolder("INBOX"); + IMAPFolder imapFolder = (IMAPFolder) folder; + imapFolder.open(Folder.READ_ONLY); + Message[] messages = imapFolder.getMessages(); + log.info("Folder {} opened", folder.getFullName()); + //TODO int messageCount = folder.getMessageCount(); + log.info("{} messages found", messages.length); + for (Message message : messages) { + log.info("Message {}: {}, {}, {}", message.getMessageNumber(), message.getSubject(), message.getReceivedDate(), message.getSentDate()); + //log.info("Message: {}", message.getAllRecipients()); + //TODO Address[] addresses; + printAddress(message.getRecipients(Message.RecipientType.TO)); + printAddress(message.getRecipients(Message.RecipientType.CC)); + printAddress(message.getRecipients(Message.RecipientType.BCC)); + } + store.close(); + log.info("Connection closed"); + } catch (NoSuchProviderException e) { + throw new RuntimeException(e); + } catch (MessagingException e) { + throw new RuntimeException(e); + } + } + + private void printAddress(Address[] addresses) { + if (addresses != null) { + for (Address address: addresses) { + log.info("Address {}: {}", address.getType(), address.toString()); + InternetAddress internetAddress = (InternetAddress)address; + log.info("InternetAddress {}: {}", internetAddress.getPersonal(), internetAddress.getAddress()); + } + } + } + + private SideNavItem addSubFolder(Folder mailFolder) throws MessagingException { + log.debug("addSubFolder: {}", mailFolder.getName()); + Span counter = new Span(String.valueOf(mailFolder.getMessageCount())); + counter.getElement().getThemeList().add("badge contrast pill"); + counter.getElement().setAttribute("aria-label", String.format("%d unread messages", mailFolder.getMessageCount())); + SideNavItem folder = new SideNavItem(mailFolder.getName()); + folder.setSuffixComponent(counter); + Folder[] folders = mailFolder.list(); + log.info("{} subfolders found", folders.length); + for (Folder value : folders) { + SideNavItem subFolder = addSubFolder(value); + folder.addItem(subFolder); + } + return folder; + } + + private void configureView() { + HorizontalLayout layoutMenubar = new HorizontalLayout(); + HorizontalLayout layoutRow2 = new HorizontalLayout(); + VerticalLayout layoutColumn2 = new VerticalLayout(); + VerticalLayout layoutColumn3 = new VerticalLayout(); + MessageList messageList = new MessageList(); + VerticalLayout layoutColumn4 = new VerticalLayout(); + Paragraph textMedium = new Paragraph(); + getContent().setWidth("100%"); + getContent().getStyle().set("flex-grow", "1"); + layoutMenubar.addClassName(Gap.MEDIUM); + layoutMenubar.setWidth("100%"); + layoutMenubar.setHeight("min-content"); + menuBar.setWidth("min-content"); + setMenuBarSampleData(menuBar); + layoutRow2.addClassName(Gap.MEDIUM); + layoutRow2.setWidth("100%"); + layoutRow2.getStyle().set("flex-grow", "1"); + layoutColumn2.getStyle().set("flex-grow", "1"); + accordion.setWidth("100%"); + setAccordionSampleData(accordion); + layoutColumn3.setHeightFull(); + layoutRow2.setFlexGrow(1.0, layoutColumn3); + layoutColumn3.setWidth("100%"); + layoutColumn3.getStyle().set("flex-grow", "1"); + layoutColumn3.setJustifyContentMode(JustifyContentMode.START); + layoutColumn3.setAlignItems(Alignment.START); + messageList.setWidth("100%"); + setMessageListSampleData(messageList); + layoutColumn4.setWidthFull(); + layoutColumn3.setFlexGrow(1.0, layoutColumn4); + layoutColumn4.setWidth("100%"); + layoutColumn4.getStyle().set("flex-grow", "1"); + textMedium.setText( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + textMedium.setWidth("100%"); + textMedium.getStyle().set("font-size", "var(--lumo-font-size-m)"); + getContent().add(layoutMenubar); + layoutMenubar.add(menuBar); + getContent().add(layoutRow2); + layoutRow2.add(layoutColumn2); + layoutColumn2.add(folderList); + layoutRow2.add(layoutColumn3); + layoutColumn3.add(messageList); + layoutColumn3.add(layoutColumn4); + layoutColumn4.add(textMedium); + } + + private void setMenuBarSampleData(MenuBar menuBar) { + menuBar.addItem("View"); + menuBar.addItem("Edit"); + menuBar.addItem("Share"); + menuBar.addItem("Move"); + } + + private void setAccordionSampleData(Accordion accordion) { + Span name = new Span("Sophia Williams"); + Span email = new Span("sophia.williams@company.com"); + Span phone = new Span("(501) 555-9128"); + VerticalLayout personalInformationLayout = new VerticalLayout(name, email, phone); + personalInformationLayout.setSpacing(false); + personalInformationLayout.setPadding(false); + accordion.add("Personal information", personalInformationLayout); + Span street = new Span("4027 Amber Lake Canyon"); + Span zipCode = new Span("72333-5884 Cozy Nook"); + Span city = new Span("Arkansas"); + VerticalLayout billingAddressLayout = new VerticalLayout(); + billingAddressLayout.setSpacing(false); + billingAddressLayout.setPadding(false); + billingAddressLayout.add(street, zipCode, city); + accordion.add("Billing address", billingAddressLayout); + Span cardBrand = new Span("Mastercard"); + Span cardNumber = new Span("1234 5678 9012 3456"); + Span expiryDate = new Span("Expires 06/21"); + VerticalLayout paymentLayout = new VerticalLayout(); + paymentLayout.setSpacing(false); + paymentLayout.setPadding(false); + paymentLayout.add(cardBrand, cardNumber, expiryDate); + accordion.add("Payment", paymentLayout); + } + + private void setMessageListSampleData(MessageList messageList) { + MessageListItem message1 = new MessageListItem("Nature does not hurry, yet everything gets accomplished.", + LocalDateTime.now().minusDays(1).toInstant(ZoneOffset.UTC), "Matt Mambo"); + message1.setUserColorIndex(1); + MessageListItem message2 = new MessageListItem( + "Using your talent, hobby or profession in a way that makes you contribute with something good to this world is truly the way to go.", + LocalDateTime.now().minusMinutes(55).toInstant(ZoneOffset.UTC), "Linsey Listy"); + message2.setUserColorIndex(2); + messageList.setItems(message1, message2); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/ImportArea.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/ImportArea.java new file mode 100644 index 0000000..94aa935 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/ImportArea.java @@ -0,0 +1,112 @@ +package de.thpeetz.kontor.views; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.JsonNodeType; +import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.html.H4; +import com.vaadin.flow.component.html.Paragraph; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; + +import de.thpeetz.kontor.services.DataManagementService; +import lombok.extern.slf4j.Slf4j; +import org.json.simple.parser.ParseException; + +import java.io.*; +import java.util.*; + +@Slf4j +public class ImportArea extends VerticalLayout { + + protected File uploadFolder; + DataManagementService service; + boolean pruneTables = false; + + public ImportArea(File uploadFolder, Checkbox pruneTablesCheckbox, DataManagementService service) { + this.uploadFolder = uploadFolder; + this.service = service; + this.pruneTables = pruneTablesCheckbox.isEnabled(); + setMargin(true); + } + + public void processFiles() { + removeAll(); + if (pruneTables) { + add(new Paragraph("prune all tables")); + } + add(new H4("Process file")); + + for (File file: uploadFolder.listFiles()) { + add(new Paragraph("reading " + file.getName())); + try { + processFile(file); + } catch (ParseException e) { + throw new RuntimeException(e); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + private void processFile(File file) throws FileNotFoundException, IOException, ParseException { + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode node = objectMapper.readTree(file); + log.info("parsing: {}, {}", node.getNodeType(), node.size()); + Iterator fieldNamesIterator = node.fieldNames(); + while (fieldNamesIterator.hasNext()) { + String fieldName = fieldNamesIterator.next(); + parseRoot(node, fieldName); + } + } + + private void parseRoot(JsonNode parentNode, String field) { + JsonNode node = parentNode.get(field); + String nodeType = String.valueOf(node.getNodeType()); + if (nodeType.equals("ARRAY")) { + log.info(" {}: {}", field, node.size()); + Iterator elements = node.elements(); + while (elements.hasNext()) { + JsonNode subNode = elements.next(); + String status = parseNode(subNode, field); + add(new Paragraph(status)); + } + } else { + log.info("unknown type: {}", nodeType); + } + } + + private String parseNode(JsonNode node, String nodeName) { + Map fields = parseFields(node); + return service.getEntry(nodeName, fields); + } + + private Map parseFields(JsonNode node) { + Map fields = new HashMap<>(); + node.fieldNames().forEachRemaining(field -> { + + JsonNode value = node.get(field); + log.debug("type: {}", value.getNodeType()); + JsonNodeType nodeType = value.getNodeType(); + switch (nodeType) { + case NUMBER: + fields.put(field, String.valueOf(value.intValue())); + break; + case STRING: + String stringValue = value.textValue(); + if (stringValue.contains("\"")) { + log.debug("remove double quotes"); + String stripped = stringValue.substring(1, stringValue.length()-1); + fields.put(field, stripped); + } + fields.put(field, value.textValue()); + break; + default: + log.debug("no implementation for type {}", nodeType.name()); + } + }); + log.debug("fields: {}", fields); + return fields; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/UploadArea.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/UploadArea.java new file mode 100644 index 0000000..618a23d --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/UploadArea.java @@ -0,0 +1,58 @@ +package de.thpeetz.kontor.views; + +import com.vaadin.flow.component.html.Span; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.upload.MultiFileReceiver; +import com.vaadin.flow.component.upload.Receiver; +import com.vaadin.flow.component.upload.Upload; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; + +@Slf4j +public class UploadArea extends VerticalLayout { + + @Getter + private final Upload uploadField; + private final Span errorField; + + public UploadArea(File uploadFolder) { + uploadField = new Upload(createFileReceiver(uploadFolder)); + uploadField.setMaxFiles(1); + uploadField.setMaxFileSize(2*1024*1024); + + errorField = new Span(); + errorField.setVisible(false); + errorField.getStyle().set("color", "red"); + + uploadField.addFailedListener(e -> showErrorMessage(e.getReason().getMessage())); + uploadField.addFileRejectedListener(e -> showErrorMessage(e.getErrorMessage())); + + add(uploadField, errorField); + } + + public void hideErrorField() { + errorField.setVisible(false); + } + + private Receiver createFileReceiver(File uploadFolder) { + return (MultiFileReceiver) (filename, mimetype) -> { + File file = new File(uploadFolder, filename); + try { + return new FileOutputStream(file); + } + catch (FileNotFoundException fnfe) { + log.info(fnfe.getStackTrace().toString()); + return null; + } + }; + } + + private void showErrorMessage(String message) { + errorField.setVisible(true); + errorField.setText(message); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/AdminLayout.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/AdminLayout.java new file mode 100644 index 0000000..6f42e4e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/AdminLayout.java @@ -0,0 +1,43 @@ +package de.thpeetz.kontor.views.admin; + +import com.vaadin.flow.component.applayout.AppLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.theme.lumo.LumoUtility; + +import de.thpeetz.kontor.constants.AdminConstants; +import de.thpeetz.kontor.security.SecurityService; +import de.thpeetz.kontor.services.AdminService; +import de.thpeetz.kontor.views.common.KontorLayoutUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.info.BuildProperties; + +@Slf4j +public class AdminLayout extends AppLayout { + + @SuppressWarnings("unused") + private final AdminService adminService; + + @SuppressWarnings("unused") + private final SecurityService securityService; + + @SuppressWarnings("unused") + private final BuildProperties buildProperties; + + public AdminLayout(AdminService adminService, SecurityService securityService, BuildProperties buildProperties) { + this.adminService = adminService; + this.securityService = securityService; + this.buildProperties = buildProperties; + + KontorLayoutUtil layout = new KontorLayoutUtil(this, adminService, securityService, buildProperties); + layout.setSecondaryNavigation(getSecondaryNavigation()); + layout.createHeader(AdminConstants.ADMIN_TITLE); + } + + private HorizontalLayout getSecondaryNavigation() { + HorizontalLayout navigation = new HorizontalLayout(); + navigation.addClassNames(LumoUtility.JustifyContent.CENTER, LumoUtility.Gap.SMALL, LumoUtility.Height.MEDIUM); + navigation.add(AdminConstants.getProfileNavigation(), AdminConstants.getPermissionNavigation(), + AdminConstants.getAuthorizationNavigation()); + return navigation; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/AssignmentForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/AssignmentForm.java new file mode 100644 index 0000000..0c719f8 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/AssignmentForm.java @@ -0,0 +1,112 @@ +package de.thpeetz.kontor.views.admin; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.admin.Assignment; +import de.thpeetz.kontor.data.admin.Permission; +import de.thpeetz.kontor.data.admin.Profile; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AssignmentForm extends FormLayout { + + ComboBox profile = new ComboBox<>("Proile"); + ComboBox permission = new ComboBox<>("Permission"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Assignment.class); + + public AssignmentForm(List profiles, List permissions) { + addClassName("assignment-form"); + binder.bindInstanceFields(this); + + profile.setItems(profiles); + profile.setItemLabelGenerator(Profile::getUserName); + permission.setItems(permissions); + permission.setItemLabelGenerator(Permission::getName); + add(profile, permission, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setAssignment(Assignment assignment) { + binder.setBean(assignment); + } + + public abstract static class AssignmentFormEvent extends ComponentEvent { + private Assignment assignment; + + protected AssignmentFormEvent(AssignmentForm source, Assignment assignment) { + super(source, false); + this.assignment = assignment; + } + + public Assignment getAssignment() { + return assignment; + } + } + + public static class SaveEvent extends AssignmentFormEvent { + SaveEvent(AssignmentForm source, Assignment assignment) { + super(source, assignment); + } + } + + public static class DeleteEvent extends AssignmentFormEvent { + DeleteEvent(AssignmentForm source, Assignment assignment) { + super(source, assignment); + } + } + + public static class CloseEvent extends AssignmentFormEvent { + CloseEvent(AssignmentForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/AssignmentView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/AssignmentView.java new file mode 100644 index 0000000..b81fc34 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/AssignmentView.java @@ -0,0 +1,114 @@ +package de.thpeetz.kontor.views.admin; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; + +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.AdminConstants; +import de.thpeetz.kontor.data.admin.Assignment; +import de.thpeetz.kontor.services.AdminService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.RolesAllowed; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@SpringComponent +@Scope("prototype") +@RolesAllowed("ROLE_ADMIN") +@Route(value = AdminConstants.ASSIGNMENT_ROUTE, layout = MainLayout.class) +@PageTitle("Authorization | Admin | Kontor") +public class AssignmentView extends VerticalLayout { + + Grid grid = new Grid<>(Assignment.class); + AssignmentForm form; + AdminService service; + + public AssignmentView(AdminService service) { + this.service = service; + addClassName("assignment-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("assignment-grid"); + grid.setSizeFull(); + grid.setColumns("profile.userName", "permission.name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editAssignment(event.getValue())); + } + + private void configureForm() { + form = new AssignmentForm(service.findAllProfiles(), service.findAllPermissions()); + form.setWidth("25em"); + form.addSaveListener(this::saveAssignment); + form.addDeleteListener(this::deleteAssignment); + form.addCloseListener(e -> closeEditor()); + } + + private void saveAssignment(AssignmentForm.SaveEvent event) { + Assignment assignment = event.getAssignment(); + service.saveAssignment(assignment); + updateList(); + closeEditor(); + } + + private void deleteAssignment(AssignmentForm.DeleteEvent event) { + service.deleteAssignment(event.getAssignment()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + Button addAuthorizationMaxtrixButton = new Button("Add permission", click -> addAssignment()); + HorizontalLayout toolbar = new HorizontalLayout(addAuthorizationMaxtrixButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editAssignment(Assignment assignment) { + if (assignment == null) { + closeEditor(); + } else { + form.setAssignment(assignment); + form.setVisible(true); + addClassName("editing"); + } + } + + public void closeEditor() { + form.setAssignment(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addAssignment() { + grid.asSingleSelect().clear(); + editAssignment(new Assignment()); + } + + private void updateList() { + grid.setItems(service.findAllAssignments()); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/LoginView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/LoginView.java new file mode 100644 index 0000000..07f6650 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/LoginView.java @@ -0,0 +1,51 @@ +package de.thpeetz.kontor.views.admin; + +import org.springframework.security.core.context.SecurityContextHolder; + +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.html.Span; +import com.vaadin.flow.component.login.LoginForm; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.BeforeEnterEvent; +import com.vaadin.flow.router.BeforeEnterObserver; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.server.auth.AnonymousAllowed; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Route("login") +@PageTitle("Login | Vaadin Kontor") +@AnonymousAllowed +public class LoginView extends VerticalLayout implements BeforeEnterObserver { + + private final LoginForm login = new LoginForm(); + + public LoginView() { + addClassName("login-view"); + setSizeFull(); + setAlignItems(Alignment.CENTER); + setJustifyContentMode(JustifyContentMode.CENTER); + + login.setAction("login"); + + add(new H1("Vaadin Kontor")); + add(new Span("Username: user, Password: password")); + add(new Span("Username: admin, Password: password")); + add(login); + } + + @Override + public void beforeEnter(BeforeEnterEvent beforeEnterEvent) { + log.info("beforeEnter: {}", beforeEnterEvent.getLocation()); + log.info("beforeEnter: {}", SecurityContextHolder.getContext().getAuthentication()); + // inform the user about an authentication error + if (beforeEnterEvent.getLocation() + .getQueryParameters() + .getParameters() + .containsKey("error")) { + login.setError(true); + } + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/PermissionForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/PermissionForm.java new file mode 100644 index 0000000..c2fccb6 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/PermissionForm.java @@ -0,0 +1,102 @@ +package de.thpeetz.kontor.views.admin; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.admin.Permission; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PermissionForm extends FormLayout { + + TextField name = new TextField("Role name"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Permission.class); + + public PermissionForm() { + addClassName("permission-form"); + binder.bindInstanceFields(this); + add(name, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setPermission(Permission permission) { + binder.setBean(permission); + } + + public abstract static class PermissionFormEvent extends ComponentEvent { + private Permission permission; + + protected PermissionFormEvent(PermissionForm source, Permission permission) { + super(source, false); + this.permission = permission; + } + + public Permission getPermission() { + return permission; + } + } + + public static class SaveEvent extends PermissionFormEvent { + SaveEvent(PermissionForm source, Permission permission) { + super(source, permission); + } + } + + public static class DeleteEvent extends PermissionFormEvent { + DeleteEvent(PermissionForm source, Permission permission) { + super(source, permission); + } + } + + public static class CloseEvent extends PermissionFormEvent { + CloseEvent(PermissionForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/PermissionView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/PermissionView.java new file mode 100644 index 0000000..c7f1505 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/PermissionView.java @@ -0,0 +1,119 @@ +package de.thpeetz.kontor.views.admin; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.AdminConstants; +import de.thpeetz.kontor.data.admin.Permission; +import de.thpeetz.kontor.services.AdminService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.RolesAllowed; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@SpringComponent +@Scope("prototype") +@RolesAllowed("ROLE_ADMIN") +@Route(value = AdminConstants.PERMISSION_ROUTE, layout = MainLayout.class) +@PageTitle("Permissions | Admin | Kontor") +public class PermissionView extends VerticalLayout { + + Grid grid = new Grid<>(Permission.class); + TextField filterText = new TextField(); + PermissionForm form; + AdminService service; + + public PermissionView(AdminService service) { + this.service = service; + addClassName("permission-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("permission-grid"); + grid.setSizeFull(); + grid.setColumns("name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editPermission(event.getValue())); + } + + private void configureForm() { + form = new PermissionForm(); + form.setWidth("25em"); + form.addSaveListener(this::savePermission); + form.addDeleteListener(this::deletePermission); + form.addCloseListener(e -> closeEditor()); + } + + private void savePermission(PermissionForm.SaveEvent event) { + service.savePermission(event.getPermission()); + updateList(); + closeEditor(); + } + + private void deletePermission(PermissionForm.DeleteEvent event) { + service.deletePermission(event.getPermission()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by user name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + Button addUserButton = new Button("Add user", click -> addPermission()); + HorizontalLayout toolbar = new HorizontalLayout(filterText, addUserButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editPermission(Permission permission) { + if (permission == null) { + closeEditor(); + } else { + form.setPermission(permission); + form.setVisible(true); + addClassName("editing"); + } + } + + public void closeEditor() { + form.setPermission(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addPermission() { + grid.asSingleSelect().clear(); + editPermission(new Permission()); + } + + private void updateList() { + grid.setItems(service.findAllPermissions(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/ProfileForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/ProfileForm.java new file mode 100644 index 0000000..5053683 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/ProfileForm.java @@ -0,0 +1,144 @@ +package de.thpeetz.kontor.views.admin; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.checkbox.CheckboxGroup; +import com.vaadin.flow.component.checkbox.CheckboxGroupVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.EmailField; +import com.vaadin.flow.component.textfield.PasswordField; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.admin.Permission; +import de.thpeetz.kontor.data.admin.Profile; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +@Slf4j +public class ProfileForm extends FormLayout { + + TextField userName = new TextField("User name"); + PasswordField password = new PasswordField("Password"); + EmailField email = new EmailField("Email"); + TextField firstName = new TextField("First name"); + TextField lastName = new TextField("Last name"); + Checkbox enabled = new Checkbox("Enabled"); + String originalPassword; + + CheckboxGroup permissionList = new CheckboxGroup<>("Permissions"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Profile.class); + + public ProfileForm() { + addClassName("profile-form"); + binder.bindInstanceFields(this); + add(userName, password, email, firstName, lastName, enabled, configurePermissionsGroup(), createButtonsLayout()); + } + + private CheckboxGroup configurePermissionsGroup() { + permissionList.addThemeVariants(CheckboxGroupVariant.LUMO_VERTICAL); + permissionList.setItemLabelGenerator(Permission::getName); + permissionList.addValueChangeListener(event -> { + log.debug("permissions changed: {}", event); + }); + return permissionList; + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new ProfileForm.DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new ProfileForm.CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new ProfileForm.SaveEvent(this, binder.getBean())); + } + } + + public void setProfile(Profile profile) { + binder.setBean(profile); + //log.debug("UserForm.setUser: {}", user); + if (profile != null) { + this.originalPassword = profile.getPassword(); + } else { + this.originalPassword = null; + } + } + + public void setPermissions(List permissions, Profile profile) { + permissionList.setItems(permissions); + profile.getAssignments().stream().forEach(assignment -> { + permissionList.select(assignment.getPermission()); + }); + } + + public boolean hasPasswordChanged(Profile profile) { + return !originalPassword.equals(profile.getPassword()); + } + + public abstract static class ProfileFormEvent extends ComponentEvent { + private Profile profile; + + protected ProfileFormEvent(ProfileForm source, Profile profile) { + super(source, false); + this.profile = profile; + } + + public Profile getProfile() { + return profile; + } + } + + public static class SaveEvent extends ProfileForm.ProfileFormEvent { + SaveEvent(ProfileForm source, Profile profile) { + super(source, profile); + } + } + + public static class DeleteEvent extends ProfileForm.ProfileFormEvent { + DeleteEvent(ProfileForm source, Profile profile) { + super(source, profile); + } + } + + public static class CloseEvent extends ProfileForm.ProfileFormEvent { + CloseEvent(ProfileForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(ProfileForm.DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(ProfileForm.SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(ProfileForm.CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/ProfileView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/ProfileView.java new file mode 100644 index 0000000..117f5dc --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/ProfileView.java @@ -0,0 +1,136 @@ +package de.thpeetz.kontor.views.admin; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.data.admin.Permission; +import de.thpeetz.kontor.data.admin.Profile; +import de.thpeetz.kontor.services.KontorUserDetailsService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.RolesAllowed; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.security.crypto.password.PasswordEncoder; + +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@SpringComponent +@Scope("prototype") +@RolesAllowed("ROLE_ADMIN") +@Route(value = "admin/profile", layout = MainLayout.class) +@PageTitle("Profile | Admin | Kontor") +public class ProfileView extends VerticalLayout { + + Grid grid = new Grid<>(Profile.class); + TextField filterText = new TextField(); + ProfileForm form; + KontorUserDetailsService service; + + @Autowired + PasswordEncoder passwordEncoder; + + public ProfileView(KontorUserDetailsService service) { + this.service = service; + addClassName("profile-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("profile-grid"); + grid.setSizeFull(); + grid.setColumns("userName", "email", "firstName", "lastName", "enabled"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editProfile(event.getValue())); + } + + private void configureForm() { + form = new ProfileForm(); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveProfile); + form.addDeleteListener(this::deleteProfile); + form.addCloseListener(e -> closeEditor()); + } + + private void saveProfile(ProfileForm.SaveEvent event) { + Profile profile = event.getProfile(); + log.debug("ProfileView.saveProfile: {}", profile); + List permissions = form.permissionList.getSelectedItems().stream().collect(Collectors.toList()); + log.info("selected permissions: {}", permissions); + if (form.hasPasswordChanged(profile)) { + profile.setPassword(passwordEncoder.encode(profile.getPassword())); + log.debug("password changed for profile {}", profile); + } + service.saveProfile(profile, permissions); + updateList(); + closeEditor(); + } + + private void deleteProfile(ProfileForm.DeleteEvent event) { + service.deleteProfile(event.getProfile()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by user name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + Button addProfileButton = new Button("Add profile", click -> addProfile()); + HorizontalLayout toolbar = new HorizontalLayout(filterText, addProfileButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editProfile(Profile profile) { + if (profile == null) { + closeEditor(); + } else { + form.setProfile(profile); + form.setPermissions(service.findAllPermissions(), profile); + form.setVisible(true); + addClassName("editing"); + } + } + + public void closeEditor() { + form.setProfile(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addProfile() { + grid.asSingleSelect().clear(); + editProfile(new Profile()); + } + + private void updateList() { + grid.setItems(service.findAllProfiles(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/UserProfileView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/UserProfileView.java new file mode 100644 index 0000000..35f5113 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/admin/UserProfileView.java @@ -0,0 +1,76 @@ +package de.thpeetz.kontor.views.admin; + +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; + +import de.thpeetz.kontor.data.admin.Profile; +import de.thpeetz.kontor.security.SecurityService; +import de.thpeetz.kontor.services.AdminService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Route(value = "user/profile", layout = MainLayout.class) +@PermitAll +@PageTitle("Profile | User | Kontor") +public class UserProfileView extends VerticalLayout { + + @SuppressWarnings("unused") + private SecurityService securityService; + + @SuppressWarnings("unused") + private AdminService adminService; + + TextField firstName = new TextField("First name"); + TextField lastName = new TextField("Last name"); + + Button save = new Button("Save"); + Button close = new Button("Cancel"); + Binder binder = new BeanValidationBinder<>(Profile.class); + + public UserProfileView(AdminService adminService, SecurityService securityService) { + this.adminService = adminService; + this.securityService = securityService; + binder.bindInstanceFields(this); + + add(firstName, lastName, createButtonsLayout()); + securityService.getAuthenticatedUser().ifPresent(user -> { + log.info("UserProfileView: {}", user.getUsername()); + binder.setBean(adminService.getProfile(user.getUsername())); + }); + + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + close.addClickListener(event -> closeView()); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + log.info("update user profile"); + } + } + + private void closeView() { + log.info("close user profile view"); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/ArticleForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/ArticleForm.java new file mode 100644 index 0000000..54f80e3 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/ArticleForm.java @@ -0,0 +1,105 @@ +package de.thpeetz.kontor.views.bookshelf; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.bookshelf.Article; +import de.thpeetz.kontor.data.bookshelf.Author; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ArticleForm extends FormLayout { + + TextField title = new TextField("Title"); + Grid author = new Grid<>(Author.class); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder
    binder = new BeanValidationBinder<>(Article.class); + + public ArticleForm() { + addClassName("article-form"); + binder.bindInstanceFields(this); + + add(title, author, createButtonsLayout()); + } + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new ArticleForm.DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new ArticleForm.CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new ArticleForm.SaveEvent(this, binder.getBean())); + } + } + + public void setArticle(Article article) { + binder.setBean(article); + } + + public abstract static class ArticleFormEvent extends ComponentEvent { + private Article article; + + protected ArticleFormEvent(ArticleForm source, Article article) { + super(source, false); + this.article = article; + } + + public Article getArticle() { + return article; + } + } + + public static class SaveEvent extends ArticleForm.ArticleFormEvent { + SaveEvent(ArticleForm source, Article article) { + super(source, article); + } + } + + public static class DeleteEvent extends ArticleForm.ArticleFormEvent { + DeleteEvent(ArticleForm source, Article article) { + super(source, article); + } + } + + public static class CloseEvent extends ArticleForm.ArticleFormEvent { + CloseEvent(ArticleForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(ArticleForm.DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(ArticleForm.SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(ArticleForm.CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/ArticleView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/ArticleView.java new file mode 100644 index 0000000..e378a48 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/ArticleView.java @@ -0,0 +1,123 @@ +package de.thpeetz.kontor.views.bookshelf; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.BookshelfConstants; +import de.thpeetz.kontor.data.bookshelf.Article; +import de.thpeetz.kontor.services.BookshelfService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; +import lombok.Getter; +import org.springframework.context.annotation.Scope; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = BookshelfConstants.ARTICLE_ROUTE, layout = MainLayout.class) +@PageTitle("Article | Bookshelf | Kontor") +public class ArticleView extends VerticalLayout { + + @Getter + Grid
    grid = new Grid<>(Article.class); + TextField filterText = new TextField(); + @Getter + ArticleForm form; + BookshelfService service; + + public ArticleView(BookshelfService service) { + this.service = service; + addClassName("article-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("article-grid"); + grid.setSizeFull(); + grid.setColumns("title"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editArticle(event.getValue())); + } + + private void configureForm() { + form = new ArticleForm(); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveArticle); + form.addDeleteListener(this::deleteArticle); + form.addCloseListener(e -> closeEditor()); + } + + private void saveArticle(ArticleForm.SaveEvent event) { + service.saveArticle(event.getArticle()); + updateList(); + closeEditor(); + } + + private void deleteArticle(ArticleForm.DeleteEvent event) { + service.deleteArticle(event.getArticle()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by title or isbn..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addArticleButton = new Button("Add article"); + addArticleButton.addClickListener(click -> addArticle()); + + HorizontalLayout toolbar = new HorizontalLayout(filterText, addArticleButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editArticle(Article article) { + if (article == null) { + closeEditor(); + } else { + form.setArticle(article); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setArticle(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addArticle() { + grid.asSingleSelect().clear(); + editArticle(new Article()); + } + + public void updateList() { + grid.setItems(service.findAllArticles(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/AuthorForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/AuthorForm.java new file mode 100644 index 0000000..4d170c7 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/AuthorForm.java @@ -0,0 +1,116 @@ +package de.thpeetz.kontor.views.bookshelf; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.listbox.ListBox; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.bookshelf.Author; +import de.thpeetz.kontor.data.bookshelf.Book; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +@Slf4j +public class AuthorForm extends FormLayout { + + TextField firstName = new TextField("First Name"); + TextField lastName = new TextField("Last Name"); + ListBox books = new ListBox<>(); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Author.class); + + public AuthorForm() { + addClassName("author-form"); + binder.bindInstanceFields(this); + + books.setHeight("100px"); + //books.setColumns("title", "publisher.name"); + //books.getColumns().forEach(col -> col.setAutoWidth(true)); + add(firstName, lastName, books, createButtonsLayout()); + } + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new AuthorForm.DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new AuthorForm.CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new AuthorForm.SaveEvent(this, binder.getBean())); + } + } + + public void setAuthor(Author author) { + binder.setBean(author); + } + + public void setBooks(List books) { + log.info("setting Books: ", books); + this.books.setItems(books); + } + + public abstract static class AuthorFormEvent extends ComponentEvent { + private Author author; + + protected AuthorFormEvent(AuthorForm source, Author author) { + super(source, false); + this.author = author; + } + + public Author getAuthor() { + return author; + } + } + + public static class SaveEvent extends AuthorForm.AuthorFormEvent { + SaveEvent(AuthorForm source, Author author) { + super(source, author); + } + } + + public static class DeleteEvent extends AuthorForm.AuthorFormEvent { + DeleteEvent(AuthorForm source, Author author) { + super(source, author); + } + } + + public static class CloseEvent extends AuthorForm.AuthorFormEvent { + CloseEvent(AuthorForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(AuthorForm.DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(AuthorForm.SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(AuthorForm.CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/AuthorView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/AuthorView.java new file mode 100644 index 0000000..1a66294 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/AuthorView.java @@ -0,0 +1,132 @@ +package de.thpeetz.kontor.views.bookshelf; + +import java.util.stream.Collectors; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.BookshelfConstants; +import de.thpeetz.kontor.data.bookshelf.Author; +import de.thpeetz.kontor.data.bookshelf.BookAuthor; +import de.thpeetz.kontor.services.BookshelfService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = BookshelfConstants.AUTHOR_ROUTE, layout = MainLayout.class) +@PageTitle("Author | Bookshelf | Kontor") +public class AuthorView extends VerticalLayout { + + Grid grid = new Grid<>(Author.class); + TextField filterText = new TextField(); + AuthorForm form; + BookshelfService service; + + public AuthorView(BookshelfService service) { + this.service = service; + addClassName("author-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + public Grid getGrid() { + return grid; + } + + public AuthorForm getForm() { + return form; + } + + private void configureGrid() { + grid.addClassName("author-grid"); + grid.setSizeFull(); + grid.setColumns("firstName", "lastName"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editAuthor(event.getValue())); + } + + private void configureForm() { + form = new AuthorForm(); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveAuthor); + form.addDeleteListener(this::deleteAuthor); + form.addCloseListener(e -> closeEditor()); + } + private void saveAuthor(AuthorForm.SaveEvent event) { + service.saveAuthor(event.getAuthor()); + updateList(); + closeEditor(); + } + + private void deleteAuthor(AuthorForm.DeleteEvent event) { + service.deleteAuthor(event.getAuthor()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addAuthorButton = new Button("Add author"); + addAuthorButton.addClickListener(click -> addAuthor()); + + HorizontalLayout toolbar = new HorizontalLayout(filterText, addAuthorButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editAuthor(Author author) { + if (author == null) { + closeEditor(); + } else { + form.setAuthor(author); + form.setBooks(author.getBookAuthors().stream().map(BookAuthor::getBook).collect(Collectors.toList())); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setAuthor(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addAuthor() { + grid.asSingleSelect().clear(); + editAuthor(new Author()); + } + + public void updateList() { + grid.setItems(service.findAllAuthors(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/BookForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/BookForm.java new file mode 100644 index 0000000..5988958 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/BookForm.java @@ -0,0 +1,112 @@ +package de.thpeetz.kontor.views.bookshelf; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.IntegerField; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.bookshelf.Book; +import de.thpeetz.kontor.data.bookshelf.BookshelfPublisher; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +@Slf4j +public class BookForm extends FormLayout { + + TextField title = new TextField("Title"); + TextField isbn = new TextField("ISBN"); + IntegerField year = new IntegerField("Year"); + ComboBox publisher = new ComboBox<>("Publisher"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Book.class); + + public BookForm(List publishers) { + addClassName("book-form"); + binder.bindInstanceFields(this); + + publisher.setItems(publishers); + publisher.setItemLabelGenerator(BookshelfPublisher::getName); + add(title, isbn, year, publisher, createButtonsLayout()); + } + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new BookForm.DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new BookForm.CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new BookForm.SaveEvent(this, binder.getBean())); + } + } + + public void setBook(Book book) { + binder.setBean(book); + } + + public abstract static class BookFormEvent extends ComponentEvent { + private Book book; + + protected BookFormEvent(BookForm source, Book book) { + super(source, false); + this.book = book; + } + + public Book getBook() { + return book; + } + } + + public static class SaveEvent extends BookForm.BookFormEvent { + SaveEvent(BookForm source, Book book) { + super(source, book); + } + } + + public static class DeleteEvent extends BookForm.BookFormEvent { + DeleteEvent(BookForm source, Book book) { + super(source, book); + } + } + + public static class CloseEvent extends BookForm.BookFormEvent { + CloseEvent(BookForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(BookForm.DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(BookForm.SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(BookForm.CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/BookView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/BookView.java new file mode 100644 index 0000000..f0275e7 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/BookView.java @@ -0,0 +1,124 @@ +package de.thpeetz.kontor.views.bookshelf; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.BookshelfConstants; +import de.thpeetz.kontor.data.bookshelf.Book; +import de.thpeetz.kontor.services.BookshelfService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; +import lombok.Getter; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = BookshelfConstants.BOOK_ROUTE, layout = MainLayout.class) +@PageTitle("Book | Bookshelf | Kontor") +public class BookView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(Book.class); + TextField filterText = new TextField(); + @Getter + BookForm form; + BookshelfService service; + + public BookView(BookshelfService service) { + this.service = service; + addClassName("book-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("book-grid"); + grid.setSizeFull(); + grid.setColumns("title", "isbn", "publisher.name", "year"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editBook(event.getValue())); + } + + private void configureForm() { + form = new BookForm(service.findAllPublishers(null)); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveBook); + form.addDeleteListener(this::deleteBook); + form.addCloseListener(e -> closeEditor()); + } + + private void saveBook(BookForm.SaveEvent event) { + service.saveBook(event.getBook()); + updateList(); + closeEditor(); + } + + private void deleteBook(BookForm.DeleteEvent event) { + service.deleteBook(event.getBook()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by title or isbn..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addBookButton = new Button("Add book"); + addBookButton.addClickListener(click -> addBook()); + + HorizontalLayout toolbar = new HorizontalLayout(filterText, addBookButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editBook(Book book) { + if (book == null) { + closeEditor(); + } else { + form.setBook(book); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setBook(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addBook() { + grid.asSingleSelect().clear(); + editBook(new Book()); + } + + public void updateList() { + grid.setItems(service.findAllBooks(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/BookshelfLayout.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/BookshelfLayout.java new file mode 100644 index 0000000..bdd7ff3 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/BookshelfLayout.java @@ -0,0 +1,41 @@ +package de.thpeetz.kontor.views.bookshelf; + +import com.vaadin.flow.component.applayout.AppLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.theme.lumo.LumoUtility; + +import de.thpeetz.kontor.constants.BookshelfConstants; +import de.thpeetz.kontor.security.SecurityService; +import de.thpeetz.kontor.services.AdminService; +import de.thpeetz.kontor.views.common.KontorLayoutUtil; +import org.springframework.boot.info.BuildProperties; + +public class BookshelfLayout extends AppLayout { + + @SuppressWarnings("unused") + private final AdminService adminService; + + @SuppressWarnings("unused") + private final SecurityService securityService; + + @SuppressWarnings("unused") + private final BuildProperties buildProperties; + + public BookshelfLayout(AdminService adminService, SecurityService securityService, BuildProperties buildProperties) { + this.adminService = adminService; + this.securityService = securityService; + this.buildProperties = buildProperties; + + KontorLayoutUtil layout = new KontorLayoutUtil(this, adminService, securityService, buildProperties); + layout.setSecondaryNavigation(getSecondaryNavigation()); + layout.createHeader(BookshelfConstants.BOOKSHELF); + } + + private HorizontalLayout getSecondaryNavigation() { + HorizontalLayout navigation = new HorizontalLayout(); + navigation.addClassNames(LumoUtility.JustifyContent.CENTER, LumoUtility.Gap.SMALL, LumoUtility.Height.MEDIUM); + navigation.add(BookshelfConstants.getBookLink(), BookshelfConstants.getArticleLink(), + BookshelfConstants.getPublisherLink(), BookshelfConstants.getAuthorLink()); + return navigation; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/BookshelfPublisherView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/BookshelfPublisherView.java new file mode 100644 index 0000000..1e4bf19 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/BookshelfPublisherView.java @@ -0,0 +1,130 @@ +package de.thpeetz.kontor.views.bookshelf; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.BookshelfConstants; +import de.thpeetz.kontor.data.bookshelf.BookshelfPublisher; +import de.thpeetz.kontor.services.BookshelfService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = BookshelfConstants.PUBLISHER_ROUTE, layout = MainLayout.class) +@PageTitle("Publisher | Bookshelf | Kontor") +public class BookshelfPublisherView extends VerticalLayout { + + Grid grid = new Grid<>(BookshelfPublisher.class); + TextField filterText = new TextField(); + PublisherForm form; + + BookshelfService service; + + public BookshelfPublisherView(BookshelfService service) { + this.service = service; + addClassName("publisher-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("publisher-grid"); + grid.setSizeFull(); + grid.setColumns("name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editPublisher(event.getValue())); + } + + private void configureForm() { + form = new PublisherForm(); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::savePublisher); + form.addDeleteListener(this::deletePublisher); + form.addCloseListener(e -> closeEditor()); + } + + private void savePublisher(PublisherForm.SaveEvent event) { + service.savePublisher(event.getPublisher()); + updateList(); + closeEditor(); + } + + private void deletePublisher(PublisherForm.DeleteEvent event) { + service.deletePublisher(event.getPublisher()); + updateList(); + closeEditor(); + } + + public Grid getGrid() { + return grid; + } + + public PublisherForm getForm() { + return form; + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addPublisherButton = new Button("Add publisher"); + addPublisherButton.addClickListener(click -> addPublisher()); + + HorizontalLayout toolbar = new HorizontalLayout(filterText, addPublisherButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editPublisher(BookshelfPublisher publisher) { + if (publisher == null) { + closeEditor(); + } else { + form.setPublisher(publisher); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setPublisher(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addPublisher() { + grid.asSingleSelect().clear(); + editPublisher(new BookshelfPublisher()); + } + + public void updateList() { + grid.setItems(service.findAllPublishers(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/PublisherForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/PublisherForm.java new file mode 100644 index 0000000..7f23ca0 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/bookshelf/PublisherForm.java @@ -0,0 +1,108 @@ +package de.thpeetz.kontor.views.bookshelf; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.bookshelf.BookshelfPublisher; + +public class PublisherForm extends FormLayout { + private TextField name = new TextField("Name"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder(BookshelfPublisher.class); + + public PublisherForm() { + addClassName("publisher-form"); + binder.bindInstanceFields(this); + + add(name, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public TextField getName() { + return name; + } + + public void setName(TextField name) { + this.name = name; + } + + public void setPublisher(BookshelfPublisher publisher) { + binder.setBean(publisher); + } + + public abstract static class PublisherFormEvent extends ComponentEvent { + private BookshelfPublisher publisher; + + protected PublisherFormEvent(PublisherForm source, BookshelfPublisher publisher) { + super(source, false); + this.publisher = publisher; + } + + public BookshelfPublisher getPublisher() { + return publisher; + } + } + + public static class SaveEvent extends PublisherFormEvent { + SaveEvent(PublisherForm source, BookshelfPublisher publisher) { + super(source, publisher); + } + } + + public static class DeleteEvent extends PublisherFormEvent { + DeleteEvent(PublisherForm source, BookshelfPublisher publisher) { + super(source, publisher); + } + } + + public static class CloseEvent extends PublisherFormEvent { + CloseEvent(PublisherForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ArtistForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ArtistForm.java new file mode 100644 index 0000000..f38b0a3 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ArtistForm.java @@ -0,0 +1,117 @@ +package de.thpeetz.kontor.views.comics; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.comics.Artist; +import de.thpeetz.kontor.data.comics.ComicWork; +import lombok.*; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ArtistForm extends FormLayout { + + public TextField name = new TextField("Name"); + TextField weblink = new TextField("Link"); + Grid comicWorks = new Grid<>(ComicWork.class); + + public Button save = new Button("Save"); + public Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Artist.class); + + public ArtistForm() { + addClassName("artist-form"); + binder.bindInstanceFields(this); + + comicWorks.setColumns("workType.name", "comic.title"); + comicWorks.getColumnByKey("workType.name").setHeader("Work type"); + comicWorks.getColumnByKey("comic.title").setHeader("Comic"); + comicWorks.getColumns().forEach(col -> col.setAutoWidth(true)); + add(name, weblink, comicWorks, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setArtist(Artist artist) { + binder.setBean(artist); + } + + public void setComicWorks(List works) { + log.info("Setting comic works: {}", works); + this.comicWorks.setItems(works); + } + + @Getter + public abstract static class ArtistFormEvent extends ComponentEvent { + private final Artist artist; + + protected ArtistFormEvent(ArtistForm source, Artist artist) { + super(source, false); + this.artist = artist; + } + + } + + public static class SaveEvent extends ArtistFormEvent { + SaveEvent(ArtistForm source, Artist artist) { + super(source, artist); + } + } + + public static class DeleteEvent extends ArtistFormEvent { + DeleteEvent(ArtistForm source, Artist artist) { + super(source, artist); + } + } + + public static class CloseEvent extends ArtistFormEvent { + CloseEvent(ArtistForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ArtistView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ArtistView.java new file mode 100644 index 0000000..d5c2c4e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ArtistView.java @@ -0,0 +1,124 @@ +package de.thpeetz.kontor.views.comics; + +import lombok.Getter; +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.data.comics.Artist; +import de.thpeetz.kontor.services.ComicService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = "artist", layout = MainLayout.class) +@PageTitle("Artist | Comics | Kontor") +public class ArtistView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(Artist.class); + TextField filterText = new TextField(); + @Getter + ArtistForm form; + ComicService service; + + public ArtistView(ComicService service) { + this.service = service; + addClassName("artist-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("artist-grid"); + grid.setSizeFull(); + grid.setColumns("name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editArtist(event.getValue())); + } + + private void configureForm() { + form = new ArtistForm(); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveArtist); + form.addDeleteListener(this::deleteArtist); + form.addCloseListener(e -> closeEditor()); + } + + private void saveArtist(ArtistForm.SaveEvent event) { + service.saveArtist(event.getArtist()); + updateList(); + closeEditor(); + } + + private void deleteArtist(ArtistForm.DeleteEvent event) { + service.deleteArtist(event.getArtist()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addArtistButton = new Button("Add artist"); + addArtistButton.addClickListener(click -> addArtist()); + + HorizontalLayout toolbar = new HorizontalLayout(filterText, addArtistButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editArtist(Artist artist) { + if (artist == null) { + closeEditor(); + } else { + form.setArtist(artist); + form.setComicWorks(artist.getComicWorks()); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setArtist(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addArtist() { + grid.asSingleSelect().clear(); + editArtist(new Artist()); + } + + public void updateList() { + grid.setItems(service.findAllArtists(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicForm.java new file mode 100644 index 0000000..10acf18 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicForm.java @@ -0,0 +1,130 @@ +package de.thpeetz.kontor.views.comics; + +import java.util.List; + +import lombok.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.ComicWork; +import de.thpeetz.kontor.data.comics.Publisher; + +public class ComicForm extends FormLayout { + + private static final Logger log = LoggerFactory.getLogger(ComicForm.class); + + public TextField title = new TextField("Title"); + ComboBox publisher = new ComboBox<>("Publisher"); + TextField weblink = new TextField("Link"); + Checkbox currentOrder = new Checkbox("Current order"); + Checkbox completed = new Checkbox("Completed"); + Grid comicWorks = new Grid<>(ComicWork.class); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Comic.class); + + public ComicForm(List publishers) { + addClassName("comic-form"); + binder.bindInstanceFields(this); + + publisher.setItems(publishers); + publisher.setItemLabelGenerator(Publisher::getName); + // comicWorks.addClassName("comic-works-grid"); + // comicWorks.setSizeFull(); + comicWorks.setColumns("workType.name", "artist.name"); + comicWorks.getColumnByKey("workType.name").setHeader("Work type"); + comicWorks.getColumnByKey("artist.name").setHeader("Artist"); + comicWorks.getColumns().forEach(col -> col.setAutoWidth(true)); + add(title, publisher, weblink, currentOrder, completed, comicWorks, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setComic(Comic comic) { + binder.setBean(comic); + } + + public void setComicWorks(List works) { + log.info("Setting comic works: {}", works); + comicWorks.setItems(works); + } + + @Getter + public abstract static class ComicFormEvent extends ComponentEvent { + private final Comic comic; + + protected ComicFormEvent(ComicForm source, Comic comic) { + super(source, false); + this.comic = comic; + } + + } + + public static class SaveEvent extends ComicFormEvent { + SaveEvent(ComicForm source, Comic comic) { + super(source, comic); + } + } + + public static class DeleteEvent extends ComicFormEvent { + DeleteEvent(ComicForm source, Comic comic) { + super(source, comic); + } + } + + public static class CloseEvent extends ComicFormEvent { + CloseEvent(ComicForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicLayout.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicLayout.java new file mode 100644 index 0000000..b44c2ca --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicLayout.java @@ -0,0 +1,49 @@ +package de.thpeetz.kontor.views.comics; + +import com.vaadin.flow.component.applayout.AppLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.theme.lumo.LumoUtility; + +import de.thpeetz.kontor.constants.ComicConstants; +import de.thpeetz.kontor.security.SecurityService; +import de.thpeetz.kontor.services.AdminService; +import de.thpeetz.kontor.views.common.KontorLayoutUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.info.BuildProperties; + +/** + * Represents a custom layout for the comic view in the application. + * This layout extends the AppLayout class. + */ +@Slf4j +public class ComicLayout extends AppLayout { + + @SuppressWarnings("unused") + private final AdminService adminService; + + @SuppressWarnings("unused") + private final SecurityService securityService; + + @SuppressWarnings("unused") + private final BuildProperties buildProperties; + + public ComicLayout(AdminService adminService, SecurityService securityService, BuildProperties buildProperties) { + this.adminService = adminService; + this.securityService = securityService; + this.buildProperties = buildProperties; + + KontorLayoutUtil layout = new KontorLayoutUtil(this, adminService, securityService, buildProperties); + layout.setSecondaryNavigation(getSecondaryNavigation()); + layout.createHeader(ComicConstants.COMICS); + } + + private HorizontalLayout getSecondaryNavigation() { + HorizontalLayout navigation = new HorizontalLayout(); + navigation.addClassNames(LumoUtility.JustifyContent.CENTER, LumoUtility.Gap.SMALL, LumoUtility.Height.MEDIUM); + navigation.add(ComicConstants.getComicLink(), ComicConstants.getPublisherLink(), ComicConstants.getIssueLink(), + ComicConstants.getTradePaperbackLink(), ComicConstants.getStoryArcLink(), + ComicConstants.getVolumeLink(), ComicConstants.getArtistLink(), ComicConstants.getComicWorkLink(), + ComicConstants.getWorktypeLink()); + return navigation; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicView.java new file mode 100644 index 0000000..b8669f5 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicView.java @@ -0,0 +1,160 @@ +package de.thpeetz.kontor.views.comics; + +import de.thpeetz.kontor.views.common.ColumnToggleContextMenu; +import de.thpeetz.kontor.views.common.MainLayout; +import de.thpeetz.kontor.views.common.SearchFilterField; +import de.thpeetz.kontor.views.common.StatusIcon; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.ComicConstants; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.services.ComicService; +import jakarta.annotation.security.PermitAll; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = ComicConstants.COMICS_ROUTE, layout = MainLayout.class) +@PageTitle("Comic | Comics | Kontor") +public class ComicView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(Comic.class, false); + Grid.Column idColumn = grid.addColumn(Comic::getId) + .setHeader("ID").setResizable(true).setSortable(true); + Grid.Column createdColumn = grid.addColumn(Comic::getCreatedDate) + .setHeader("Erstellt").setResizable(true).setSortable(true); + Grid.Column modifiedColumn = grid.addColumn(Comic::getLastModifiedDate) + .setHeader("Geändert").setResizable(true).setSortable(true); + Grid.Column titleColumn = grid.addColumn(Comic::getTitle) + .setHeader("Titel").setResizable(true).setSortable(true); + Grid.Column publisherColumn = grid.addColumn(Comic::getPublisherName) + .setHeader("Verlag").setResizable(true).setSortable(true); + Grid.Column currentOrderColumn = grid.addComponentColumn(comic -> StatusIcon.create(comic.getCurrentOrder())) + .setHeader("Bestellung").setWidth("6rem").setSortable(true); + Grid.Column completedColumn = grid.addComponentColumn(comic -> StatusIcon.create(comic.getCompleted())) + .setHeader("Abgeschlossen").setWidth("6rem").setSortable(true); + Grid.Column weblinkColumn = grid.addColumn(Comic::getWeblink) + .setHeader("Link").setResizable(true).setSortable(true); + SearchFilterField searchFilterField = new SearchFilterField(); + @Getter + ComicForm form; + ComicService service; + + public ComicView(ComicService service) { + this.service = service; + addClassName("comic-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("comic-grid"); + grid.setSizeFull(); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editComic(event.getValue())); + } + + private void configureForm() { + form = new ComicForm(service.findAllPublishers(null)); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveComic); + form.addDeleteListener(this::deleteComic); + form.addCloseListener(e -> closeEditor()); + } + + private void saveComic(ComicForm.SaveEvent event) { + service.saveComic(event.getComic()); + updateList(); + closeEditor(); + } + + private void deleteComic(ComicForm.DeleteEvent event) { + service.deleteComic(event.getComic()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + searchFilterField.addFilter("Bestellung"); + searchFilterField.addFilter("Abgeschlossen"); + searchFilterField.addValueChangeListener(e -> updateList()); + + Button addComicButton = new Button("Add comic"); + addComicButton.addClickListener(click -> addComic()); + + Button menuButton = new Button("Show/Hide Columns"); + menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); + columnToggleContextMenu.addColumnToggleItem(idColumn); + columnToggleContextMenu.addColumnToggleItem(createdColumn); + columnToggleContextMenu.addColumnToggleItem(modifiedColumn); + columnToggleContextMenu.addColumnToggleItem(titleColumn); + columnToggleContextMenu.addColumnToggleItem(publisherColumn); + columnToggleContextMenu.addColumnToggleItem(currentOrderColumn); + columnToggleContextMenu.addColumnToggleItem(completedColumn); + columnToggleContextMenu.addColumnToggleItem(weblinkColumn); + HorizontalLayout toolbar = new HorizontalLayout(searchFilterField, addComicButton, menuButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editComic(Comic comic) { + if (comic == null) { + closeEditor(); + } else { + form.setComic(comic); + if (comic.getComicWorks() == null) { + log.info("No comic works"); + } else { + log.info("Comic works sze: {}", comic.getComicWorks().size()); + } + form.setComicWorks(comic.getComicWorks()); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setComic(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addComic() { + grid.asSingleSelect().clear(); + editComic(new Comic()); + } + + public void updateList() { + grid.setItems(service.findAllComicsByFilter(searchFilterField.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicWorkForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicWorkForm.java new file mode 100644 index 0000000..743d4a1 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicWorkForm.java @@ -0,0 +1,113 @@ +package de.thpeetz.kontor.views.comics; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.comics.Artist; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.ComicWork; +import de.thpeetz.kontor.data.comics.Worktype; + +public class ComicWorkForm extends FormLayout { + public ComboBox comic = new ComboBox<>("Comic"); + ComboBox artist = new ComboBox<>("Artist"); + ComboBox workType = new ComboBox<>("Worktype"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(ComicWork.class); + + public ComicWorkForm(List comics, List artists, List workTypes) { + addClassName("comicwork-form"); + binder.bindInstanceFields(this); + + comic.setItems(comics); + comic.setItemLabelGenerator(Comic::getTitle); + artist.setItems(artists); + artist.setItemLabelGenerator(Artist::getName); + workType.setItems(workTypes); + workType.setItemLabelGenerator(Worktype::getName); + add(comic, artist, workType, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setComicWork(ComicWork comicWork) { + binder.setBean(comicWork); + } + + public abstract static class ComicWorkFormEvent extends ComponentEvent { + private ComicWork comicWork; + + protected ComicWorkFormEvent(ComicWorkForm source, ComicWork comicWork) { + super(source, false); + this.comicWork = comicWork; + } + + public ComicWork getComicWork() { + return comicWork; + } + } + + public static class SaveEvent extends ComicWorkFormEvent { + SaveEvent(ComicWorkForm source, ComicWork comicWork) { + super(source, comicWork); + } + } + + public static class DeleteEvent extends ComicWorkFormEvent { + DeleteEvent(ComicWorkForm source, ComicWork comicWork) { + super(source, comicWork); + } + } + + public static class CloseEvent extends ComicWorkFormEvent { + CloseEvent(ComicWorkForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicWorkView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicWorkView.java new file mode 100644 index 0000000..ac3d494 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/ComicWorkView.java @@ -0,0 +1,122 @@ +package de.thpeetz.kontor.views.comics; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.ComicConstants; +import de.thpeetz.kontor.data.comics.ComicWork; +import de.thpeetz.kontor.services.ComicService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = ComicConstants.COMICWORK_ROUTE, layout = MainLayout.class) +@PageTitle("ComicWork | Comics | Kontor") +public class ComicWorkView extends VerticalLayout { + + Grid grid = new Grid<>(ComicWork.class); + ComicWorkForm form; + ComicService service; + + public ComicWorkView(ComicService service) { + this.service = service; + addClassName("comicWork-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + public Grid getGrid() { + return grid; + } + + private void configureGrid() { + grid.addClassName("comic-grid"); + grid.setSizeFull(); + grid.setColumns("comic.title", "artist.name", "workType.name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editComicWork(event.getValue())); + } + + public ComicWorkForm getForm() { + return form; + } + + private void configureForm() { + form = new ComicWorkForm(service.findAllComics(null), service.findAllArtists(null), + service.findAllWorktypes(null)); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveComicWork); + form.addDeleteListener(this::deleteComicWork); + form.addCloseListener(e -> closeEditor()); + } + + private void saveComicWork(ComicWorkForm.SaveEvent event) { + service.saveComicWork(event.getComicWork()); + updateList(); + closeEditor(); + } + + private void deleteComicWork(ComicWorkForm.DeleteEvent event) { + service.deleteComicWork(event.getComicWork()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + Button addComicButton = new Button("Add ComicWork"); + addComicButton.addClickListener(click -> addComicWork()); + + HorizontalLayout toolbar = new HorizontalLayout(addComicButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editComicWork(ComicWork comicWork) { + if (comicWork == null) { + closeEditor(); + } else { + form.setComicWork(comicWork); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setComicWork(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addComicWork() { + grid.asSingleSelect().clear(); + editComicWork(new ComicWork()); + } + + public void updateList() { + grid.setItems(service.findAllComicWorks()); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/IssueForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/IssueForm.java new file mode 100644 index 0000000..5322aa4 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/IssueForm.java @@ -0,0 +1,151 @@ +package de.thpeetz.kontor.views.comics; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.grid.*; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; + +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.Issue; +import de.thpeetz.kontor.data.comics.IssueWork; +import de.thpeetz.kontor.data.comics.Volume; +import de.thpeetz.kontor.views.common.YearMonthField; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class IssueForm extends FormLayout { + + ComboBox comic = new ComboBox<>("Comic"); + ComboBox volume = new ComboBox<>("Volume"); + public TextField issueNumber = new TextField("Issue number"); + TextField title = new TextField("Full Title"); + YearMonthField publishedOn = new YearMonthField(); + Checkbox isRead = new Checkbox("Read"); + Checkbox inStock = new Checkbox("In stock"); + Grid issueWorks = new Grid<>(IssueWork.class); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Issue.class); + + public IssueForm(List comics, List volumes) { + addClassName("issue-form"); + binder.bindInstanceFields(this); + + comic.setItems(comics); + comic.addValueChangeListener(event -> { + if (event.getValue() != null) { + volume.setItems(event.getValue().getVolumes()); + } else { + volume.clear(); + } + }); + comic.setItemLabelGenerator(Comic::getTitle); + volume.setItems(volumes); + volume.setItemLabelGenerator(Volume::getName); + issueWorks.setColumns("workType.name", "artist.name"); + issueWorks.getColumnByKey("workType.name").setHeader("Work type"); + issueWorks.getColumnByKey("artist.name").setHeader("Artist"); + issueWorks.getColumns().forEach(col -> col.setAutoWidth(true)); + add(comic, volume, issueNumber, title, publishedOn, isRead, inStock, issueWorks, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setIssue(Issue issue) { + log.debug("IssueForm.setIssue: {}", issue); + Volume issueVolume = null; + if (issue != null) { + issueVolume = issue.getVolume(); + } + binder.setBean(issue); + if (issue != null && issue.getComic() != null) { + log.debug("populate list of volumes"); + volume.setItems(issue.getComic().getVolumes()); + log.debug("Issue.Volume= {}", issue.getVolume()); + if (issueVolume != null) { + log.debug("Set volume {} for issue: {}", issueVolume, issue); + volume.setValue(issueVolume); + } + } + } + + public void setIssueWorks(List works) { + log.info("Setting issue works: {}", works); + issueWorks.setItems(works); + } + + public abstract static class IssueFormEvent extends ComponentEvent { + @lombok.Getter + private final Issue issue; + + protected IssueFormEvent(IssueForm source, Issue issue) { + super(source, false); + this.issue = issue; + } + } + + public static class SaveEvent extends IssueFormEvent { + SaveEvent(IssueForm source, Issue issue) { + super(source, issue); + } + } + + public static class DeleteEvent extends IssueFormEvent { + DeleteEvent(IssueForm source, Issue issue) { + super(source, issue); + } + } + + public static class CloseEvent extends IssueFormEvent { + CloseEvent(IssueForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/IssueView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/IssueView.java new file mode 100644 index 0000000..eca54ea --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/IssueView.java @@ -0,0 +1,186 @@ +package de.thpeetz.kontor.views.comics; + +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.grid.GridSortOrder; +import com.vaadin.flow.data.provider.SortDirection; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.ComicConstants; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.Issue; +import de.thpeetz.kontor.services.ComicService; +import de.thpeetz.kontor.views.common.ColumnToggleContextMenu; +import de.thpeetz.kontor.views.common.MainLayout; +import de.thpeetz.kontor.views.common.StatusIcon; +import jakarta.annotation.security.PermitAll; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = ComicConstants.ISSUE_ROUTE, layout = MainLayout.class) +@PageTitle("Issue | Comics | Kontor") +public class IssueView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(Issue.class, false); + Grid.Column idColumn = grid.addColumn(Issue::getId) + .setHeader("ID").setResizable(true).setSortable(true); + Grid.Column createdColumn = grid.addColumn(Issue::getCreatedDate) + .setHeader("Erstellt").setResizable(true).setSortable(true); + Grid.Column modifiedColumn = grid.addColumn(Issue::getLastModifiedDate) + .setHeader("Geändert").setResizable(true).setSortable(true); + Grid.Column versionColumn = grid.addColumn(Issue::getVersion) + .setHeader("Version").setResizable(true).setSortable(true); + Grid.Column titleColumn = grid.addColumn(Issue::getComicTitle) + .setHeader("Comic").setResizable(true).setSortable(true); + Grid.Column volumeColumn = grid.addColumn(Issue::getVolumeName) + .setHeader("Volume").setResizable(true).setSortable(true); + Grid.Column issueNumberColumn = grid.addColumn(Issue::getIssueNumber) + .setHeader("Heft Nummer").setResizable(true).setSortable(true); + Grid.Column issueTitleColumn = grid.addColumn(Issue::getTitle) + .setHeader("Full Title").setResizable(true).setSortable(true); + Grid.Column publishedOncolumn = grid.addColumn(Issue::getPublishedOn) + .setHeader("Published").setResizable(true).setSortable(true); + Grid.Column isReadColumn = grid.addComponentColumn(issueColumn -> StatusIcon.create(issueColumn.getIsRead())) + .setHeader("Gelesen?").setWidth("6rem").setSortable(true); + Grid.Column inStockColumn = grid + .addComponentColumn(issueColumn -> StatusIcon.create(issueColumn.getInStock())) + .setHeader("Im Bestand?").setWidth("6rem").setSortable(true); + ComboBox comicFilter = new ComboBox<>("Comic"); + @Getter + IssueForm form; + ComicService service; + + public IssueView(ComicService service) { + this.service = service; + addClassName("issue-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("issue-grid"); + grid.setSizeFull(); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + idColumn.setVisible(false); + createdColumn.setVisible(false); + modifiedColumn.setVisible(false); + versionColumn.setVisible(false); + grid.setMultiSort(true); + List> sortOrder = new ArrayList<>(); + sortOrder.add(new GridSortOrder(titleColumn, SortDirection.ASCENDING)); + sortOrder.add(new GridSortOrder(issueNumberColumn, SortDirection.ASCENDING)); + grid.sort(sortOrder); + grid.asSingleSelect().addValueChangeListener(event -> editIssue(event.getValue())); + } + + private void configureForm() { + form = new IssueForm(service.findAllComics(null), service.findAllVolumes()); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveIssue); + form.addDeleteListener(this::deleteIssue); + form.addCloseListener(e -> closeEditor()); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + comicFilter.setItems(service.findAllComics(null)); + comicFilter.setItemLabelGenerator(Comic::getTitle); + comicFilter.setClearButtonVisible(true); + comicFilter.addValueChangeListener(e -> updateList()); + + Button addIssueButton = new Button("Add issue"); + addIssueButton.addClickListener(click -> addIssue()); + + Button menuButton = new Button("Show/Hide Columns"); + menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); + columnToggleContextMenu.addColumnToggleItem(idColumn); + columnToggleContextMenu.addColumnToggleItem(createdColumn); + columnToggleContextMenu.addColumnToggleItem(modifiedColumn); + columnToggleContextMenu.addColumnToggleItem(versionColumn); + columnToggleContextMenu.addColumnToggleItem(titleColumn); + columnToggleContextMenu.addColumnToggleItem(volumeColumn); + columnToggleContextMenu.addColumnToggleItem(issueNumberColumn); + columnToggleContextMenu.addColumnToggleItem(issueTitleColumn); + columnToggleContextMenu.addColumnToggleItem(publishedOncolumn); + columnToggleContextMenu.addColumnToggleItem(isReadColumn); + columnToggleContextMenu.addColumnToggleItem(inStockColumn); + HorizontalLayout toolbar = new HorizontalLayout(comicFilter, addIssueButton, menuButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + private void saveIssue(IssueForm.SaveEvent event) { + service.saveIssue(event.getIssue()); + updateList(); + closeEditor(); + } + + private void deleteIssue(IssueForm.DeleteEvent event) { + service.deleteIssue(event.getIssue()); + updateList(); + closeEditor(); + } + + public void editIssue(Issue issue) { + if (issue == null) { + closeEditor(); + } else { + form.setIssue(issue); + if (issue.getIssueWorks() == null) { + log.info("No issue works"); + } else { + log.info("Issue works sze: {}", issue.getIssueWorks().size()); + } + form.setIssueWorks(issue.getIssueWorks()); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setIssue(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addIssue() { + grid.asSingleSelect().clear(); + editIssue(new Issue()); + } + + private void updateList() { + grid.setItems(service.findAllIssuesForComic(comicFilter.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/IssueWorkForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/IssueWorkForm.java new file mode 100644 index 0000000..077dab5 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/IssueWorkForm.java @@ -0,0 +1,115 @@ +package de.thpeetz.kontor.views.comics; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.comics.Artist; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.IssueWork; +import de.thpeetz.kontor.data.comics.Worktype; +import de.thpeetz.kontor.views.common.ComicIssueField; + +public class IssueWorkForm extends FormLayout { + ComicIssueField issue = new ComicIssueField("Issue"); + ComboBox artist = new ComboBox<>("Artist"); + ComboBox workType = new ComboBox<>("Worktype"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(IssueWork.class); + + public IssueWorkForm(List comics, List artists, List workTypes) { + addClassName("issuework-form"); + binder.bindInstanceFields(this); + + issue.setComics(comics); + //issue.setItems(issues); + //issue.setItemLabelGenerator(Issue::getIssueNumber); + artist.setItems(artists); + artist.setItemLabelGenerator(Artist::getName); + workType.setItems(workTypes); + workType.setItemLabelGenerator(Worktype::getName); + add(issue, artist, workType, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setIssueWork(IssueWork issueWork) { + binder.setBean(issueWork); + } + + public abstract static class IssueWorkFormEvent extends ComponentEvent { + private IssueWork issueWork; + + protected IssueWorkFormEvent(IssueWorkForm source, IssueWork issueWork) { + super(source, false); + this.issueWork = issueWork; + } + + public IssueWork getIssueWork() { + return issueWork; + } + } + + public static class SaveEvent extends IssueWorkFormEvent { + SaveEvent(IssueWorkForm source, IssueWork issueWork) { + super(source, issueWork); + } + } + + public static class DeleteEvent extends IssueWorkFormEvent { + DeleteEvent(IssueWorkForm source, IssueWork issueWork) { + super(source, issueWork); + } + } + + public static class CloseEvent extends IssueWorkFormEvent { + CloseEvent(IssueWorkForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/IssueWorkView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/IssueWorkView.java new file mode 100644 index 0000000..ecd9a1e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/IssueWorkView.java @@ -0,0 +1,118 @@ +package de.thpeetz.kontor.views.comics; + +import lombok.Getter; +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.ComicConstants; +import de.thpeetz.kontor.data.comics.Issue; +import de.thpeetz.kontor.data.comics.IssueWork; +import de.thpeetz.kontor.services.ComicService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = ComicConstants.ISSUEWORK_ROUTE, layout = MainLayout.class) +@PageTitle("IssueWork | Comics | Kontor") +public class IssueWorkView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(IssueWork.class); + @Getter + IssueWorkForm form; + ComicService service; + + public IssueWorkView(ComicService service) { + this.service = service; + addClassName("issueWork-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("issue-grid"); + grid.setSizeFull(); + grid.setColumns("issue.fullTitle", "artist.name", "workType.name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editIssueWork(event.getValue())); + } + + private void configureForm() { + form = new IssueWorkForm(service.findAllComics(null), service.findAllArtists(null), + service.findAllWorktypes(null)); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveIssueWork); + form.addDeleteListener(this::deleteIssueWork); + form.addCloseListener(e -> closeEditor()); + } + + private void saveIssueWork(IssueWorkForm.SaveEvent event) { + service.saveIssueWork(event.getIssueWork()); + updateList(); + closeEditor(); + } + + private void deleteIssueWork(IssueWorkForm.DeleteEvent event) { + service.deleteIssueWork(event.getIssueWork()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + Button addIssueButton = new Button("Add IssueWork"); + addIssueButton.addClickListener(click -> addIssueWork()); + + HorizontalLayout toolbar = new HorizontalLayout(addIssueButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editIssueWork(IssueWork issueWork) { + if (issueWork == null) { + closeEditor(); + } else { + form.setIssueWork(issueWork); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setIssueWork(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addIssueWork() { + grid.asSingleSelect().clear(); + editIssueWork(new IssueWork()); + } + + public void updateList() { + grid.setItems(service.findAllIssueWorks()); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/PublisherForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/PublisherForm.java new file mode 100644 index 0000000..8c13e56 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/PublisherForm.java @@ -0,0 +1,106 @@ +package de.thpeetz.kontor.views.comics; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.*; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.comics.Publisher; +import lombok.*; + +import java.util.*; + +public class PublisherForm extends FormLayout { + public TextField name = new TextField("Name"); + public TextField weblink = new TextField("Link"); + ComboBox parentCompany = new ComboBox<>("Parent Company"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Publisher.class); + + public PublisherForm(List publishers) { + addClassName("publisher-form"); + binder.bindInstanceFields(this); + + parentCompany.setItems(publishers); + parentCompany.setItemLabelGenerator(Publisher::getName); + add(name, weblink, parentCompany, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setPublisher(Publisher publisher) { + binder.setBean(publisher); + } + + @Getter + public abstract static class PublisherFormEvent extends ComponentEvent { + private final Publisher publisher; + + protected PublisherFormEvent(PublisherForm source, Publisher publisher) { + super(source, false); + this.publisher = publisher; + } + + } + + public static class SaveEvent extends PublisherFormEvent { + SaveEvent(PublisherForm source, Publisher publisher) { + super(source, publisher); + } + } + + public static class DeleteEvent extends PublisherFormEvent { + DeleteEvent(PublisherForm source, Publisher publisher) { + super(source, publisher); + } + } + + public static class CloseEvent extends PublisherFormEvent { + CloseEvent(PublisherForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/PublisherView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/PublisherView.java new file mode 100644 index 0000000..10ad849 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/PublisherView.java @@ -0,0 +1,150 @@ +package de.thpeetz.kontor.views.comics; + +import com.vaadin.flow.component.button.*; +import de.thpeetz.kontor.constants.ComicConstants; +import de.thpeetz.kontor.views.common.ColumnToggleContextMenu; +import de.thpeetz.kontor.views.common.MainLayout; +import de.thpeetz.kontor.views.common.StatusIcon; +import lombok.*; +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.data.comics.Publisher; +import de.thpeetz.kontor.services.ComicService; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = ComicConstants.PUBLISHER_ROUTE, layout = MainLayout.class) +@PageTitle("Publisher | Comics | Kontor") +public class PublisherView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(Publisher.class, false); + Grid.Column idColumn = grid.addColumn(Publisher::getId) + .setHeader("ID").setResizable(true).setSortable(true); + Grid.Column createdColumn = grid.addColumn(Publisher::getCreatedDate) + .setHeader("Erstellt").setResizable(true).setSortable(true); + Grid.Column modifiedColumn = grid.addColumn(Publisher::getLastModifiedDate) + .setHeader("Geändert").setResizable(true).setSortable(true); + Grid.Column nameColumn = grid.addColumn(Publisher::getName) + .setHeader("Titel").setResizable(true).setSortable(true); + Grid.Column parentCompanyColumn = grid.addColumn(Publisher::getParentCompanyName) + .setHeader("Parent Company").setResizable(true).setSortable(true); + Grid.Column imprintColumn = grid.addComponentColumn(publisher -> StatusIcon.create(publisher.getParentCompany() != null)) + .setHeader("Imprint").setWidth("6rem").setSortable(true); + Grid.Column weblinkColumn = grid.addColumn(Publisher::getWeblink) + .setHeader("Link").setResizable(true).setSortable(true); + TextField filterText = new TextField(); + @Getter + PublisherForm form; + + ComicService service; + + public PublisherView(ComicService service) { + this.service = service; + addClassName("publisher-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("publisher-grid"); + grid.setSizeFull(); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editPublisher(event.getValue())); + } + + private void configureForm() { + form = new PublisherForm(service.findAllPublishers(null)); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::savePublisher); + form.addDeleteListener(this::deletePublisher); + form.addCloseListener(e -> closeEditor()); + } + + private void savePublisher(PublisherForm.SaveEvent event) { + service.savePublisher(event.getPublisher()); + updateList(); + closeEditor(); + } + + private void deletePublisher(PublisherForm.DeleteEvent event) { + service.deletePublisher(event.getPublisher()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addPublisherButton = new Button("Add publisher"); + addPublisherButton.addClickListener(click -> addPublisher()); + + Button menuButton = new Button("Show/Hide Columns"); + menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); + columnToggleContextMenu.addColumnToggleItem(idColumn); + columnToggleContextMenu.addColumnToggleItem(createdColumn); + columnToggleContextMenu.addColumnToggleItem(modifiedColumn); + columnToggleContextMenu.addColumnToggleItem(nameColumn); + columnToggleContextMenu.addColumnToggleItem(parentCompanyColumn); + columnToggleContextMenu.addColumnToggleItem(imprintColumn); + columnToggleContextMenu.addColumnToggleItem(weblinkColumn); + HorizontalLayout toolbar = new HorizontalLayout(filterText, addPublisherButton, menuButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editPublisher(Publisher publisher) { + if (publisher == null) { + closeEditor(); + } else { + form.setPublisher(publisher); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setPublisher(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addPublisher() { + grid.asSingleSelect().clear(); + editPublisher(new Publisher()); + } + + public void updateList() { + grid.setItems(service.findAllPublishers(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/StoryArcForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/StoryArcForm.java new file mode 100644 index 0000000..6bac6c4 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/StoryArcForm.java @@ -0,0 +1,108 @@ +package de.thpeetz.kontor.views.comics; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.StoryArc; + +import java.util.List; + +public class StoryArcForm extends FormLayout { + + ComboBox comic = new ComboBox<>("Comic"); + public TextField name = new TextField("Story Arc Name"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(StoryArc.class); + + public StoryArcForm(List comics) { + addClassName("storyarc-form"); + binder.bindInstanceFields(this); + + comic.setItems(comics); + comic.setItemLabelGenerator(Comic::getTitle); + add(comic, name, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setStoryArc(StoryArc storyArc) { + binder.setBean(storyArc); + } + + public abstract static class StoryArcFormEvent extends ComponentEvent { + private StoryArc storyArc; + + protected StoryArcFormEvent(StoryArcForm source, StoryArc storyArc) { + super(source, false); + this.storyArc = storyArc; + } + + public StoryArc getStoryArc() { + return storyArc; + } + } + + public static class SaveEvent extends StoryArcFormEvent { + SaveEvent(StoryArcForm source, StoryArc storyArc) { + super(source, storyArc); + } + } + + public static class DeleteEvent extends StoryArcFormEvent { + DeleteEvent(StoryArcForm source, StoryArc storyArc) { + super(source, storyArc); + } + } + + public static class CloseEvent extends StoryArcFormEvent { + CloseEvent(StoryArcForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/StoryArcView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/StoryArcView.java new file mode 100644 index 0000000..79a3e80 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/StoryArcView.java @@ -0,0 +1,130 @@ +package de.thpeetz.kontor.views.comics; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.ComicConstants; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.StoryArc; +import de.thpeetz.kontor.services.ComicService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = ComicConstants.STORYARC_ROTE, layout = MainLayout.class) +@PageTitle("StoryArc | Comics | Kontor") +public class StoryArcView extends VerticalLayout { + + Grid grid = new Grid<>(StoryArc.class); + ComboBox comicFilter = new ComboBox<>("Comic"); + StoryArcForm form; + ComicService service; + + public StoryArcView(ComicService service) { + this.service = service; + addClassName("storyarc-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + public StoryArcForm getForm() { + return form; + } + + public Grid getGrid() { + return grid; + } + + private void configureGrid() { + grid.addClassName("storyarc-grid"); + grid.setSizeFull(); + grid.setColumns("comic.title", "name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editStoryArc(event.getValue())); + } + + private void configureForm() { + form = new StoryArcForm(service.findAllComics(null)); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveStoryArc); + form.addDeleteListener(this::deleteStoryArc); + form.addCloseListener(e -> closeEditor()); + } + + private void saveStoryArc(StoryArcForm.SaveEvent event) { + service.saveStoryArc(event.getStoryArc()); + updateList(); + closeEditor(); + } + + private void deleteStoryArc(StoryArcForm.DeleteEvent event) { + service.deleteStoryArc(event.getStoryArc()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + comicFilter.setItems(service.findAllComics(null)); + comicFilter.setItemLabelGenerator(Comic::getTitle); + comicFilter.addValueChangeListener(e -> updateList()); + comicFilter.setClearButtonVisible(true); + + Button addStoryArcButton = new Button("Add StoryArc", click -> addStoryArc()); + + HorizontalLayout toolbar = new HorizontalLayout(comicFilter, addStoryArcButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editStoryArc(StoryArc storyArc) { + if (storyArc == null) { + closeEditor(); + } else { + form.setStoryArc(storyArc); + form.setVisible(true); + addClassName("editing"); + } + } + + public void closeEditor() { + form.setStoryArc(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addStoryArc() { + grid.asSingleSelect().clear(); + editStoryArc(new StoryArc()); + } + + private void updateList() { + grid.setItems(service.findAllStoryArcsForComic(comicFilter.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/TradePaperBackForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/TradePaperBackForm.java new file mode 100644 index 0000000..cb2195d --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/TradePaperBackForm.java @@ -0,0 +1,109 @@ +package de.thpeetz.kontor.views.comics; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.TradePaperback; + +public class TradePaperBackForm extends FormLayout { + public TextField name = new TextField("Name"); + ComboBox comic = new ComboBox<>("Comic"); + TextField issueStart = new TextField("Issue Start"); + TextField issueEnd = new TextField("Issue End"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(TradePaperback.class); + + public TradePaperBackForm(List comics) { + addClassName("tradepaperback-form"); + binder.bindInstanceFields(this); + + comic.setItems(comics); + comic.setItemLabelGenerator(Comic::getTitle); + add(name, comic, issueStart, issueEnd, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setTradePaperBack(TradePaperback tradepaperback) { + binder.setBean(tradepaperback); + } + + public abstract static class TradePaperBackFormEvent extends ComponentEvent { + private TradePaperback tradepaperback; + + protected TradePaperBackFormEvent(TradePaperBackForm source, TradePaperback tradepaperback) { + super(source, false); + this.tradepaperback = tradepaperback; + } + + public TradePaperback getTradePaperBack() { + return tradepaperback; + } + } + + public static class SaveEvent extends TradePaperBackFormEvent { + SaveEvent(TradePaperBackForm source, TradePaperback tradepaperback) { + super(source, tradepaperback); + } + } + + public static class DeleteEvent extends TradePaperBackFormEvent { + DeleteEvent(TradePaperBackForm source, TradePaperback tradepaperback) { + super(source, tradepaperback); + } + } + + public static class CloseEvent extends TradePaperBackFormEvent { + CloseEvent(TradePaperBackForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/TradePaperbackView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/TradePaperbackView.java new file mode 100644 index 0000000..5862e63 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/TradePaperbackView.java @@ -0,0 +1,129 @@ +package de.thpeetz.kontor.views.comics; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.ComicConstants; +import de.thpeetz.kontor.data.comics.TradePaperback; +import de.thpeetz.kontor.services.ComicService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = ComicConstants.TPB_ROUTE, layout = MainLayout.class) +@PageTitle("TradePaperBack | Comics | Kontor") +public class TradePaperbackView extends VerticalLayout { + + Grid grid = new Grid<>(TradePaperback.class); + TextField filterText = new TextField(); + TradePaperBackForm form; + ComicService service; + + public TradePaperbackView(ComicService service) { + this.service = service; + addClassName("tradepaperback-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + public Grid getGrid() { + return grid; + } + + private void configureGrid() { + grid.addClassName("tradepaperback-grid"); + grid.setSizeFull(); + grid.setColumns("name", "comic.title", "issueStart", "issueEnd"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editTradePaperBack(event.getValue())); + } + + public TradePaperBackForm getForm() { + return form; + } + + private void configureForm() { + form = new TradePaperBackForm(service.findAllComics(null)); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveTradePaperBack); + form.addDeleteListener(this::deleteTradePaperBack); + form.addCloseListener(e -> closeEditor()); + } + + private void saveTradePaperBack(TradePaperBackForm.SaveEvent event) { + service.saveTradePaperBack(event.getTradePaperBack()); + updateList(); + closeEditor(); + } + + private void deleteTradePaperBack(TradePaperBackForm.DeleteEvent event) { + service.deleteTradePaperBack(event.getTradePaperBack()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addTradePaperBackButton = new Button("Add TradePaperBack"); + addTradePaperBackButton.addClickListener(click -> addTradePaperBack()); + + HorizontalLayout toolbar = new HorizontalLayout(filterText, addTradePaperBackButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editTradePaperBack(TradePaperback tradepaperback) { + if (tradepaperback == null) { + closeEditor(); + } else { + form.setTradePaperBack(tradepaperback); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setTradePaperBack(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addTradePaperBack() { + grid.asSingleSelect().clear(); + editTradePaperBack(new TradePaperback()); + } + + public void updateList() { + grid.setItems(service.findAllTradePaperbacks(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/VolumeForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/VolumeForm.java new file mode 100644 index 0000000..06dcf80 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/VolumeForm.java @@ -0,0 +1,108 @@ +package de.thpeetz.kontor.views.comics; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.Volume; + +public class VolumeForm extends FormLayout { + + ComboBox comic = new ComboBox<>("Comic"); + public TextField name = new TextField("Name"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Volume.class); + + public VolumeForm(List comics) { + addClassName("volume-form"); + binder.bindInstanceFields(this); + + comic.setItems(comics); + comic.setItemLabelGenerator(Comic::getTitle); + add(comic, name, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setVolume(Volume volume) { + binder.setBean(volume); + } + + public abstract static class VolumeFormEvent extends ComponentEvent { + private Volume volume; + + protected VolumeFormEvent(VolumeForm source, Volume volume) { + super(source, false); + this.volume = volume; + } + + public Volume getVolume() { + return volume; + } + } + + public static class SaveEvent extends VolumeFormEvent { + SaveEvent(VolumeForm source, Volume volume) { + super(source, volume); + } + } + + public static class DeleteEvent extends VolumeFormEvent { + DeleteEvent(VolumeForm source, Volume volume) { + super(source, volume); + } + } + + public static class CloseEvent extends VolumeFormEvent { + CloseEvent(VolumeForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/VolumeView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/VolumeView.java new file mode 100644 index 0000000..641f929 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/VolumeView.java @@ -0,0 +1,130 @@ +package de.thpeetz.kontor.views.comics; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.ComicConstants; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.Volume; +import de.thpeetz.kontor.services.ComicService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = ComicConstants.VOLUME_ROUTE, layout = MainLayout.class) +@PageTitle("Volume | Comics | Kontor") +public class VolumeView extends VerticalLayout { + + Grid grid = new Grid<>(Volume.class); + ComboBox comicFilter = new ComboBox<>("Comic"); + VolumeForm form; + ComicService service; + + public VolumeView(ComicService service) { + this.service = service; + addClassName("volume-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + public VolumeForm getForm() { + return form; + } + + public Grid getGrid() { + return grid; + } + + private void configureGrid() { + grid.addClassName("volume-grid"); + grid.setSizeFull(); + grid.setColumns("comic.title", "name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editVolume(event.getValue())); + } + + private void configureForm() { + form = new VolumeForm(service.findAllComics(null)); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveVolume); + form.addDeleteListener(this::deleteVolume); + form.addCloseListener(e -> closeEditor()); + } + + private void saveVolume(VolumeForm.SaveEvent event) { + service.saveVolume(event.getVolume()); + updateList(); + closeEditor(); + } + + private void deleteVolume(VolumeForm.DeleteEvent event) { + service.deleteVolume(event.getVolume()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + comicFilter.setItems(service.findAllComics(null)); + comicFilter.setItemLabelGenerator(Comic::getTitle); + comicFilter.addValueChangeListener(e -> updateList()); + comicFilter.setClearButtonVisible(true); + + Button addVolumeButton = new Button("Add Volume", click -> addVolume()); + + HorizontalLayout toolbar = new HorizontalLayout(comicFilter, addVolumeButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editVolume(Volume volume) { + if (volume == null) { + closeEditor(); + } else { + form.setVolume(volume); + form.setVisible(true); + addClassName("editing"); + } + } + + public void closeEditor() { + form.setVolume(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addVolume() { + grid.asSingleSelect().clear(); + editVolume(new Volume()); + } + + private void updateList() { + grid.setItems(service.findAllVolumesForComic(comicFilter.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/WorktypeForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/WorktypeForm.java new file mode 100644 index 0000000..d180cc8 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/WorktypeForm.java @@ -0,0 +1,121 @@ +package de.thpeetz.kontor.views.comics; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.comics.ComicWork; +import de.thpeetz.kontor.data.comics.Worktype; + +public class WorktypeForm extends FormLayout { + + private static final Logger log = LoggerFactory.getLogger(WorktypeForm.class); + + public TextField name = new TextField("Name"); + Grid comicWorks = new Grid<>(ComicWork.class); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Worktype.class); + + public WorktypeForm() { + addClassName("worktype-form"); + binder.bindInstanceFields(this); + + comicWorks.setColumns("comic.title", "artist.name"); + comicWorks.getColumnByKey("comic.title").setHeader("Comic"); + comicWorks.getColumnByKey("artist.name").setHeader("Artist"); + comicWorks.getColumns().forEach(col -> col.setAutoWidth(true)); + + add(name, comicWorks, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setWorktype(Worktype worktype) { + binder.setBean(worktype); + } + + public void setComicWorks(List works) { + log.info("Setting comic works: {}", works); + this.comicWorks.setItems(works); + } + + public abstract static class WorktypeFormEvent extends ComponentEvent { + private Worktype worktype; + + protected WorktypeFormEvent(WorktypeForm source, Worktype worktype) { + super(source, false); + this.worktype = worktype; + } + + public Worktype getWorktype() { + return worktype; + } + } + + public static class SaveEvent extends WorktypeFormEvent { + SaveEvent(WorktypeForm source, Worktype worktype) { + super(source, worktype); + } + } + + public static class DeleteEvent extends WorktypeFormEvent { + DeleteEvent(WorktypeForm source, Worktype worktype) { + super(source, worktype); + } + } + + public static class CloseEvent extends WorktypeFormEvent { + CloseEvent(WorktypeForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/WorktypeView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/WorktypeView.java new file mode 100644 index 0000000..5b9afd0 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/comics/WorktypeView.java @@ -0,0 +1,125 @@ +package de.thpeetz.kontor.views.comics; + +import lombok.*; +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.ComicConstants; +import de.thpeetz.kontor.data.comics.Worktype; +import de.thpeetz.kontor.services.ComicService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = ComicConstants.WORKTYPE_ROUTE, layout = MainLayout.class) +@PageTitle("Worktype | Comics | Kontor") +public class WorktypeView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(Worktype.class); + TextField filterText = new TextField(); + @Getter + WorktypeForm form; + ComicService service; + + public WorktypeView(ComicService service) { + this.service = service; + addClassName("worktype-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("worktype-grid"); + grid.setSizeFull(); + grid.setColumns("name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editWorktype(event.getValue())); + } + + private void configureForm() { + form = new WorktypeForm(); + form.setWidth("45em"); + form.setVisible(false); + form.addSaveListener(this::saveWorktype); + form.addDeleteListener(this::deleteWorktype); + form.addCloseListener(e -> closeEditor()); + } + + private void saveWorktype(WorktypeForm.SaveEvent event) { + service.saveWorktype(event.getWorktype()); + updateList(); + closeEditor(); + } + + private void deleteWorktype(WorktypeForm.DeleteEvent event) { + service.deleteWorktype(event.getWorktype()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addWorktypeButton = new Button("Add worktype"); + addWorktypeButton.addClickListener(click -> addWorktype()); + + HorizontalLayout toolbar = new HorizontalLayout(filterText, addWorktypeButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editWorktype(Worktype worktype) { + if (worktype == null) { + closeEditor(); + } else { + form.setWorktype(worktype); + form.setComicWorks(worktype.getComicWorks()); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setWorktype(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addWorktype() { + grid.asSingleSelect().clear(); + editWorktype(new Worktype()); + } + + public void updateList() { + grid.setItems(service.findAllWorktypes(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/AvatarMenuBar.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/AvatarMenuBar.java new file mode 100644 index 0000000..2e6951f --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/AvatarMenuBar.java @@ -0,0 +1,58 @@ +package de.thpeetz.kontor.views.common; + +import com.vaadin.flow.component.avatar.Avatar; +import com.vaadin.flow.component.contextmenu.MenuItem; +import com.vaadin.flow.component.contextmenu.SubMenu; +import com.vaadin.flow.component.html.Div; +import com.vaadin.flow.component.menubar.MenuBar; +import com.vaadin.flow.component.menubar.MenuBarVariant; +import com.vaadin.flow.router.Route; + +import de.thpeetz.kontor.security.SecurityService; +import de.thpeetz.kontor.services.AdminService; +import de.thpeetz.kontor.views.admin.UserProfileView; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.info.BuildProperties; + +@Slf4j +@Route("avatar-menu-bar") +public class AvatarMenuBar extends Div { + + private final SecurityService securityService; + + final AdminService adminService; + + private final BuildProperties buildProperties; + + public AvatarMenuBar(SecurityService securityService, AdminService adminService, BuildProperties buildProperties) { + this.adminService = adminService; + this.securityService = securityService; + this.buildProperties = buildProperties; + + Avatar avatar = new Avatar(); + securityService.getAuthenticatedUser().ifPresent(user -> { + log.info("AdminService: {}", adminService); + if (user != null) { + String userName = user.getUsername(); + String fullName = adminService.getProfileFullName(userName); + avatar.setName(fullName); + } + }); + // avatar.setImage(pictureUrl); + MenuBar menuBar = new MenuBar(); + menuBar.addThemeVariants(MenuBarVariant.LUMO_TERTIARY_INLINE); + MenuItem menuItem = menuBar.addItem(avatar); + SubMenu subMenu = menuItem.getSubMenu(); + MenuItem logoutMenuItem = subMenu.addItem("Log out"); + logoutMenuItem.addClickListener(e -> securityService.logout()); + MenuItem profileItem = subMenu.addItem("Profile"); + profileItem.addClickListener(e -> profileItem.getUI().ifPresent(ui -> ui.navigate(UserProfileView.class))); + subMenu.addItem("Settings"); + subMenu.addItem("Help"); + subMenu.addSeparator(); + subMenu.addItem("Version"); + subMenu.addItem(this.buildProperties.getVersion()); + subMenu.addItem(this.buildProperties.getTime().toString()); + add(menuBar); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/ColumnToggleContextMenu.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/ColumnToggleContextMenu.java new file mode 100644 index 0000000..c5d4f25 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/ColumnToggleContextMenu.java @@ -0,0 +1,32 @@ +package de.thpeetz.kontor.views.common; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.contextmenu.ContextMenu; +import com.vaadin.flow.component.contextmenu.MenuItem; +import com.vaadin.flow.component.grid.Grid; + +public class ColumnToggleContextMenu extends ContextMenu { + public ColumnToggleContextMenu(Component target) { + super(target); + setOpenOnClick(true); + } + + public void addColumnToggleItem(Grid.Column column) { + String label = column.getHeaderText(); + MenuItem menuItem = this.addItem(label, e -> { + column.setVisible(e.getSource().isChecked()); + }); + menuItem.setCheckable(true); + menuItem.setChecked(column.isVisible()); + menuItem.setKeepOpen(true); + } + + public void addColumnToggleItem(String label, Grid.Column column) { + MenuItem menuItem = this.addItem(label, e -> { + column.setVisible(e.getSource().isChecked()); + }); + menuItem.setCheckable(true); + menuItem.setChecked(column.isVisible()); + menuItem.setKeepOpen(true); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/ComicIssueField.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/ComicIssueField.java new file mode 100644 index 0000000..20964a6 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/ComicIssueField.java @@ -0,0 +1,62 @@ +package de.thpeetz.kontor.views.common; + +import com.vaadin.flow.component.Unit; +import com.vaadin.flow.component.customfield.CustomField; +import com.vaadin.flow.component.select.Select; +import lombok.extern.slf4j.Slf4j; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.Issue; + +import java.util.List; + +@Slf4j +public class ComicIssueField extends CustomField { + + public final Select comic = new Select<>(); + public final Select issue = new Select<>(); + + public ComicIssueField(String caption) { + comic.setEnabled(false); + comic.setWidth(9, Unit.EM); + comic.setItemLabelGenerator(Comic::getTitle); + comic.addValueChangeListener(e -> { + updateIssues(); + }); + issue.setEnabled(false); + issue.setWidth(9, Unit.EM); + issue.setItemLabelGenerator(Issue::getIssueNumber); + add(comic, issue); + } + + @Override + protected Issue generateModelValue() { + log.info("ComicIssueField.generateModelValue: {}", issue.getValue()); + return issue.getValue(); + } + + @Override + protected void setPresentationValue(Issue newPresentationValue) { + log.info("ComicIssueField.setPresentationValue({})", newPresentationValue); + if (newPresentationValue == null) return; + comic.setValue(newPresentationValue.getComic()); + log.info("setPresentationValue: set Comic select = {}", comic.getValue()); + issue.setValue(newPresentationValue); + } + + public void setComics(List comics) { + log.info("ComicIssueField.setComics"); + comic.setItems(comics); + comic.setEnabled(true); + } + + private void updateIssues() { + log.info("ComicIssueField.updateIssues"); + if (comic.getValue() == null) { + issue.setValue(null); + issue.setEnabled(false); + return; + } + issue.setItems(comic.getValue().getIssues()); + issue.setEnabled(true); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/FilterOption.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/FilterOption.java new file mode 100644 index 0000000..e6037de --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/FilterOption.java @@ -0,0 +1,21 @@ +package de.thpeetz.kontor.views.common; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@ToString +public class FilterOption { + @Getter + @Setter + private String name; + + @Getter + @Setter + private Boolean value; + + public FilterOption(String name, Boolean value) { + this.name = name; + this.value = value; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/KontorLayoutUtil.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/KontorLayoutUtil.java new file mode 100644 index 0000000..a1dbb79 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/KontorLayoutUtil.java @@ -0,0 +1,101 @@ +package de.thpeetz.kontor.views.common; + +import com.vaadin.flow.component.applayout.AppLayout; +import com.vaadin.flow.component.applayout.AppLayout.Section; +import com.vaadin.flow.component.applayout.DrawerToggle; +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.html.H2; +import com.vaadin.flow.component.orderedlayout.FlexComponent; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.Scroller; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.sidenav.SideNav; +import com.vaadin.flow.router.RouterLink; +import com.vaadin.flow.theme.lumo.LumoUtility; + +import de.thpeetz.kontor.constants.AdminConstants; +import de.thpeetz.kontor.constants.BookshelfConstants; +import de.thpeetz.kontor.constants.ComicConstants; +import de.thpeetz.kontor.constants.TyscConstants; +import de.thpeetz.kontor.security.SecurityService; +import de.thpeetz.kontor.services.AdminService; +import lombok.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.info.BuildProperties; + +@Slf4j +public class KontorLayoutUtil { + + private final AppLayout appLayout; + @Setter + private HorizontalLayout secondaryNavigation; + + private final AdminService adminService; + + private final SecurityService securityService; + + private final BuildProperties buildProperties; + + public KontorLayoutUtil(AppLayout layout, AdminService adminService, SecurityService securityService, BuildProperties buildProperties) { + this.adminService = adminService; + this.securityService = securityService; + this.buildProperties = buildProperties; + this.appLayout = layout; + } + + public void createHeader(String titleName) { + appLayout.addToDrawer(createTitle(), getScroller()); + appLayout.addToNavbar(getHeader(titleName)); + appLayout.setPrimarySection(Section.DRAWER); + } + + private H1 createTitle() { + H1 appTitle = new H1(new RouterLink("Kontor", MainView.class)); + appTitle.getStyle().set("font-size", "var(--lumo-font-size-l)") + .set("line-height", "var(--lumo-size-l)") + .set("margin", "0 var(--lumo-space-m)"); + return appTitle; + } + + private Scroller getScroller() { + Scroller scroller = new Scroller(getPrimaryNavigation()); + scroller.setClassName(LumoUtility.Padding.SMALL); + return scroller; + } + + private VerticalLayout getHeader(String header) { + DrawerToggle toggle = new DrawerToggle(); + H2 viewTitle = new H2(header); + viewTitle.addClassNames(LumoUtility.FontSize.LARGE, LumoUtility.Margin.NONE); + HorizontalLayout subViews = this.secondaryNavigation; + + AvatarMenuBar avatar = new AvatarMenuBar(securityService, adminService, buildProperties); + HorizontalLayout wrapper = new HorizontalLayout(toggle, viewTitle, avatar); + wrapper.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER); + wrapper.expand(viewTitle); + wrapper.setWidthFull(); + wrapper.setSpacing(false); + + VerticalLayout viewHeader = new VerticalLayout(wrapper, subViews); + viewHeader.setPadding(false); + viewHeader.setSpacing(false); + return viewHeader; + } + + private SideNav getPrimaryNavigation() { + SideNav sideNav = new SideNav(); + sideNav.addItem(ComicConstants.getComicsNavigation()); + sideNav.addItem(TyscConstants.getTyscNavigation()); + sideNav.addItem(BookshelfConstants.getBookshelfNavigation()); + securityService.getAuthenticatedUser().ifPresent(user -> { + log.info("User {} found", user.getUsername()); + boolean isAdmin = user.getAuthorities().stream() + .anyMatch(grantedAuthority -> "ROLE_ADMIN".equals(grantedAuthority.getAuthority())); + log.info("User {} hat Admin-Rechte: {}", user, isAdmin); + if (isAdmin) { + sideNav.addItem(AdminConstants.getAdminNavigation()); + } + }); + return sideNav; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/MainLayout.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/MainLayout.java new file mode 100644 index 0000000..3bc7334 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/MainLayout.java @@ -0,0 +1,106 @@ +package de.thpeetz.kontor.views.common; + +import com.vaadin.flow.component.applayout.AppLayout; +import com.vaadin.flow.component.applayout.DrawerToggle; +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.html.H2; +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.orderedlayout.FlexComponent; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.Scroller; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.sidenav.SideNav; +import com.vaadin.flow.component.sidenav.SideNavItem; +import com.vaadin.flow.router.RouterLink; +import com.vaadin.flow.theme.lumo.LumoUtility; + +import de.thpeetz.kontor.constants.AdminConstants; +import de.thpeetz.kontor.constants.BookshelfConstants; +import de.thpeetz.kontor.constants.ComicConstants; +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.constants.TyscConstants; +import de.thpeetz.kontor.security.SecurityService; +import de.thpeetz.kontor.services.AdminService; +import de.thpeetz.kontor.views.DataManagementView; +import de.thpeetz.kontor.views.EmailView; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.info.BuildProperties; + +import java.util.ArrayList; + +@Slf4j +public class MainLayout extends AppLayout { + + private final AdminService adminService; + + private final SecurityService securityService; + + private final BuildProperties buildProperties; + + public MainLayout(AdminService adminService, SecurityService securityService, BuildProperties buildProperties) { + this.adminService = adminService; + this.securityService = securityService; + this.buildProperties = buildProperties; + + createHeader("Kontor"); + createDrawer(); + } + + public void createDrawer() { + H1 appTitle = new H1(new RouterLink("Kontor", MainView.class)); + appTitle.getStyle().set("font-size", "var(--lumo-font-size-l)") + .set("line-height", "var(--lumo-size-l)") + .set("margin", "0 var(--lumo-space-m)"); + Scroller scroller = new Scroller(getPrimaryNavigation()); + scroller.setClassName(LumoUtility.Padding.SMALL); + addToDrawer(appTitle, scroller); + } + + public void createHeader(String titleName) { + DrawerToggle toggle = new DrawerToggle(); + H2 viewTitle = new H2(titleName); + viewTitle.addClassNames(LumoUtility.FontSize.LARGE, LumoUtility.Margin.NONE); + + AvatarMenuBar avatar = new AvatarMenuBar(securityService, adminService, buildProperties); + HorizontalLayout wrapper = new HorizontalLayout(toggle, viewTitle, avatar); + wrapper.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER); + wrapper.expand(viewTitle); + wrapper.setWidthFull(); + wrapper.setSpacing(false); + + VerticalLayout viewHeader = new VerticalLayout(wrapper); + viewHeader.setPadding(false); + viewHeader.setSpacing(false); + + addToNavbar(viewHeader); + setPrimarySection(Section.DRAWER); + } + + private SideNav getPrimaryNavigation() { + SideNav sideNav = new SideNav(); + ArrayList roles = new ArrayList<>(); + securityService.getAuthenticatedUser().ifPresent(user -> { + log.info("Get roles for user {}", user.getUsername()); + user.getAuthorities().forEach(grantedAuthority -> { + roles.add(grantedAuthority.getAuthority()); + }); + log.info("user {} has roles: {}", user, roles); + }); + sideNav.addItem(ComicConstants.getComicsNavigation()); + sideNav.addItem(TyscConstants.getTyscNavigation()); + sideNav.addItem(BookshelfConstants.getBookshelfNavigation()); + sideNav.addItem(MediaConstants.getMediaNavigation(roles)); + sideNav.addItem(new SideNavItem("Emails", EmailView.class)); + sideNav.addItem(new SideNavItem("Data Management", DataManagementView.class, VaadinIcon.DATABASE.create())); + securityService.getAuthenticatedUser().ifPresent(user -> { + log.info("User {} found", user.getUsername()); + boolean isAdmin = user.getAuthorities().stream() + .anyMatch(grantedAuthority -> "ROLE_ADMIN".equals(grantedAuthority.getAuthority())); + log.info("User {} hat Admin-Rechte: {}", user, isAdmin); + if (isAdmin) { + sideNav.addItem(AdminConstants.getAdminNavigation()); + } + }); + return sideNav; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/MainView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/MainView.java new file mode 100644 index 0000000..ac60ec3 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/MainView.java @@ -0,0 +1,18 @@ +package de.thpeetz.kontor.views.common; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.server.auth.AnonymousAllowed; +import com.vaadin.flow.spring.annotation.SpringComponent; + +@SpringComponent +@Scope("prototype") +@AnonymousAllowed +@Route(value = "/", layout = MainLayout.class) +@PageTitle("Kontor") +public class MainView extends VerticalLayout { + +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/SearchFilter.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/SearchFilter.java new file mode 100644 index 0000000..cce626d --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/SearchFilter.java @@ -0,0 +1,36 @@ +package de.thpeetz.kontor.views.common; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@ToString +public class SearchFilter { + + @Getter + @Setter + private String searchTerm; + + @Getter + private List filterOptions = new LinkedList<>(); + + private final Map filterMap = new HashMap<>(); + + public SearchFilter() { + + } + + public void addFilter(FilterOption option) { + filterOptions.add(option); + filterMap.put(option.getName(), option); + } + + public FilterOption getFilter(String optionName) { + return filterMap.get(optionName); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/SearchFilterField.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/SearchFilterField.java new file mode 100644 index 0000000..6e4c1a8 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/SearchFilterField.java @@ -0,0 +1,57 @@ +package de.thpeetz.kontor.views.common; + +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import com.vaadin.flow.component.combobox.MultiSelectComboBox; +import com.vaadin.flow.component.combobox.MultiSelectComboBox.AutoExpandMode; +import com.vaadin.flow.component.customfield.CustomField; +import com.vaadin.flow.component.textfield.TextField; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SearchFilterField extends CustomField { + + private final TextField searchField = new TextField(); + private final MultiSelectComboBox filterField = new MultiSelectComboBox<>(); + private final List filterOptions = new LinkedList<>(); + + public SearchFilterField() { + searchField.setPlaceholder("Search"); + searchField.setClearButtonVisible(true); + filterField.setPlaceholder("Filter"); + filterField.setClearButtonVisible(true); + filterField.setItemLabelGenerator(FilterOption::getName); + filterField.setAutoExpand(AutoExpandMode.BOTH); + add(searchField, filterField); + } + + @Override + protected SearchFilter generateModelValue() { + SearchFilter filter = new SearchFilter(); + if (searchField.getValue() != null) { + filter.setSearchTerm(searchField.getValue()); + } + Set filterOptions = filterField.getValue(); + for (FilterOption filterOption : filterOptions) { + filter.addFilter(filterOption); + } + log.info("use searchfilter: {}", filter); + return filter; + } + + @Override + protected void setPresentationValue(SearchFilter searchFilter) { + log.info("display filter: {}", searchFilter); + if (searchFilter == null) return; + searchField.setValue(searchFilter.getSearchTerm()); + } + + public void addFilter(String optionName) { + FilterOption filterOption = new FilterOption(optionName, true); + filterOptions.add(filterOption); + filterField.setItems(filterOptions); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/SeparateMainLayout.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/SeparateMainLayout.java new file mode 100644 index 0000000..4ba460e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/SeparateMainLayout.java @@ -0,0 +1,26 @@ +package de.thpeetz.kontor.views.common; + +import com.vaadin.flow.component.applayout.AppLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.theme.lumo.LumoUtility; +import org.springframework.boot.info.BuildProperties; + +import de.thpeetz.kontor.security.SecurityService; +import de.thpeetz.kontor.services.AdminService; + +public class SeparateMainLayout extends AppLayout { + + public SeparateMainLayout(AdminService adminService, SecurityService securityService, BuildProperties buildProperties) { + + KontorLayoutUtil layout = new KontorLayoutUtil(this, adminService, securityService, buildProperties); + layout.setSecondaryNavigation(getSecondaryNavigation()); + layout.createHeader("Kontor"); + } + + private HorizontalLayout getSecondaryNavigation() { + HorizontalLayout navigation = new HorizontalLayout(); + navigation.addClassNames(LumoUtility.JustifyContent.CENTER, LumoUtility.Gap.SMALL, LumoUtility.Height.MEDIUM); + return navigation; + } + +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/StatusIcon.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/StatusIcon.java new file mode 100644 index 0000000..a2c03ae --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/StatusIcon.java @@ -0,0 +1,19 @@ +package de.thpeetz.kontor.views.common; + +import com.vaadin.flow.component.icon.Icon; +import com.vaadin.flow.component.icon.VaadinIcon; + +public class StatusIcon { + public static Icon create(boolean status) { + Icon icon; + if (status) { + icon = VaadinIcon.CHECK.create(); + icon.getElement().getThemeList().add("badge success"); + } else { + icon = VaadinIcon.CLOSE_SMALL.create(); + icon.getElement().getThemeList().add("badge error"); + } + icon.getStyle().set("padding", "var(--lumo-space-xs"); + return icon; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/YearMonthField.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/YearMonthField.java new file mode 100644 index 0000000..8a377e6 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/common/YearMonthField.java @@ -0,0 +1,54 @@ +package de.thpeetz.kontor.views.common; + +import com.vaadin.flow.component.Unit; +import com.vaadin.flow.component.customfield.CustomField; +import com.vaadin.flow.component.select.Select; +import lombok.extern.slf4j.Slf4j; + +import java.time.LocalDate; +import java.time.Month; +import java.time.YearMonth; +import java.time.ZoneId; +import java.time.format.TextStyle; +import java.util.List; +import java.util.Locale; +import java.util.stream.IntStream; + +@Slf4j +public class YearMonthField extends CustomField { + + private final Select year = new Select<>();; + private final Select month = new Select<>(); + + public YearMonthField() { + LocalDate now = LocalDate.now(ZoneId.systemDefault()); + List selectableYears = IntStream.range(1970, now.getYear()).boxed().toList(); + year.setItems(selectableYears); + year.setWidth(6, Unit.EM); + month.setItems(Month.values()); + month.setItemLabelGenerator(m -> m.getDisplayName(TextStyle.FULL, Locale.getDefault())); + month.setWidth(9, Unit.EM); + add(year, month); + } + + @Override + protected YearMonth generateModelValue() { + if (year.getValue() != null && month.getValue() != null) { + int yearValue = year.getValue(); + int monthValue = month.getValue().getValue(); + YearMonth result = YearMonth.of(yearValue, monthValue); + log.debug("YearMonthField.generateModelValue() = {}", result); + return result; + } else { + log.debug("YearMonthField.generateModelValue() = null"); + return null; + } + } + + @Override + protected void setPresentationValue(YearMonth yearMonth) { + if (yearMonth == null) return; + year.setValue(yearMonth.getYear()); + month.setValue(yearMonth.getMonth()); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaActorFileForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaActorFileForm.java new file mode 100644 index 0000000..18ed2eb --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaActorFileForm.java @@ -0,0 +1,107 @@ +package de.thpeetz.kontor.views.media; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.media.MediaActor; +import de.thpeetz.kontor.data.media.MediaActorFile; +import de.thpeetz.kontor.data.media.MediaFile; +import lombok.Getter; + +import java.util.List; + +public class MediaActorFileForm extends FormLayout { + ComboBox mediaFile = new ComboBox<>("Media File"); + ComboBox mediaActor = new ComboBox<>("Actor"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(MediaActorFile.class); + + public MediaActorFileForm(List mediaFiles, List actors) { + addClassName("mediaactorfile-form"); + binder.bindInstanceFields(this); + + mediaFile.setItems(mediaFiles); + mediaFile.setItemLabelGenerator(MediaFile::getTitle); + mediaActor.setItems(actors); + mediaActor.setItemLabelGenerator(MediaActor::getName); + add(mediaFile, mediaActor, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new MediaActorFileForm.DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new MediaActorFileForm.CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new MediaActorFileForm.SaveEvent(this, binder.getBean())); + } + } + + public void setMediaActorFile(MediaActorFile mediaActorFile) { + binder.setBean(mediaActorFile); + } + + public abstract static class MediaActorFileFormEvent extends ComponentEvent { + @Getter + private MediaActorFile mediaActorFile; + + protected MediaActorFileFormEvent(MediaActorFileForm source, MediaActorFile mediaActorFile) { + super(source, false); + this.mediaActorFile = mediaActorFile; + } + } + + public static class SaveEvent extends MediaActorFileForm.MediaActorFileFormEvent { + SaveEvent(MediaActorFileForm source, MediaActorFile mediaActorFile) { + super(source, mediaActorFile); + } + } + + public static class DeleteEvent extends MediaActorFileForm.MediaActorFileFormEvent { + DeleteEvent(MediaActorFileForm source, MediaActorFile mediaActorFile) { + super(source, mediaActorFile); + } + } + + public static class CloseEvent extends MediaActorFileForm.MediaActorFileFormEvent { + CloseEvent(MediaActorFileForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(MediaActorFileForm.DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(MediaActorFileForm.SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(MediaActorFileForm.CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaActorFileView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaActorFileView.java new file mode 100644 index 0000000..486ed4e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaActorFileView.java @@ -0,0 +1,115 @@ +package de.thpeetz.kontor.views.media; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.data.media.MediaActorFile; +import de.thpeetz.kontor.services.MediaFileService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; +import lombok.Getter; +import org.springframework.context.annotation.Scope; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = MediaConstants.MEDIAACTORFILE_ROUTE, layout = MainLayout.class) +@PageTitle("MediaActorFile | Media | Kontor") +public class MediaActorFileView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(MediaActorFile.class); + @Getter + MediaActorFileForm form; + MediaFileService service; + + public MediaActorFileView(MediaFileService service) { + this.service = service; + addClassName("mediaactorfile-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("mediaactorfile-grid"); + grid.setSizeFull(); + grid.setColumns("id", "media_actor.name", "media_file.title"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editMediaActorFile(event.getValue())); + } + + private void configureForm() { + form = new MediaActorFileForm(service.findAllMediaFiles(null), service.findAllMediaActors(null)); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveMediaActorFile); + form.addDeleteListener(this::deleteMediaActorFile); + form.addCloseListener(e -> closeEditor()); + } + + private void saveMediaActorFile(MediaActorFileForm.SaveEvent event) { + service.saveMediaActorFile(event.getMediaActorFile()); + updateList(); + closeEditor(); + } + + private void deleteMediaActorFile(MediaActorFileForm.DeleteEvent event) { + service.deleteMediaActorFile(event.getMediaActorFile()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + Button addMediaActorFileButton = new Button("Add MediaActorFile"); + addMediaActorFileButton.addClickListener(click -> addMediaActorFile()); + + HorizontalLayout toolbar = new HorizontalLayout(addMediaActorFileButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editMediaActorFile(MediaActorFile mediaActorFile) { + if (mediaActorFile == null) { + closeEditor(); + } else { + form.setMediaActorFile(mediaActorFile); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setMediaActorFile(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addMediaActorFile() { + grid.asSingleSelect().clear(); + editMediaActorFile(new MediaActorFile()); + } + + public void updateList() { + grid.setItems(service.findAllMediaActorFiles()); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaActorForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaActorForm.java new file mode 100644 index 0000000..a26839e --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaActorForm.java @@ -0,0 +1,119 @@ +package de.thpeetz.kontor.views.media; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.media.MediaActor; +import de.thpeetz.kontor.data.media.MediaActorFile; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +@Slf4j +public class MediaActorForm extends FormLayout { + + TextField name = new TextField("Name"); + TextField url = new TextField("URL"); + Grid mediaActorFiles = new Grid<>(MediaActorFile.class); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(MediaActor.class); + + public MediaActorForm() { + addClassName("media-actor-form"); + binder.bindInstanceFields(this); + + mediaActorFiles.setColumns("media_file.title"); + mediaActorFiles.getColumnByKey("media_file.title").setHeader("File Title"); + add(name, 2); + add(url, 2); + add(mediaActorFiles, 2); + add(createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new MediaActorForm.DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new MediaActorForm.CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new MediaActorForm.SaveEvent(this, binder.getBean())); + } + } + + public void setMediaActor(MediaActor mediaActor) { + binder.setBean(mediaActor); + } + + public void setMediaActorFiles(List mediaActorFiles) { + log.info("Setting mediaActorFiles: {}", mediaActorFiles); + this.mediaActorFiles.setItems(mediaActorFiles); + } + + public abstract static class MediaActorFormEvent extends ComponentEvent { + private MediaActor mediaActor; + + protected MediaActorFormEvent(MediaActorForm source, MediaActor mediaActor) { + super(source, false); + this.mediaActor = mediaActor; + } + + public MediaActor getMediaActor() { + return mediaActor; + } + } + + public static class SaveEvent extends MediaActorForm.MediaActorFormEvent { + SaveEvent(MediaActorForm source, MediaActor mediaActor) { + super(source, mediaActor); + } + } + + public static class DeleteEvent extends MediaActorForm.MediaActorFormEvent { + DeleteEvent(MediaActorForm source, MediaActor mediaActor) { + super(source, mediaActor); + } + } + + public static class CloseEvent extends MediaActorForm.MediaActorFormEvent { + CloseEvent(MediaActorForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(MediaActorForm.DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(MediaActorForm.SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(MediaActorForm.CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaActorView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaActorView.java new file mode 100644 index 0000000..bd6b4e1 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaActorView.java @@ -0,0 +1,143 @@ +package de.thpeetz.kontor.views.media; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.data.media.MediaActor; +import de.thpeetz.kontor.services.MediaFileService; +import de.thpeetz.kontor.views.common.ColumnToggleContextMenu; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; +import lombok.Getter; +import org.springframework.context.annotation.Scope; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = MediaConstants.MEDIAACTOR_ROUTE, layout = MainLayout.class) +@PageTitle("Actor | Media | Kontor") +public class MediaActorView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(MediaActor.class, false); + Grid.Column idColumn = grid.addColumn(MediaActor::getId) + .setHeader("ID").setResizable(true).setSortable(true); + Grid.Column createdColumn = grid.addColumn(MediaActor::getCreatedDate) + .setHeader("Erstellt").setResizable(true).setSortable(true); + Grid.Column modifiedColumn = grid.addColumn(MediaActor::getLastModifiedDate) + .setHeader("Geändert").setResizable(true).setSortable(true); + Grid.Column nameColumn = grid.addColumn(MediaActor::getName) + .setHeader("Name").setResizable(true).setSortable(true); + Grid.Column urlColumn = grid.addColumn(MediaActor::getUrl) + .setHeader("URL").setResizable(true).setSortable(true); + TextField filterText = new TextField(); + @Getter + MediaActorForm form; + MediaFileService service; + + public MediaActorView(MediaFileService service) { + this.service = service; + addClassName("media-actor-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("media-actor-grid"); + grid.setSizeFull(); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editMediaActor(event.getValue())); + } + + private void configureForm() { + form = new MediaActorForm(); + form.setWidth("75em"); + form.setVisible(false); + form.addSaveListener(this::saveMediaActor); + form.addDeleteListener(this::deleteMediaActor); + form.addCloseListener(e -> closeEditor()); + } + + private void saveMediaActor(MediaActorForm.SaveEvent event) { + service.saveMediaActor(event.getMediaActor()); + updateList(); + closeEditor(); + } + + private void deleteMediaActor(MediaActorForm.DeleteEvent event) { + service.deleteMediaActor(event.getMediaActor()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addMediaActorButton = new Button("Add actor"); + addMediaActorButton.addClickListener(click -> addMediaActor()); + + Button menuButton = new Button("Show/Hide Columns"); + menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); + columnToggleContextMenu.addColumnToggleItem(idColumn); + columnToggleContextMenu.addColumnToggleItem(createdColumn); + columnToggleContextMenu.addColumnToggleItem(modifiedColumn); + columnToggleContextMenu.addColumnToggleItem(nameColumn); + columnToggleContextMenu.addColumnToggleItem(urlColumn); + HorizontalLayout toolbar = new HorizontalLayout(filterText, addMediaActorButton, menuButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editMediaActor(MediaActor mediaActor) { + if (mediaActor == null) { + closeEditor(); + } else { + form.setMediaActor(mediaActor); + form.setMediaActorFiles(mediaActor.getMediaActorFiles()); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setMediaActor(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addMediaActor() { + grid.asSingleSelect().clear(); + editMediaActor(new MediaActor()); + } + + public void updateList() { + grid.setItems(service.findAllMediaActors(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaArticleForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaArticleForm.java new file mode 100644 index 0000000..361f2a6 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaArticleForm.java @@ -0,0 +1,109 @@ +package de.thpeetz.kontor.views.media; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.media.MediaArticle; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MediaArticleForm extends FormLayout { + + TextField url = new TextField("URL"); + TextField title = new TextField("Title"); + Checkbox review = new Checkbox("Review"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(MediaArticle.class); + + public MediaArticleForm() { + addClassName("mediaarticle-form"); + binder.bindInstanceFields(this); + add(url, 2); + add(title, 2); + add(review, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new MediaArticleForm.DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new MediaArticleForm.CloseEvent(this))); + + binder.addStatusChangeListener(event -> { + save.setEnabled(event.getBinder().isValid()); + }); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new MediaArticleForm.SaveEvent(this, binder.getBean())); + } + } + + public void setMediaArticle(MediaArticle mediaArticle) { + binder.setBean(mediaArticle); + } + + public abstract static class MediaArticleFormEvent extends ComponentEvent { + private MediaArticle mediaArticle; + + protected MediaArticleFormEvent(MediaArticleForm source, MediaArticle mediaArticle) { + super(source, false); + this.mediaArticle = mediaArticle; + } + + public MediaArticle getMediaArticle() { + return mediaArticle; + } + } + + public static class SaveEvent extends MediaArticleForm.MediaArticleFormEvent { + SaveEvent(MediaArticleForm source, MediaArticle mediaArticle) { + super(source, mediaArticle); + } + } + + public static class DeleteEvent extends MediaArticleForm.MediaArticleFormEvent { + DeleteEvent(MediaArticleForm source, MediaArticle mediaArticle) { + super(source, mediaArticle); + } + } + + public static class CloseEvent extends MediaArticleForm.MediaArticleFormEvent { + CloseEvent(MediaArticleForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(MediaArticleForm.DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(MediaArticleForm.SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(MediaArticleForm.CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaArticleView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaArticleView.java new file mode 100644 index 0000000..cdc3f22 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaArticleView.java @@ -0,0 +1,142 @@ +package de.thpeetz.kontor.views.media; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.icon.Icon; +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.data.media.MediaArticle; +import de.thpeetz.kontor.services.MediaArticleService; +import de.thpeetz.kontor.views.common.ColumnToggleContextMenu; +import de.thpeetz.kontor.views.common.MainLayout; +import de.thpeetz.kontor.views.common.StatusIcon; +import jakarta.annotation.security.PermitAll; +import lombok.Getter; +import org.springframework.context.annotation.Scope; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = MediaConstants.MEDIAARTICLE_ROUTE, layout = MainLayout.class) +@PageTitle("MediaArticle | Media | Kontor") +public class MediaArticleView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(MediaArticle.class, false); + Grid.Column idColumn = grid.addColumn(MediaArticle::getId).setHeader("ID").setResizable(true); + Grid.Column urlColumn = grid.addColumn(MediaArticle::getUrl).setHeader("URL").setResizable(true).setSortable(true); + Grid.Column titleColumn = grid.addColumn(MediaArticle::getTitle).setHeader("Titel").setResizable(true).setSortable(true); + Grid.Column reviewColumn = grid.addComponentColumn(mediaArticle -> StatusIcon.create(mediaArticle.isReview())) + .setHeader("Überprüfung") + .setWidth("6rem"); + TextField searchField = new TextField(); + @Getter + MediaArticleForm form; + MediaArticleService service; + + public MediaArticleView(MediaArticleService service) { + this.service = service; + addClassName("mediaarticle-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("mediaarticle-grid"); + grid.setSizeFull(); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + idColumn.setVisible(false); + grid.asSingleSelect().addValueChangeListener(event -> editMediaArticle(event.getValue())); + } + + private void configureForm() { + form = new MediaArticleForm(); + form.setWidth("75em"); + form.setVisible(false); + form.addSaveListener(this::saveMediaArticle); + form.addDeleteListener(this::deleteMediaArticle); + form.addCloseListener(e -> closeEditor()); + } + + private void saveMediaArticle(MediaArticleForm.SaveEvent event) { + service.saveMediaArticle(event.getMediaArticle()); + updateList(); + closeEditor(); + } + + private void deleteMediaArticle(MediaArticleForm.DeleteEvent event) { + service.deleteMediaArticle(event.getMediaArticle()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + searchField.setPlaceholder("Search"); + searchField.setClearButtonVisible(true); + searchField.setPrefixComponent(new Icon(VaadinIcon.SEARCH)); + searchField.setValueChangeMode(ValueChangeMode.EAGER); + searchField.addValueChangeListener(e -> updateList()); + + Button addMediaArticleButton = new Button("Add MediaArticle"); + addMediaArticleButton.addClickListener(click -> addMediaArticle()); + + Button menuButton = new Button("Show/Hide Columns"); + menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); + columnToggleContextMenu.addColumnToggleItem(idColumn); + columnToggleContextMenu.addColumnToggleItem(urlColumn); + columnToggleContextMenu.addColumnToggleItem(titleColumn); + columnToggleContextMenu.addColumnToggleItem(reviewColumn); + HorizontalLayout toolbar = new HorizontalLayout(searchField, addMediaArticleButton, menuButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editMediaArticle(MediaArticle mediaArticle) { + if (mediaArticle == null) { + closeEditor(); + } else { + form.setMediaArticle(mediaArticle); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setMediaArticle(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addMediaArticle() { + grid.asSingleSelect().clear(); + editMediaArticle(new MediaArticle()); + } + + public void updateList() { + grid.setItems(service.findAllMediaArticles(searchField.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaFileForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaFileForm.java new file mode 100644 index 0000000..5a8aa9f --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaFileForm.java @@ -0,0 +1,129 @@ +package de.thpeetz.kontor.views.media; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.media.MediaActorFile; +import de.thpeetz.kontor.data.media.MediaFile; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +@Slf4j +public class MediaFileForm extends FormLayout { + + TextField id = new TextField("ID"); + TextField url = new TextField("URL"); + TextField title = new TextField("Title"); + TextField fileName = new TextField("Dateiname"); + TextField cloudLink = new TextField("Cloud Link"); + Checkbox review = new Checkbox("Review"); + Checkbox shouldDownload = new Checkbox("Download"); + Grid mediaActorFiles = new Grid<>(MediaActorFile.class); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(MediaFile.class); + + public MediaFileForm() { + addClassName("mediafile-form"); + binder.bindInstanceFields(this); + id.setReadOnly(true); + + mediaActorFiles.setColumns("media_actor.name"); + mediaActorFiles.getColumnByKey("media_actor.name").setHeader("Actor"); + + add(id, 2); + add(url, 2); + add(title, 2); + add(fileName, 2); + add(cloudLink, 2); + add(review, shouldDownload); + add(mediaActorFiles, 2); + add(createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(event -> save.setEnabled(event.getBinder().isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setMediaFile(MediaFile mediaFile) { + binder.setBean(mediaFile); + } + + public void setMediaActorFiles(List actorFiles) { + mediaActorFiles.setItems(actorFiles); + } + + @Getter + public abstract static class MediaFileFormEvent extends ComponentEvent { + private final MediaFile mediaFile; + + protected MediaFileFormEvent(MediaFileForm source, MediaFile mediaFile) { + super(source, false); + this.mediaFile = mediaFile; + } + + } + + public static class SaveEvent extends MediaFileFormEvent { + SaveEvent(MediaFileForm source, MediaFile mediaFile) { + super(source, mediaFile); + } + } + + public static class DeleteEvent extends MediaFileFormEvent { + DeleteEvent(MediaFileForm source, MediaFile mediaFile) { + super(source, mediaFile); + } + } + + public static class CloseEvent extends MediaFileFormEvent { + CloseEvent(MediaFileForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaFileView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaFileView.java new file mode 100644 index 0000000..9ca59df --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaFileView.java @@ -0,0 +1,161 @@ +package de.thpeetz.kontor.views.media; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; +import de.thpeetz.kontor.data.media.MediaFile; +import de.thpeetz.kontor.services.MediaFileService; +import de.thpeetz.kontor.views.common.ColumnToggleContextMenu; +import de.thpeetz.kontor.views.common.MainLayout; +import de.thpeetz.kontor.views.common.SearchFilterField; +import de.thpeetz.kontor.views.common.StatusIcon; +import jakarta.annotation.security.RolesAllowed; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Scope; + +@Slf4j +@SpringComponent +@Scope("prototype") +@RolesAllowed("MEDIA") +@Route(value = "media/mediafile", layout = MainLayout.class) +@PageTitle("MediaFile | Media | Kontor") +public class MediaFileView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(MediaFile.class, false); + Grid.Column idColumn = grid.addColumn(MediaFile::getId) + .setHeader("ID").setResizable(true).setSortable(true); + Grid.Column createdColumn = grid.addColumn(MediaFile::getCreatedDate) + .setHeader("Erstellt").setResizable(true).setSortable(true); + Grid.Column modifiedColumn = grid.addColumn(MediaFile::getLastModifiedDate) + .setHeader("Geändert").setResizable(true).setSortable(true); + Grid.Column urlColumn = grid.addColumn(MediaFile::getUrl) + .setHeader("URL").setResizable(true).setSortable(true); + Grid.Column titleColumn = grid.addColumn(MediaFile::getTitle) + .setHeader("Titel").setResizable(true).setSortable(true); + Grid.Column fileNameColumn = grid.addColumn(MediaFile::getFileName) + .setHeader("Dateiname").setResizable(true).setSortable(true); + Grid.Column cloudLinkColumn = grid.addColumn(MediaFile::getCloudLink) + .setHeader("Cloud Link").setResizable(true).setSortable(true); + Grid.Column reviewColumn = grid.addComponentColumn(mediafile -> StatusIcon.create(mediafile.isReview())). + setHeader("Überprüfung").setWidth("6rem").setSortable(true); + Grid.Column shouldDownloadColumn = grid.addComponentColumn(mediafile -> StatusIcon.create(mediafile.isShouldDownload())). + setHeader("Download?").setWidth("6rem").setSortable(true); + SearchFilterField searchFilterField = new SearchFilterField(); + @Getter + MediaFileForm form; + MediaFileService service; + + public MediaFileView(MediaFileService service) { + this.service = service; + addClassName("mediafile-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("mediafile-grid"); + grid.setSizeFull(); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + //idColumn.setVisible(false); + grid.asSingleSelect().addValueChangeListener(event -> editMediaFile(event.getValue())); + } + + private void configureForm() { + form = new MediaFileForm(); + form.setWidth("75em"); + form.setVisible(false); + form.addSaveListener(this::saveMediaFile); + form.addDeleteListener(this::deleteMediaFile); + form.addCloseListener(e -> closeEditor()); + } + + private void saveMediaFile(MediaFileForm.SaveEvent event) { + service.saveMediaFile(event.getMediaFile()); + updateList(); + closeEditor(); + } + + private void deleteMediaFile(MediaFileForm.DeleteEvent event) { + service.deleteMediaFile(event.getMediaFile()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + searchFilterField.addFilter("Überprüfung"); + searchFilterField.addFilter("Download"); + searchFilterField.addValueChangeListener(e -> updateList()); + + Button addMediaFileButton = new Button("Add MediaFile"); + addMediaFileButton.addClickListener(click -> addMediaFile()); + + Button menuButton = new Button("Show/Hide Columns"); + menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); + columnToggleContextMenu.addColumnToggleItem(idColumn); + columnToggleContextMenu.addColumnToggleItem(createdColumn); + columnToggleContextMenu.addColumnToggleItem(modifiedColumn); + columnToggleContextMenu.addColumnToggleItem(urlColumn); + columnToggleContextMenu.addColumnToggleItem(titleColumn); + columnToggleContextMenu.addColumnToggleItem(fileNameColumn); + columnToggleContextMenu.addColumnToggleItem(cloudLinkColumn); + columnToggleContextMenu.addColumnToggleItem(reviewColumn); + columnToggleContextMenu.addColumnToggleItem(shouldDownloadColumn); + HorizontalLayout toolbar = new HorizontalLayout(searchFilterField, addMediaFileButton, menuButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editMediaFile(MediaFile mediaFile) { + if (mediaFile == null) { + closeEditor(); + } else { + form.setMediaFile(mediaFile); + if (mediaFile.getMediaActorFiles() == null) { + log.info("no MediaActorFiles"); + } else { + log.info("MediaActorFiles size: {}", mediaFile.getMediaActorFiles().size()); + } + form.setMediaActorFiles(mediaFile.getMediaActorFiles()); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setMediaFile(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addMediaFile() { + grid.asSingleSelect().clear(); + editMediaFile(new MediaFile()); + } + + public void updateList() { + log.info("searchFilterField: {}", searchFilterField.getValue()); + grid.setItems(service.findAllMediaFiles(searchFilterField.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaLofiForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaLofiForm.java new file mode 100644 index 0000000..0b1234f --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaLofiForm.java @@ -0,0 +1,113 @@ +package de.thpeetz.kontor.views.media; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.media.MediaLofi; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MediaLofiForm extends FormLayout { + + TextField url = new TextField("URL"); + TextField title = new TextField("Title"); + TextField fileName = new TextField("Dateiname"); + Checkbox review = new Checkbox("Review"); + Checkbox shouldDownload = new Checkbox("Download"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(MediaLofi.class); + + + public MediaLofiForm() { + addClassName("medialofi-form"); + binder.bindInstanceFields(this); + add(url, 2); + add(title, 2); + add(fileName, 2); + add(review, shouldDownload, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(event -> { + save.setEnabled(event.getBinder().isValid()); + }); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setMediaLofi(MediaLofi mediaLofi) { + binder.setBean(mediaLofi); + } + + public abstract static class MediaLofiFormEvent extends ComponentEvent { + private MediaLofi mediaLofi; + + protected MediaLofiFormEvent(MediaLofiForm source, MediaLofi mediaLofi) { + super(source, false); + this.mediaLofi = mediaLofi; + } + + public MediaLofi getMediaLofi() { + return mediaLofi; + } + } + + public static class SaveEvent extends MediaLofiFormEvent { + SaveEvent(MediaLofiForm source, MediaLofi mediaLofi) { + super(source, mediaLofi); + } + } + + public static class DeleteEvent extends MediaLofiFormEvent { + DeleteEvent(MediaLofiForm source, MediaLofi mediaLofi) { + super(source, mediaLofi); + } + } + + public static class CloseEvent extends MediaLofiFormEvent { + CloseEvent(MediaLofiForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaLofiView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaLofiView.java new file mode 100644 index 0000000..0eb8121 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaLofiView.java @@ -0,0 +1,144 @@ +package de.thpeetz.kontor.views.media; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.data.media.MediaLofi; +import de.thpeetz.kontor.services.MediaLofiService; +import de.thpeetz.kontor.views.common.ColumnToggleContextMenu; +import de.thpeetz.kontor.views.common.MainLayout; +import de.thpeetz.kontor.views.common.SearchFilterField; +import de.thpeetz.kontor.views.common.StatusIcon; +import jakarta.annotation.security.PermitAll; +import lombok.Getter; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = MediaConstants.MEDIALOFI_ROUTE, layout = MainLayout.class) +@PageTitle("MediaLoFi | Media | Kontor") +public class MediaLofiView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(MediaLofi.class, false); + Grid.Column idColumn = grid.addColumn(MediaLofi::getId).setHeader("ID").setResizable(true); + Grid.Column urlColumn = grid.addColumn(MediaLofi::getUrl).setHeader("URL").setResizable(true).setSortable(true); + Grid.Column titleColumn = grid.addColumn(MediaLofi::getTitle).setHeader("Titel").setResizable(true).setSortable(true); + Grid.Column fileNameColumn = grid.addColumn(MediaLofi::getFileName).setHeader("Dateiname").setResizable(true).setSortable(true); + Grid.Column reviewColumn = grid.addComponentColumn(mediaLofi -> StatusIcon.create(mediaLofi.isReview())) + .setHeader("Überprüfung") + .setWidth("6rem"); + Grid.Column shouldDownloadColumn = grid.addComponentColumn(mediaLofi -> StatusIcon.create(mediaLofi.isShouldDownload())) + .setHeader("Download?") + .setWidth("6rem"); + SearchFilterField searchFilterField = new SearchFilterField(); + @Getter + MediaLofiForm form; + MediaLofiService service; + + public MediaLofiView(MediaLofiService service) { + this.service = service; + addClassName("medialofi-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("mediavideo-grid"); + grid.setSizeFull(); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + idColumn.setVisible(false); + grid.asSingleSelect().addValueChangeListener(event -> editMediaLofi(event.getValue())); + } + + private void configureForm() { + form = new MediaLofiForm(); + form.setWidth("75em"); + form.setVisible(false); + form.addSaveListener(this::saveMediaVideo); + form.addDeleteListener(this::deleteMediaLofi); + form.addCloseListener(e -> closeEditor()); + } + + private void saveMediaVideo(MediaLofiForm.SaveEvent event) { + service.saveMediaLofi(event.getMediaLofi()); + updateList(); + closeEditor(); + } + + private void deleteMediaLofi(MediaLofiForm.DeleteEvent event) { + service.deleteMediaLofi(event.getMediaLofi()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + searchFilterField.addFilter("Überprüfung"); + searchFilterField.addFilter("Download"); + searchFilterField.addValueChangeListener(e -> updateList()); + + Button addMediaLofiButton = new Button("Add MediaLofi"); + addMediaLofiButton.addClickListener(click -> addMediaLofi()); + + Button menuButton = new Button("Show/Hide Columns"); + menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); + columnToggleContextMenu.addColumnToggleItem(idColumn); + columnToggleContextMenu.addColumnToggleItem(urlColumn); + columnToggleContextMenu.addColumnToggleItem(titleColumn); + columnToggleContextMenu.addColumnToggleItem(fileNameColumn); + columnToggleContextMenu.addColumnToggleItem(reviewColumn); + columnToggleContextMenu.addColumnToggleItem(shouldDownloadColumn); + HorizontalLayout toolbar = new HorizontalLayout(searchFilterField, addMediaLofiButton, menuButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editMediaLofi(MediaLofi mediaLofi) { + if (mediaLofi == null) { + closeEditor(); + } else { + form.setMediaLofi(mediaLofi); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setMediaLofi(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addMediaLofi() { + grid.asSingleSelect().clear(); + editMediaLofi(new MediaLofi()); + } + + public void updateList() { + grid.setItems(service.findAllMediaLofis(searchFilterField.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaVideoForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaVideoForm.java new file mode 100644 index 0000000..869f883 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaVideoForm.java @@ -0,0 +1,114 @@ +package de.thpeetz.kontor.views.media; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.media.MediaVideo; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MediaVideoForm extends FormLayout { + + TextField url = new TextField("URL"); + TextField title = new TextField("Title"); + TextField fileName = new TextField("Dateiname"); + TextField cloudLink = new TextField("Cloud Link"); + Checkbox review = new Checkbox("Review"); + Checkbox shouldDownload = new Checkbox("Download"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(MediaVideo.class); + + public MediaVideoForm() { + addClassName("mediavideo-form"); + binder.bindInstanceFields(this); + add(url, 2); + add(title, 2); + add(fileName, 2); + add(cloudLink, 2); + add(review, shouldDownload, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(event -> { + save.setEnabled(event.getBinder().isValid()); + }); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setMediaVideo(MediaVideo mediaVideo) { + binder.setBean(mediaVideo); + } + + public abstract static class MediaVideoFormEvent extends ComponentEvent { + private MediaVideo mediaVideo; + + protected MediaVideoFormEvent(MediaVideoForm source, MediaVideo mediaVideo) { + super(source, false); + this.mediaVideo = mediaVideo; + } + + public MediaVideo getMediaVideo() { + return mediaVideo; + } + } + + public static class SaveEvent extends MediaVideoFormEvent { + SaveEvent(MediaVideoForm source, MediaVideo mediaVideo) { + super(source, mediaVideo); + } + } + + public static class DeleteEvent extends MediaVideoFormEvent { + DeleteEvent(MediaVideoForm source, MediaVideo mediaVideo) { + super(source, mediaVideo); + } + } + + public static class CloseEvent extends MediaVideoFormEvent { + CloseEvent(MediaVideoForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaVideoView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaVideoView.java new file mode 100644 index 0000000..5f08840 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/media/MediaVideoView.java @@ -0,0 +1,150 @@ +package de.thpeetz.kontor.views.media; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.icon.Icon; +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.MediaConstants; +import de.thpeetz.kontor.data.media.MediaVideo; +import de.thpeetz.kontor.services.MediaVideoService; +import de.thpeetz.kontor.views.common.ColumnToggleContextMenu; +import de.thpeetz.kontor.views.common.MainLayout; +import de.thpeetz.kontor.views.common.StatusIcon; +import jakarta.annotation.security.PermitAll; +import lombok.Getter; +import org.springframework.context.annotation.Scope; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = MediaConstants.MEDIAVIDEO_ROUTE, layout = MainLayout.class) +@PageTitle("MediaVideo | Media | Kontor") +public class MediaVideoView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(MediaVideo.class, false); + Grid.Column idColumn = grid.addColumn(MediaVideo::getId).setHeader("ID").setResizable(true); + Grid.Column urlColumn = grid.addColumn(MediaVideo::getUrl).setHeader("URL").setResizable(true).setSortable(true); + Grid.Column titleColumn = grid.addColumn(MediaVideo::getTitle).setHeader("Titel").setResizable(true).setSortable(true); + Grid.Column fileNameColumn = grid.addColumn(MediaVideo::getFileName).setHeader("Dateiname").setResizable(true).setSortable(true); + Grid.Column cloudLinkColumn = grid.addColumn(MediaVideo::getCloudLink).setHeader("Cloud Link").setResizable(true).setSortable(true); + Grid.Column reviewColumn = grid.addComponentColumn(mediaVideo -> StatusIcon.create(mediaVideo.isReview())) + .setHeader("Überprüfung") + .setWidth("6rem"); + Grid.Column shouldDownloadColumn = grid.addComponentColumn(mediaVideo -> StatusIcon.create(mediaVideo.isShouldDownload())) + .setHeader("Download?") + .setWidth("6rem"); + TextField searchField = new TextField(); + @Getter + MediaVideoForm form; + MediaVideoService service; + + public MediaVideoView(MediaVideoService service) { + this.service = service; + addClassName("mediavideo-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("mediavideo-grid"); + grid.setSizeFull(); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + idColumn.setVisible(false); + grid.asSingleSelect().addValueChangeListener(event -> editMediaVideo(event.getValue())); + } + + private void configureForm() { + form = new MediaVideoForm(); + form.setWidth("75em"); + form.setVisible(false); + form.addSaveListener(this::saveMediaVideo); + form.addDeleteListener(this::deleteMediaVideo); + form.addCloseListener(e -> closeEditor()); + } + + private void saveMediaVideo(MediaVideoForm.SaveEvent event) { + service.saveMediaVideo(event.getMediaVideo()); + updateList(); + closeEditor(); + } + + private void deleteMediaVideo(MediaVideoForm.DeleteEvent event) { + service.deleteMediaVideo(event.getMediaVideo()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + searchField.setPlaceholder("Search"); + searchField.setClearButtonVisible(true); + searchField.setPrefixComponent(new Icon(VaadinIcon.SEARCH)); + searchField.setValueChangeMode(ValueChangeMode.EAGER); + searchField.addValueChangeListener(e -> updateList()); + + Button addMediaVideoButton = new Button("Add MediaVideo"); + addMediaVideoButton.addClickListener(click -> addMediaVideo()); + + Button menuButton = new Button("Show/Hide Columns"); + menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); + columnToggleContextMenu.addColumnToggleItem(idColumn); + columnToggleContextMenu.addColumnToggleItem(urlColumn); + columnToggleContextMenu.addColumnToggleItem(titleColumn); + columnToggleContextMenu.addColumnToggleItem(fileNameColumn); + columnToggleContextMenu.addColumnToggleItem(cloudLinkColumn); + columnToggleContextMenu.addColumnToggleItem(reviewColumn); + columnToggleContextMenu.addColumnToggleItem(shouldDownloadColumn); + HorizontalLayout toolbar = new HorizontalLayout(searchField, addMediaVideoButton, menuButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editMediaVideo(MediaVideo mediaVideo) { + if (mediaVideo == null) { + closeEditor(); + } else { + form.setMediaVideo(mediaVideo); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setMediaVideo(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addMediaVideo() { + grid.asSingleSelect().clear(); + editMediaVideo(new MediaVideo()); + } + + public void updateList() { + grid.setItems(service.findAllMediaVideos(searchField.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/CardForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/CardForm.java new file mode 100644 index 0000000..de1d760 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/CardForm.java @@ -0,0 +1,116 @@ +package de.thpeetz.kontor.views.tysc; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.tysc.Card; +import de.thpeetz.kontor.data.tysc.Rooster; +import de.thpeetz.kontor.data.tysc.Vendor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CardForm extends FormLayout { + + TextField cardNumber = new TextField("CardNumber"); + TextField year = new TextField("Year"); + ComboBox vendor = new ComboBox<>("Vendor"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Card.class); + + public CardForm(List vendors) { + addClassName("card-form"); + binder.bindInstanceFields(this); + + vendor.setItems(vendors); + vendor.setItemLabelGenerator(Vendor::getName); + add(cardNumber, year, vendor, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setCard(Card card) { + binder.setBean(card); + } + + public void setRoosters(List roosters) { + log.info("Setting roosters: {}", roosters); + } + + public abstract static class CardFormEvent extends ComponentEvent { + private Card card; + + protected CardFormEvent(CardForm source, Card card) { + super(source, false); + this.card = card; + } + + public Card getCard() { + return card; + } + } + + public static class SaveEvent extends CardFormEvent { + SaveEvent(CardForm source, Card card) { + super(source, card); + } + } + + public static class DeleteEvent extends CardFormEvent { + DeleteEvent(CardForm source, Card card) { + super(source, card); + } + } + + public static class CloseEvent extends CardFormEvent { + CloseEvent(CardForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/CardSetForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/CardSetForm.java new file mode 100644 index 0000000..f5921cc --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/CardSetForm.java @@ -0,0 +1,103 @@ +package de.thpeetz.kontor.views.tysc; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.tysc.CardSet; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CardSetForm extends FormLayout { + + TextField name = new TextField("Name"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(CardSet.class); + + public CardSetForm() { + addClassName("cardSet-form"); + binder.bindInstanceFields(this); + + add(name, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setCardSet(CardSet cardSet) { + binder.setBean(cardSet); + } + + public abstract static class CardSetFormEvent extends ComponentEvent { + private CardSet cardSet; + + protected CardSetFormEvent(CardSetForm source, CardSet cardSet) { + super(source, false); + this.cardSet = cardSet; + } + + public CardSet getCardSet() { + return cardSet; + } + } + + public static class SaveEvent extends CardSetFormEvent { + SaveEvent(CardSetForm source, CardSet cardSet) { + super(source, cardSet); + } + } + + public static class DeleteEvent extends CardSetFormEvent { + DeleteEvent(CardSetForm source, CardSet cardSet) { + super(source, cardSet); + } + } + + public static class CloseEvent extends CardSetFormEvent { + CloseEvent(CardSetForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/CardSetView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/CardSetView.java new file mode 100644 index 0000000..1202234 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/CardSetView.java @@ -0,0 +1,157 @@ +package de.thpeetz.kontor.views.tysc; + +import com.vaadin.flow.component.button.*; +import lombok.*; +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.TyscConstants; +import de.thpeetz.kontor.data.tysc.CardSet; +import de.thpeetz.kontor.services.CardService; +import de.thpeetz.kontor.views.common.ColumnToggleContextMenu; +import de.thpeetz.kontor.views.common.MainLayout; +import de.thpeetz.kontor.views.common.StatusIcon; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = TyscConstants.CARDSET_ROUTE, layout = MainLayout.class) +@PageTitle("CardSet | Tysc | Kontor") +public class CardSetView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(CardSet.class, false); + Grid.Column idColumn = grid.addColumn(CardSet::getId) + .setHeader("ID").setResizable(true).setSortable(true); + Grid.Column createdColumn = grid.addColumn(CardSet::getCreatedDate) + .setHeader("Erstellt").setResizable(true).setSortable(true); + Grid.Column modifiedColumn = grid.addColumn(CardSet::getLastModifiedDate) + .setHeader("Geändert").setResizable(true).setSortable(true); + Grid.Column versionColumn = grid.addColumn(CardSet::getVersion) + .setHeader("Version").setResizable(true).setSortable(true); + Grid.Column nameColumn = grid.addColumn(CardSet::getName) + .setHeader("Comic").setResizable(true).setSortable(true); + Grid.Column vendorNameColumn = grid.addColumn(CardSet::getVendorName) + .setHeader("Hersteller").setResizable(true).setSortable(true); + Grid.Column parallelSetColumn = grid.addComponentColumn(parallelSet -> StatusIcon.create(parallelSet.isParallelSet())) + .setHeader("Parallelset?").setWidth("6rem").setSortable(true); + Grid.Column insertSetColumn = grid.addComponentColumn(insertSet -> StatusIcon.create(insertSet.isInsertSet())) + .setHeader("Parallelset?").setWidth("6rem").setSortable(true); + TextField filterText = new TextField(); + @Getter + CardSetForm form; + CardService service; + + public CardSetView(CardService service) { + this.service = service; + addClassName("cardSet-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("cardSet-grid"); + grid.setSizeFull(); + //grid.setColumns("name", "vendor.name", "parallelSet", "insertSet"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + idColumn.setVisible(false); + createdColumn.setVisible(false); + modifiedColumn.setVisible(false); + versionColumn.setVisible(false); + grid.asSingleSelect().addValueChangeListener(event -> editCardSet(event.getValue())); + } + + private void configureForm() { + form = new CardSetForm(); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveCardSet); + form.addDeleteListener(this::deleteCardSet); + form.addCloseListener(e -> closeEditor()); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addCardSetButton = new Button("Add cardSet"); + addCardSetButton.addClickListener(click -> addCardSet()); + + Button menuButton = new Button("Show/Hide Columns"); + menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); + columnToggleContextMenu.addColumnToggleItem(idColumn); + columnToggleContextMenu.addColumnToggleItem(createdColumn); + columnToggleContextMenu.addColumnToggleItem(modifiedColumn); + columnToggleContextMenu.addColumnToggleItem(versionColumn); + columnToggleContextMenu.addColumnToggleItem(nameColumn); + columnToggleContextMenu.addColumnToggleItem(vendorNameColumn); + columnToggleContextMenu.addColumnToggleItem(parallelSetColumn); + columnToggleContextMenu.addColumnToggleItem(insertSetColumn); + HorizontalLayout toolbar = new HorizontalLayout(filterText, addCardSetButton, menuButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + private void saveCardSet(CardSetForm.SaveEvent event) { + service.saveCardSet(event.getCardSet()); + updateList(); + closeEditor(); + } + + private void deleteCardSet(CardSetForm.DeleteEvent event) { + service.deleteCardSet(event.getCardSet()); + updateList(); + closeEditor(); + } + + public void editCardSet(CardSet cardSet) { + if (cardSet == null) { + closeEditor(); + } else { + form.setCardSet(cardSet); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setCardSet(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addCardSet() { + grid.asSingleSelect().clear(); + editCardSet(new CardSet()); + } + + public void updateList() { + grid.setItems(service.findAllCardSets(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/CardView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/CardView.java new file mode 100644 index 0000000..c350721 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/CardView.java @@ -0,0 +1,161 @@ +package de.thpeetz.kontor.views.tysc; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.TyscConstants; +import de.thpeetz.kontor.data.tysc.Card; +import de.thpeetz.kontor.services.CardService; +import de.thpeetz.kontor.views.common.ColumnToggleContextMenu; +import de.thpeetz.kontor.views.common.MainLayout; +import de.thpeetz.kontor.views.common.StatusIcon; +import jakarta.annotation.security.PermitAll; +import lombok.Getter; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = TyscConstants.CARD_ROUTE, layout = MainLayout.class) +@PageTitle("Card | Tysc | Kontor") +public class CardView extends VerticalLayout { + + @Getter + Grid grid = new Grid<>(Card.class, false); + Grid.Column idColumn = grid.addColumn(Card::getId).setHeader("ID") + .setResizable(true).setSortable(true); + Grid.Column createdColumn = grid.addColumn(Card::getCreatedDate) + .setHeader("Erstellt").setResizable(true).setSortable(true); + Grid.Column modifiedColumn = grid.addColumn(Card::getLastModifiedDate) + .setHeader("Geändert").setResizable(true).setSortable(true); + Grid.Column numberColumn = grid.addColumn(Card::getCardNumber) + .setHeader("Nummer").setResizable(true).setSortable(true); + Grid.Column yearColumn = grid.addColumn(Card::getYear) + .setHeader("Jahr").setResizable(true).setSortable(true); + Grid.Column vendorColumn = grid.addColumn(Card::getVendorName) + .setHeader("Hersteller").setResizable(true).setSortable(true); + Grid.Column cardSetColumn = grid.addColumn(Card::getCardSetName) + .setHeader("Cardset").setResizable(true).setSortable(true); + Grid.Column insertSetColumn = grid.addComponentColumn(card -> StatusIcon.create(card.getCardSet().isInsertSet())) + .setHeader("Inserts").setWidth("6rem").setSortable(true); + Grid.Column parallelSetColumn = grid.addComponentColumn(card -> StatusIcon.create(card.getCardSet().isParallelSet())) + .setHeader("Parallels").setWidth("6rem").setSortable(true); + Grid.Column playerColumn = grid.addColumn(Card::getPlayerName).setHeader("Spieler").setResizable(true).setSortable(true); + TextField filterText = new TextField(); + @Getter + CardForm form; + CardService service; + + public CardView(CardService service) { + this.service = service; + addClassName("card-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + private void configureGrid() { + grid.addClassName("card-grid"); + grid.setSizeFull(); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editCard(event.getValue())); + idColumn.setVisible(false); + createdColumn.setVisible(false); + modifiedColumn.setVisible(false); + } + + private void configureForm() { + form = new CardForm(service.findAllVendors(null)); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveCard); + form.addDeleteListener(this::deleteCard); + form.addCloseListener(e -> closeEditor()); + } + + private void saveCard(CardForm.SaveEvent event) { + service.saveCard(event.getCard()); + updateList(); + closeEditor(); + } + + private void deleteCard(CardForm.DeleteEvent event) { + service.deleteCard(event.getCard()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addCardButton = new Button("Add card"); + addCardButton.addClickListener(click -> addCard()); + + Button menuButton = new Button("Show/Hide Columns"); + menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); + columnToggleContextMenu.addColumnToggleItem(idColumn); + columnToggleContextMenu.addColumnToggleItem(createdColumn); + columnToggleContextMenu.addColumnToggleItem(modifiedColumn); + columnToggleContextMenu.addColumnToggleItem(numberColumn); + columnToggleContextMenu.addColumnToggleItem(yearColumn); + columnToggleContextMenu.addColumnToggleItem(vendorColumn); + columnToggleContextMenu.addColumnToggleItem(cardSetColumn); + columnToggleContextMenu.addColumnToggleItem(insertSetColumn); + columnToggleContextMenu.addColumnToggleItem(parallelSetColumn); + columnToggleContextMenu.addColumnToggleItem(playerColumn); + HorizontalLayout toolbar = new HorizontalLayout(filterText, addCardButton, menuButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editCard(Card card) { + if (card == null) { + closeEditor(); + } else { + form.setCard(card); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setCard(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addCard() { + grid.asSingleSelect().clear(); + editCard(new Card()); + } + + public void updateList() { + grid.setItems(service.findAllCards(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/PlayerForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/PlayerForm.java new file mode 100644 index 0000000..f39518d --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/PlayerForm.java @@ -0,0 +1,116 @@ +package de.thpeetz.kontor.views.tysc; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.tysc.Player; +import de.thpeetz.kontor.data.tysc.Rooster; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PlayerForm extends FormLayout { + + TextField firstName = new TextField("First Name"); + TextField lastName = new TextField("Last Name"); + Grid roosters = new Grid<>(Rooster.class); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Player.class); + + public PlayerForm() { + addClassName("player-form"); + binder.bindInstanceFields(this); + + roosters.setColumns("team.name", "position.name", "year"); + roosters.getColumns().forEach(col -> col.setAutoWidth(true)); + add(firstName, lastName, roosters, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setPlayer(Player player) { + binder.setBean(player); + } + + public void setRoosters(List roosters) { + log.info("Setting roosters: {}", roosters); + this.roosters.setItems(roosters); + } + + public abstract static class PlayerFormEvent extends ComponentEvent { + private Player player; + + protected PlayerFormEvent(PlayerForm source, Player player) { + super(source, false); + this.player = player; + } + + public Player getPlayer() { + return player; + } + } + + public static class SaveEvent extends PlayerFormEvent { + SaveEvent(PlayerForm source, Player player) { + super(source, player); + } + } + + public static class DeleteEvent extends PlayerFormEvent { + DeleteEvent(PlayerForm source, Player player) { + super(source, player); + } + } + + public static class CloseEvent extends PlayerFormEvent { + CloseEvent(PlayerForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/PlayerView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/PlayerView.java new file mode 100644 index 0000000..3c4fe0d --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/PlayerView.java @@ -0,0 +1,130 @@ +package de.thpeetz.kontor.views.tysc; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.TyscConstants; +import de.thpeetz.kontor.data.tysc.Player; +import de.thpeetz.kontor.services.SportService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = TyscConstants.PLAYER_ROUTE, layout = MainLayout.class) +@PageTitle("Player | Tysc | Kontor") +public class PlayerView extends VerticalLayout { + + Grid grid = new Grid<>(Player.class); + TextField filterText = new TextField(); + PlayerForm form; + SportService service; + + public PlayerView(SportService service) { + this.service = service; + addClassName("player-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + public Grid getGrid() { + return grid; + } + + private void configureGrid() { + grid.addClassName("player-grid"); + grid.setSizeFull(); + grid.setColumns("firstName", "lastName"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editPlayer(event.getValue())); + } + + public PlayerForm getForm() { + return form; + } + + private void configureForm() { + form = new PlayerForm(); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::savePlayer); + form.addDeleteListener(this::deletePlayer); + form.addCloseListener(e -> closeEditor()); + } + + private void savePlayer(PlayerForm.SaveEvent event) { + service.savePlayer(event.getPlayer()); + updateList(); + closeEditor(); + } + + private void deletePlayer(PlayerForm.DeleteEvent event) { + service.deletePlayer(event.getPlayer()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addPlayerButton = new Button("Add player"); + addPlayerButton.addClickListener(click -> addPlayer()); + + HorizontalLayout toolbar = new HorizontalLayout(filterText, addPlayerButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editPlayer(Player player) { + if (player == null) { + closeEditor(); + } else { + form.setPlayer(player); + form.setRoosters(player.getRoosters()); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setPlayer(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addPlayer() { + grid.asSingleSelect().clear(); + editPlayer(new Player()); + } + + public void updateList() { + grid.setItems(service.findAllPlayers(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/PositionForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/PositionForm.java new file mode 100644 index 0000000..6fcc05c --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/PositionForm.java @@ -0,0 +1,115 @@ +package de.thpeetz.kontor.views.tysc; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.tysc.FieldPosition; +import de.thpeetz.kontor.data.tysc.Rooster; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PositionForm extends FormLayout { + + TextField name = new TextField("Name"); + Grid roosters = new Grid<>(Rooster.class); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(FieldPosition.class); + + public PositionForm() { + addClassName("position-form"); + binder.bindInstanceFields(this); + + roosters.setColumns("player.fullName", "team.name", "year"); + roosters.getColumns().forEach(col -> col.setAutoWidth(true)); + add(name, roosters, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setPosition(FieldPosition position) { + binder.setBean(position); + } + + public void setRoosters(List roosters) { + log.info("Setting roosters: {}", roosters); + this.roosters.setItems(roosters); + } + + public abstract static class PositionFormEvent extends ComponentEvent { + private FieldPosition position; + + protected PositionFormEvent(PositionForm source, FieldPosition position) { + super(source, false); + this.position = position; + } + + public FieldPosition getPosition() { + return position; + } + } + + public static class SaveEvent extends PositionFormEvent { + SaveEvent(PositionForm source, FieldPosition position) { + super(source, position); + } + } + + public static class DeleteEvent extends PositionFormEvent { + DeleteEvent(PositionForm source, FieldPosition position) { + super(source, position); + } + } + + public static class CloseEvent extends PositionFormEvent { + CloseEvent(PositionForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/PositionView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/PositionView.java new file mode 100644 index 0000000..a871723 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/PositionView.java @@ -0,0 +1,131 @@ +package de.thpeetz.kontor.views.tysc; + +import de.thpeetz.kontor.constants.TyscConstants; +import de.thpeetz.kontor.data.tysc.FieldPosition; +import de.thpeetz.kontor.services.SportService; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = TyscConstants.POSITION_ROUTE, layout = MainLayout.class) +@PageTitle("Position | Tysc | Kontor") +public class PositionView extends VerticalLayout { + + Grid grid = new Grid<>(FieldPosition.class); + TextField filterText = new TextField(); + PositionForm form; + SportService service; + + public PositionView(SportService service) { + this.service = service; + addClassName("position-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + public Grid getGrid() { + return grid; + } + + private void configureGrid() { + grid.addClassName("position-grid"); + grid.setSizeFull(); + grid.setColumns("shortName", "name", "sport.name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editPosition(event.getValue())); + } + + public PositionForm getForm() { + return form; + } + + private void configureForm() { + form = new PositionForm(); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::savePosition); + form.addDeleteListener(this::deletePosition); + form.addCloseListener(e -> closeEditor()); + } + + private void savePosition(PositionForm.SaveEvent event) { + service.savePosition(event.getPosition()); + updateList(); + closeEditor(); + } + + private void deletePosition(PositionForm.DeleteEvent event) { + service.deletePosition(event.getPosition()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addPositionButton = new Button("Add position"); + addPositionButton.addClickListener(click -> addPosition()); + + HorizontalLayout toolbar = new HorizontalLayout(filterText, addPositionButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editPosition(FieldPosition fieldPosition) { + if (fieldPosition == null) { + closeEditor(); + } else { + form.setPosition(fieldPosition); + form.setRoosters(fieldPosition.getRoosters()); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setPosition(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addPosition() { + grid.asSingleSelect().clear(); + editPosition(new FieldPosition()); + } + + public void updateList() { + grid.setItems(service.findAllPositions(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/RoosterForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/RoosterForm.java new file mode 100644 index 0000000..6b94eae --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/RoosterForm.java @@ -0,0 +1,117 @@ +package de.thpeetz.kontor.views.tysc; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.IntegerField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.tysc.FieldPosition; +import de.thpeetz.kontor.data.tysc.Player; +import de.thpeetz.kontor.data.tysc.Rooster; +import de.thpeetz.kontor.data.tysc.Team; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RoosterForm extends FormLayout { + IntegerField year = new IntegerField("Year"); + ComboBox team = new ComboBox<>("Team"); + ComboBox player = new ComboBox<>("Player"); + ComboBox position = new ComboBox<>("Position"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Rooster.class); + + public RoosterForm(List teams, List players, List positions) { + addClassName("rooster-form"); + binder.bindInstanceFields(this); + + team.setItems(teams); + team.setItemLabelGenerator(Team::getName); + player.setItems(players); + player.setItemLabelGenerator(Player::getFullName); + position.setItems(positions); + position.setItemLabelGenerator(FieldPosition::getName); + add(year, team, player, position, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setRooster(Rooster rooster) { + binder.setBean(rooster); + } + + public abstract static class RoosterFormEvent extends ComponentEvent { + private Rooster rooster; + + protected RoosterFormEvent(RoosterForm source, Rooster rooster) { + super(source, false); + this.rooster = rooster; + } + + public Rooster getRooster() { + return rooster; + } + } + + public static class SaveEvent extends RoosterFormEvent { + SaveEvent(RoosterForm source, Rooster rooster) { + super(source, rooster); + } + } + + public static class DeleteEvent extends RoosterFormEvent { + DeleteEvent(RoosterForm source, Rooster rooster) { + super(source, rooster); + } + } + + public static class CloseEvent extends RoosterFormEvent { + CloseEvent(RoosterForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/RoosterView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/RoosterView.java new file mode 100644 index 0000000..fc59be6 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/RoosterView.java @@ -0,0 +1,121 @@ +package de.thpeetz.kontor.views.tysc; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.TyscConstants; +import de.thpeetz.kontor.data.tysc.Rooster; +import de.thpeetz.kontor.services.SportService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = TyscConstants.ROOSTER_ROUTE, layout = MainLayout.class) +@PageTitle("Rooster | Tysc | Kontor") +public class RoosterView extends VerticalLayout { + + Grid grid = new Grid<>(Rooster.class); + RoosterForm form; + SportService service; + + public RoosterView(SportService service) { + this.service = service; + addClassName("rooster-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + public Grid getGrid() { + return grid; + } + + private void configureGrid() { + grid.addClassName("rooster-grid"); + grid.setSizeFull(); + grid.setColumns("year", "team.name", "player.fullName", "position.name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editRooster(event.getValue())); + } + + public RoosterForm getForm() { + return form; + } + + private void configureForm() { + form = new RoosterForm(service.findAllTeams(null), service.findAllPlayers(null), service.findAllPositions(null)); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveRooster); + form.addDeleteListener(this::deleteRooster); + form.addCloseListener(e -> closeEditor()); + } + + private void saveRooster(RoosterForm.SaveEvent event) { + service.saveRooster(event.getRooster()); + updateList(); + closeEditor(); + } + + private void deleteRooster(RoosterForm.DeleteEvent event) { + service.deleteRooster(event.getRooster()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + Button addRoosterButton = new Button("Add Rooster"); + addRoosterButton.addClickListener(click -> addRooster()); + + HorizontalLayout toolbar = new HorizontalLayout(addRoosterButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editRooster(Rooster rooster) { + if (rooster == null) { + closeEditor(); + } else { + form.setRooster(rooster); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setRooster(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addRooster() { + grid.asSingleSelect().clear(); + editRooster(new Rooster()); + } + + public void updateList() { + grid.setItems(service.findAllRoosters()); + } +} \ No newline at end of file diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/SportForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/SportForm.java new file mode 100644 index 0000000..20d98f4 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/SportForm.java @@ -0,0 +1,103 @@ +package de.thpeetz.kontor.views.tysc; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.tysc.Sport; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SportForm extends FormLayout { + + TextField name = new TextField("Name"); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Sport.class); + + public SportForm() { + addClassName("sport-form"); + binder.bindInstanceFields(this); + + add(name, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setSport(Sport sport) { + binder.setBean(sport); + } + + public abstract static class SportFormEvent extends ComponentEvent { + private Sport sport; + + protected SportFormEvent(SportForm source, Sport sport) { + super(source, false); + this.sport = sport; + } + + public Sport getSport() { + return sport; + } + } + + public static class SaveEvent extends SportFormEvent { + SaveEvent(SportForm source, Sport sport) { + super(source, sport); + } + } + + public static class DeleteEvent extends SportFormEvent { + DeleteEvent(SportForm source, Sport sport) { + super(source, sport); + } + } + + public static class CloseEvent extends SportFormEvent { + CloseEvent(SportForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/SportView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/SportView.java new file mode 100644 index 0000000..67faaa9 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/SportView.java @@ -0,0 +1,129 @@ +package de.thpeetz.kontor.views.tysc; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.TyscConstants; +import de.thpeetz.kontor.data.tysc.Sport; +import de.thpeetz.kontor.services.SportService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = TyscConstants.SPORT_ROUTE, layout = MainLayout.class) +@PageTitle("Sport | Tysc | Kontor") +public class SportView extends VerticalLayout { + + Grid grid = new Grid<>(Sport.class); + TextField filterText = new TextField(); + SportForm form; + SportService service; + + public SportView(SportService service) { + this.service = service; + addClassName("sport-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + public Grid getGrid() { + return grid; + } + + private void configureGrid() { + grid.addClassName("sport-grid"); + grid.setSizeFull(); + grid.setColumns("name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editSport(event.getValue())); + } + + public SportForm getForm() { + return form; + } + + private void configureForm() { + form = new SportForm(); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveSport); + form.addDeleteListener(this::deleteSport); + form.addCloseListener(e -> closeEditor()); + } + + private void saveSport(SportForm.SaveEvent event) { + service.saveSport(event.getSport()); + updateList(); + closeEditor(); + } + + private void deleteSport(SportForm.DeleteEvent event) { + service.deleteSport(event.getSport()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addSportButton = new Button("Add sport"); + addSportButton.addClickListener(click -> addSport()); + + HorizontalLayout toolbar = new HorizontalLayout(filterText, addSportButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editSport(Sport sport) { + if (sport == null) { + closeEditor(); + } else { + form.setSport(sport); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setSport(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addSport() { + grid.asSingleSelect().clear(); + editSport(new Sport()); + } + + public void updateList() { + grid.setItems(service.findAllSports(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/TeamForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/TeamForm.java new file mode 100644 index 0000000..8cc3bcb --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/TeamForm.java @@ -0,0 +1,115 @@ +package de.thpeetz.kontor.views.tysc; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.tysc.Rooster; +import de.thpeetz.kontor.data.tysc.Team; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class TeamForm extends FormLayout { + + TextField name = new TextField("Name"); + Grid roosters = new Grid<>(Rooster.class); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Team.class); + + public TeamForm() { + addClassName("team-form"); + binder.bindInstanceFields(this); + + roosters.setColumns("player.fullName", "position.name", "year"); + roosters.getColumns().forEach(col -> col.setAutoWidth(true)); + add(name, roosters, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setTeam(Team team) { + binder.setBean(team); + } + + public void setRoosters(List roosters) { + log.info("Setting roosters: {}", roosters); + this.roosters.setItems(roosters); + } + + public abstract static class TeamFormEvent extends ComponentEvent { + private Team team; + + protected TeamFormEvent(TeamForm source, Team team) { + super(source, false); + this.team = team; + } + + public Team getTeam() { + return team; + } + } + + public static class SaveEvent extends TeamFormEvent { + SaveEvent(TeamForm source, Team team) { + super(source, team); + } + } + + public static class DeleteEvent extends TeamFormEvent { + DeleteEvent(TeamForm source, Team team) { + super(source, team); + } + } + + public static class CloseEvent extends TeamFormEvent { + CloseEvent(TeamForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/TeamView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/TeamView.java new file mode 100644 index 0000000..2012798 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/TeamView.java @@ -0,0 +1,130 @@ +package de.thpeetz.kontor.views.tysc; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.TyscConstants; +import de.thpeetz.kontor.data.tysc.Team; +import de.thpeetz.kontor.services.SportService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = TyscConstants.TEAM_ROUTE, layout = MainLayout.class) +@PageTitle("Team | Tysc | Kontor") +public class TeamView extends VerticalLayout { + + Grid grid = new Grid<>(Team.class); + TextField filterText = new TextField(); + TeamForm form; + SportService service; + + public TeamView(SportService service) { + this.service = service; + addClassName("team-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + public Grid getGrid() { + return grid; + } + + private void configureGrid() { + grid.addClassName("team-grid"); + grid.setSizeFull(); + grid.setColumns("name", "shortName", "sport.name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editTeam(event.getValue())); + } + + public TeamForm getForm() { + return form; + } + + private void configureForm() { + form = new TeamForm(); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveTeam); + form.addDeleteListener(this::deleteTeam); + form.addCloseListener(e -> closeEditor()); + } + + private void saveTeam(TeamForm.SaveEvent event) { + service.saveTeam(event.getTeam()); + updateList(); + closeEditor(); + } + + private void deleteTeam(TeamForm.DeleteEvent event) { + service.deleteTeam(event.getTeam()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addTeamButton = new Button("Add team"); + addTeamButton.addClickListener(click -> addTeam()); + + HorizontalLayout toolbar = new HorizontalLayout(filterText, addTeamButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editTeam(Team team) { + if (team == null) { + closeEditor(); + } else { + form.setTeam(team); + form.setRoosters(team.getRoosters()); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setTeam(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addTeam() { + grid.asSingleSelect().clear(); + editTeam(new Team()); + } + + public void updateList() { + grid.setItems(service.findAllTeams(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/TyscLayout.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/TyscLayout.java new file mode 100644 index 0000000..989bd7d --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/TyscLayout.java @@ -0,0 +1,45 @@ +package de.thpeetz.kontor.views.tysc; + +import com.vaadin.flow.component.applayout.AppLayout; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.theme.lumo.LumoUtility; + +import de.thpeetz.kontor.constants.TyscConstants; +import de.thpeetz.kontor.security.SecurityService; +import de.thpeetz.kontor.services.AdminService; +import de.thpeetz.kontor.views.common.KontorLayoutUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.info.BuildProperties; + +/** + * Represents a custom layout for the comic view in the application. + * This layout extends the AppLayout class. + */ +@Slf4j +public class TyscLayout extends AppLayout { + + private final AdminService adminService; + + private final SecurityService securityService; + + private final BuildProperties buildProperties; + + public TyscLayout(AdminService adminService, SecurityService securityService, BuildProperties buildProperties) { + this.adminService = adminService; + this.securityService = securityService; + this.buildProperties = buildProperties; + + KontorLayoutUtil layout = new KontorLayoutUtil(this, adminService, securityService, buildProperties); + layout.setSecondaryNavigation(getSecondaryNavigation()); + layout.createHeader(TyscConstants.TYSC); + } + + private HorizontalLayout getSecondaryNavigation() { + HorizontalLayout navigation = new HorizontalLayout(); + navigation.addClassNames(LumoUtility.JustifyContent.CENTER, LumoUtility.Gap.SMALL, LumoUtility.Height.MEDIUM); + navigation.add(TyscConstants.getSportLink(), TyscConstants.getTeamLink(), TyscConstants.getPositionLink(), + TyscConstants.getPlayerLink(), TyscConstants.getRoosterLink(), TyscConstants.getVendorLink(), + TyscConstants.getCardSetLink(), TyscConstants.getCardLink()); + return navigation; + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/VendorForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/VendorForm.java new file mode 100644 index 0000000..8527da2 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/VendorForm.java @@ -0,0 +1,115 @@ +package de.thpeetz.kontor.views.tysc; + +import java.util.List; + +import com.vaadin.flow.component.ComponentEvent; +import com.vaadin.flow.component.ComponentEventListener; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.formlayout.FormLayout; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +import de.thpeetz.kontor.data.tysc.CardSet; +import de.thpeetz.kontor.data.tysc.Vendor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class VendorForm extends FormLayout { + + TextField name = new TextField("Name"); + Grid cardSets = new Grid<>(CardSet.class); + + Button save = new Button("Save"); + Button delete = new Button("Delete"); + Button close = new Button("Cancel"); + + Binder binder = new BeanValidationBinder<>(Vendor.class); + + public VendorForm() { + addClassName("vendor-form"); + binder.bindInstanceFields(this); + + cardSets.setColumns("name", "parallelSet"); + cardSets.getColumns().forEach(col -> col.setAutoWidth(true)); + add(name, cardSets, createButtonsLayout()); + } + + private HorizontalLayout createButtonsLayout() { + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + close.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + + save.addClickShortcut(Key.ENTER); + close.addClickShortcut(Key.ESCAPE); + + save.addClickListener(event -> validateAndSave()); + delete.addClickListener(event -> fireEvent(new DeleteEvent(this, binder.getBean()))); + close.addClickListener(event -> fireEvent(new CloseEvent(this))); + + binder.addStatusChangeListener(e -> save.setEnabled(binder.isValid())); + return new HorizontalLayout(save, delete, close); + } + + private void validateAndSave() { + if (binder.isValid()) { + fireEvent(new SaveEvent(this, binder.getBean())); + } + } + + public void setVendor(Vendor vendor) { + binder.setBean(vendor); + } + + public void setCardSets(List sets) { + log.info("Setting card sets: {}", sets); + this.cardSets.setItems(sets); + } + + public abstract static class VendorFormEvent extends ComponentEvent { + private Vendor vendor; + + protected VendorFormEvent(VendorForm source, Vendor vendor) { + super(source, false); + this.vendor = vendor; + } + + public Vendor getVendor() { + return vendor; + } + } + + public static class SaveEvent extends VendorFormEvent { + SaveEvent(VendorForm source, Vendor vendor) { + super(source, vendor); + } + } + + public static class DeleteEvent extends VendorFormEvent { + DeleteEvent(VendorForm source, Vendor vendor) { + super(source, vendor); + } + } + + public static class CloseEvent extends VendorFormEvent { + CloseEvent(VendorForm source) { + super(source, null); + } + } + + public void addDeleteListener(ComponentEventListener listener) { + addListener(DeleteEvent.class, listener); + } + + public void addSaveListener(ComponentEventListener listener) { + addListener(SaveEvent.class, listener); + } + + public void addCloseListener(ComponentEventListener listener) { + addListener(CloseEvent.class, listener); + } +} diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/VendorView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/VendorView.java new file mode 100644 index 0000000..6dd8821 --- /dev/null +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/views/tysc/VendorView.java @@ -0,0 +1,130 @@ +package de.thpeetz.kontor.views.tysc; + +import org.springframework.context.annotation.Scope; + +import com.vaadin.flow.component.Component; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.annotation.SpringComponent; + +import de.thpeetz.kontor.constants.TyscConstants; +import de.thpeetz.kontor.data.tysc.Vendor; +import de.thpeetz.kontor.services.CardService; +import de.thpeetz.kontor.views.common.MainLayout; +import jakarta.annotation.security.PermitAll; + +@SpringComponent +@Scope("prototype") +@PermitAll +@Route(value = TyscConstants.VENDOR_ROUTE, layout = MainLayout.class) +@PageTitle("Vendor | Tysc | Kontor") +public class VendorView extends VerticalLayout { + + Grid grid = new Grid<>(Vendor.class); + TextField filterText = new TextField(); + VendorForm form; + CardService service; + + public VendorView(CardService service) { + this.service = service; + addClassName("vendor-view"); + setSizeFull(); + configureGrid(); + configureForm(); + + add(getToolbar(), getContent()); + updateList(); + } + + public Grid getGrid() { + return grid; + } + + private void configureGrid() { + grid.addClassName("vendor-grid"); + grid.setSizeFull(); + grid.setColumns("name"); + grid.getColumns().forEach(col -> col.setAutoWidth(true)); + grid.asSingleSelect().addValueChangeListener(event -> editVendor(event.getValue())); + } + + public VendorForm getForm() { + return form; + } + + private void configureForm() { + form = new VendorForm(); + form.setWidth("25em"); + form.setVisible(false); + form.addSaveListener(this::saveVendor); + form.addDeleteListener(this::deleteVendor); + form.addCloseListener(e -> closeEditor()); + } + + private void saveVendor(VendorForm.SaveEvent event) { + service.saveVendor(event.getVendor()); + updateList(); + closeEditor(); + } + + private void deleteVendor(VendorForm.DeleteEvent event) { + service.deleteVendor(event.getVendor()); + updateList(); + closeEditor(); + } + + private Component getContent() { + HorizontalLayout content = new HorizontalLayout(grid, form); + content.setFlexGrow(2, grid); + content.setFlexGrow(1, form); + content.addClassName("content"); + content.setSizeFull(); + return content; + } + + private HorizontalLayout getToolbar() { + filterText.setPlaceholder("Filter by name..."); + filterText.setClearButtonVisible(true); + filterText.setValueChangeMode(ValueChangeMode.LAZY); + filterText.addValueChangeListener(e -> updateList()); + + Button addVendorButton = new Button("Add vendor"); + addVendorButton.addClickListener(click -> addVendor()); + + HorizontalLayout toolbar = new HorizontalLayout(filterText, addVendorButton); + toolbar.addClassName("toolbar"); + return toolbar; + } + + public void editVendor(Vendor vendor) { + if (vendor == null) { + closeEditor(); + } else { + form.setVendor(vendor); + form.setCardSets(vendor.getCardSets()); + form.setVisible(true); + addClassName("editing"); + } + } + + private void closeEditor() { + form.setVendor(null); + form.setVisible(false); + removeClassName("editing"); + } + + private void addVendor() { + grid.asSingleSelect().clear(); + editVendor(new Vendor()); + } + + public void updateList() { + grid.setItems(service.findAllVendors(filterText.getValue())); + } +} diff --git a/kontor-spring/src/main/resources/application.yml b/kontor-spring/src/main/resources/application.yml index b62e4d4..f8454b5 100644 --- a/kontor-spring/src/main/resources/application.yml +++ b/kontor-spring/src/main/resources/application.yml @@ -1,7 +1,7 @@ app: - name: 'Kontor' - shortName: 'Kontor' - description: 'Kontor is a Spring Boot application' + name: "Kontor" + shortName: "Kontor" + description: "Kontor is a Spring Boot application" spring: profiles: active: local,dev,test,prod @@ -25,6 +25,9 @@ spring: max-file-size: 10MB max-request-size: 10MB camel: + component: + metrics: + metric-registry: prometheusMeterRegistry cloud: enabled: true springboot: @@ -36,6 +39,9 @@ management: web: exposure: include: health,info,metrics,prometheus,camelroutes + info: + git: + mode: full endpoint: health: show-details: always @@ -58,15 +64,15 @@ logging: springframework: controllers: DEBUG jwt: - auth: - secret: 'J6GOtcwC2NJI1l0VkHu20PacPFGTxpirBxWwynoHjsc=' + auth: + secret: "J6GOtcwC2NJI1l0VkHu20PacPFGTxpirBxWwynoHjsc=" mail: - protocol: 'imap' - host: 'corky.svpdata.eu' - port: 143 - userName: 'thomas.peetz@thpeetz.de' - password: 'fS9f4JYDIO7A' - starttls: true + protocol: "imap" + host: "corky.svpdata.eu" + port: 143 + userName: "thomas.peetz@thpeetz.de" + password: "fS9f4JYDIO7A" + starttls: true --- spring: config: @@ -74,8 +80,8 @@ spring: on-profile: prod datasource: url: jdbc:postgresql://postgres:5432/kontor - username: 'kontor' - password: 'kontor' + username: "kontor" + password: "kontor" artemis: mode: native broker-url: tcp://activemq:61616 diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/TestConstants.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/TestConstants.java deleted file mode 100644 index bb9d04d..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/TestConstants.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.thpeetz.kontor.bookshelf; - -public class TestConstants { - - public static final Integer ARTICLEAUTHOR_COUNT = 0; - public static final Integer ARTICLE_COUNT = 0; - public static final Integer AUTHOR_COUNT = 1; - public static final Integer BOOKAUTHOR_COUNT = 0; - public static final Integer BOOK_COUNT = 0; - public static final Integer PUBLISHER_COUNT = 0; - public static final String ARTICLE_TITLE = "Title"; - public static final String AUTHOR_FIRSTNAME = "Firstname"; - public static final String AUTHOR_LASTNAME = "Lastname"; - public static final String PUBLISHER_NIKOL = "Nikol Verlags GmbH"; - public static final String PUBLISHER_NAME = "Publisher"; - public static final String PUBLISHER_SEARCH = "kol"; - public static final String BOOK_TITLE = "Book Title"; - public static final String BOOK_ISBN = "978-3-123-467-890"; -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/ArticleAuthorRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/ArticleAuthorRepositoryTest.java deleted file mode 100644 index b54b976..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/ArticleAuthorRepositoryTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import de.thpeetz.kontor.bookshelf.TestConstants; -import org.junit.jupiter.api.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -@SpringBootTest -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -@Disabled -class ArticleAuthorRepositoryTest { - - @Autowired - ArticleAuthorRepository articleAuthorRepository; - - @Autowired - AuthorRepository authorRepository; - - @Autowired - ArticleRepository articleRepository; - - @Test - @Order(1) - void saveArticleAuthor() { - Author author = new Author(); - author.setFirstName(TestConstants.AUTHOR_FIRSTNAME); - author.setLastName(TestConstants.AUTHOR_LASTNAME); - Author savedAuthor = authorRepository.save(author); - assertEquals(TestConstants.AUTHOR_COUNT+1, authorRepository.findAll().size()); - Article article = new Article(); - article.setTitle(TestConstants.ARTICLE_TITLE); - Article savedArticle = articleRepository.save(article); - ArticleAuthor articleAuthor = new ArticleAuthor(); - articleAuthor.setArticle(article); - articleAuthor.setAuthor(author); - ArticleAuthor savedArticleAuthor = articleAuthorRepository.save(articleAuthor); - assertEquals(TestConstants.ARTICLEAUTHOR_COUNT+1, articleAuthorRepository.findAll().size()); - } - - @Test - @Order(2) - void testFindByArticle() { - Article article = articleRepository.findByTitle(TestConstants.ARTICLE_TITLE).get(0); - assertEquals(1, articleAuthorRepository.findByArticle(article).size()); - } - - @Test - @Order(3) - void testFindByAuthor() { - Author author = authorRepository.findByFirstNameAndLastName(TestConstants.AUTHOR_FIRSTNAME, TestConstants.AUTHOR_LASTNAME); - assertEquals(1, articleAuthorRepository.findByAuthor(author).size()); - } - - @Test - @Order(4) - void deleteArticleAuthor() { - assertEquals(1, articleAuthorRepository.findAll().size()); - ArticleAuthor articleAuthor = articleAuthorRepository.findAll().get(0); - Author author = articleAuthor.getAuthor(); - author.getArticleAuthors().remove(articleAuthor); - author = authorRepository.save(author); - Article article = articleAuthor.getArticle(); - article.getAuthors().remove(articleAuthor); - article = articleRepository.save(article); - articleAuthorRepository.delete(articleAuthor); - assertEquals(TestConstants.ARTICLEAUTHOR_COUNT, articleAuthorRepository.findAll().size()); - authorRepository.delete(author); - assertEquals(TestConstants.AUTHOR_COUNT, authorRepository.findAll().size()); - articleRepository.delete(article); - assertEquals(TestConstants.ARTICLE_COUNT, articleRepository.findAll().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/ArticleAuthorTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/ArticleAuthorTest.java deleted file mode 100644 index bd14fd3..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/ArticleAuthorTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import de.thpeetz.kontor.bookshelf.TestConstants; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.TransactionSystemException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -@Disabled -class ArticleAuthorTest { - - @Autowired - ArticleRepository articleRepository; - - @Autowired - AuthorRepository authorRepository; - - @Autowired - ArticleAuthorRepository articleAuthorRepository; - - @Test - @Order(1) - void checkInitialLoad() { - assertEquals(TestConstants.ARTICLEAUTHOR_COUNT, articleAuthorRepository.findAll().size()); - } - - @Test - @Order(2) - void exceptionThrownWhenSavingEmptyValues() { - ArticleAuthor articleAuthor = new ArticleAuthor(); - assertThrows(TransactionSystemException.class, () -> { - articleAuthorRepository.save(articleAuthor); - }); - } - - @Test - @Order(3) - void exceptionThrownWhenSavingIdenticalEntry() { - Author author = new Author(); - author.setFirstName(TestConstants.AUTHOR_FIRSTNAME); - author.setLastName(TestConstants.AUTHOR_LASTNAME); - Author savedAuthor = authorRepository.save(author); - Article article = new Article(); - article.setTitle(TestConstants.ARTICLE_TITLE); - Article savedArticle = articleRepository.save(article); - ArticleAuthor articleAuthor = new ArticleAuthor(); - articleAuthor.setArticle(article); - articleAuthor.setAuthor(author); - ArticleAuthor savedArticleAuthor = articleAuthorRepository.save(articleAuthor); - ArticleAuthor articleAuthor1 = new ArticleAuthor(); - articleAuthor1.setArticle(article); - articleAuthor1.setAuthor(author); - assertThrows(DataIntegrityViolationException.class, () -> { - articleAuthorRepository.save(articleAuthor1); - }); - articleAuthorRepository.delete(savedArticleAuthor); - assertEquals(TestConstants.ARTICLEAUTHOR_COUNT, articleAuthorRepository.findAll().size()); - savedAuthor.getArticleAuthors().remove(savedArticleAuthor); - authorRepository.save(savedAuthor); - authorRepository.delete(savedAuthor); - assertEquals(TestConstants.AUTHOR_COUNT, authorRepository.findAll().size()); - savedArticle.getAuthors().remove(savedArticleAuthor); - articleRepository.save(savedArticle); - articleRepository.delete(savedArticle); - assertEquals(TestConstants.ARTICLE_COUNT, articleRepository.findAll().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/ArticleRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/ArticleRepositoryTest.java deleted file mode 100644 index 7d74119..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/ArticleRepositoryTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import de.thpeetz.kontor.bookshelf.TestConstants; -import org.junit.jupiter.api.MethodOrderer; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -class ArticleRepositoryTest { - - @Autowired - ArticleRepository articleRepository; - - @Test - @Order(1) - void checkInitialLoad() { - assertEquals(TestConstants.ARTICLE_COUNT, articleRepository.findAll().size()); - } - - @Test - @Order(2) - void saveArticle() { - Article article = new Article(); - article.setTitle(TestConstants.ARTICLE_TITLE); - articleRepository.save(article); - assertEquals(TestConstants.ARTICLE_COUNT+1, articleRepository.findAll().size()); - } - - @Test - @Order(3) - void search() { - List
    articles = articleRepository.search(TestConstants.ARTICLE_TITLE.substring(2,5)); - assertEquals(1, articles.size()); - assertEquals(0, articleRepository.search(TestConstants.BOOK_TITLE).size()); - } - - @Test - @Order(4) - void findByTitle() { - List
    articles = articleRepository.search(TestConstants.ARTICLE_TITLE); - assertEquals(1, articles.size()); - } - - @Test - @Order(5) - void deleteArticle() { - List
    articles = articleRepository.findAll(); - assertEquals(1, articles.size()); - assertEquals(0, articles.get(0).getAuthors().size()); - articleRepository.delete(articles.get(0)); - assertEquals(TestConstants.ARTICLE_COUNT, articleRepository.findAll().size()); - } -} \ No newline at end of file diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/ArticleTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/ArticleTest.java deleted file mode 100644 index 2179dfe..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/ArticleTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import de.thpeetz.kontor.bookshelf.TestConstants; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.TransactionSystemException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -@SpringBootTest -class ArticleTest { - - @Autowired - ArticleRepository articleRepository; - - @Test - void checkInitialLoad() { - assertEquals(TestConstants.BOOK_COUNT, articleRepository.findAll().size()); - } - - @Test - void exceptionThrownWhenSavingEmptyFields() { - Article article = new Article(); - assertThrows(TransactionSystemException.class, () -> { - articleRepository.save(article); - }); - } - - @Test - void exceptionThrownWhenSavingIdenticalTitle() { - Article article = new Article(); - article.setTitle(TestConstants.ARTICLE_TITLE); - Article savedArticle = articleRepository.save(article); - Article article1 = new Article(); - article1.setTitle(article.getTitle()); - assertThrows(DataIntegrityViolationException.class, ()-> { - articleRepository.save(article1); - }); - articleRepository.delete(savedArticle); - assertEquals(TestConstants.ARTICLE_COUNT, articleRepository.findAll().size()); - } -} \ No newline at end of file diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/AuthorRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/AuthorRepositoryTest.java deleted file mode 100644 index f984d11..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/AuthorRepositoryTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import de.thpeetz.kontor.bookshelf.TestConstants; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -@Disabled -class AuthorRepositoryTest { - - @Autowired - AuthorRepository authorRepository; - - @Test - @Order(1) - void checkInitialLoad() { - assertEquals(TestConstants.AUTHOR_COUNT, authorRepository.findAll().size()); - } - - @Test - @Order(2) - void saveAutor() { - Author author = new Author(); - author.setFirstName(TestConstants.AUTHOR_FIRSTNAME); - author.setLastName(TestConstants.AUTHOR_LASTNAME); - authorRepository.save(author); - assertEquals(TestConstants.AUTHOR_COUNT+1, authorRepository.findAll().size()); - } - - @Test - @Order(3) - void findAuthor() { - Author existingAuthor = authorRepository.findAll().get(0); - assertNotNull(existingAuthor); - Author found = authorRepository.findByFirstNameAndLastName(existingAuthor.getFirstName(), existingAuthor.getLastName()); - assertEquals(existingAuthor, found); - } - - @Test - @Order(4) - void searchAuthor() { - List authors = authorRepository.search("glas"); - assertEquals(1, authors.size()); - assertEquals("Douglas", authors.get(0).getFirstName()); - List authors2 = authorRepository.search("dams"); - assertEquals(1, authors2.size()); - assertEquals("Adams", authors2.get(0).getLastName()); - } - - @Test - @Order(5) - void deleteAuthor() { - Author existingAuthor = authorRepository.findByFirstNameAndLastName(TestConstants.AUTHOR_FIRSTNAME, TestConstants.AUTHOR_LASTNAME); - assertNotNull(existingAuthor); - authorRepository.delete(existingAuthor); - assertEquals(TestConstants.AUTHOR_COUNT, authorRepository.findAll().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/AuthorTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/AuthorTest.java deleted file mode 100644 index 149c263..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/AuthorTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import de.thpeetz.kontor.bookshelf.TestConstants; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.TransactionSystemException; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest -class AuthorTest { - - @Autowired - private AuthorRepository authorRepository; - - @Test - void throwExceptionWhenPlayerSavedWithEmptyName() { - Author author = new Author(); - assertThrows(TransactionSystemException.class, () -> { - authorRepository.save(author); - }); - } - - @Test - void throwExceptionWhenPlayerSavedWithExistingName() { - assertEquals(TestConstants.AUTHOR_COUNT, authorRepository.findAll().size()); - Author existingAuthor = new Author(); - existingAuthor.setFirstName(TestConstants.AUTHOR_FIRSTNAME); - existingAuthor.setLastName(TestConstants.AUTHOR_LASTNAME); - existingAuthor = authorRepository.save(existingAuthor); - assertEquals(TestConstants.AUTHOR_COUNT+1, authorRepository.findAll().size()); - Author author = new Author(); - author.setFirstName(existingAuthor.getFirstName()); - author.setLastName(existingAuthor.getLastName()); - assertThrows(DataIntegrityViolationException.class, () -> { - authorRepository.save(author); - }); - assertNotNull(existingAuthor); - authorRepository.delete(existingAuthor); - assertEquals(TestConstants.AUTHOR_COUNT, authorRepository.findAll().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookAuthorRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookAuthorRepositoryTest.java deleted file mode 100644 index 4df5fd9..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookAuthorRepositoryTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import de.thpeetz.kontor.bookshelf.TestConstants; -import org.junit.jupiter.api.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -@SpringBootTest -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -@Disabled -class BookAuthorRepositoryTest { - - @Autowired - BookRepository bookRepository; - - @Autowired - AuthorRepository authorRepository; - - @Autowired - BookAuthorRepository bookAuthorRepository; - - @Autowired - BookshelfPublisherRepository bookshelfPublisherRepository; - - @Test - @Order(1) - void saveBookAuthor() { - Author author = new Author(); - author.setFirstName(TestConstants.AUTHOR_FIRSTNAME); - author.setLastName(TestConstants.AUTHOR_LASTNAME); - Author savedAuthor = authorRepository.save(author); - assertEquals(TestConstants.AUTHOR_COUNT+1, authorRepository.findAll().size()); - BookshelfPublisher publisher = new BookshelfPublisher(); - publisher.setName(TestConstants.PUBLISHER_NAME); - BookshelfPublisher savedPublisher = bookshelfPublisherRepository.save(publisher); - assertEquals(TestConstants.PUBLISHER_COUNT+1, bookshelfPublisherRepository.findAll().size()); - Book book = new Book(); - book.setTitle(TestConstants.ARTICLE_TITLE); - book.setIsbn(TestConstants.BOOK_ISBN); - book.setPublisher(savedPublisher); - Book savedBook = bookRepository.save(book); - assertEquals(TestConstants.BOOK_COUNT+1, bookRepository.findAll().size()); - BookAuthor bookAuthor = new BookAuthor(); - bookAuthor.setBook(savedBook); - bookAuthor.setAuthor(savedAuthor); - BookAuthor savedBookAuthor = bookAuthorRepository.save(bookAuthor); - assertEquals(TestConstants.BOOKAUTHOR_COUNT+1, bookAuthorRepository.findAll().size()); - } - - @Test - @Order(2) - void testFindByBook() { - List bookAuthors = bookAuthorRepository.findAll(); - assertEquals(1, bookAuthors.size()); - Book book = bookAuthors.get(0).getBook(); - assertEquals(1, bookAuthorRepository.findByBook(book).size()); - } - - @Test - @Order(3) - void testFindByAuthor() { - List bookAuthors = bookAuthorRepository.findAll(); - assertEquals(1, bookAuthors.size()); - Author author = bookAuthors.get(0).getAuthor(); - assertEquals(1, bookAuthorRepository.findByAuthor(author).size()); - } - - @Test - @Order(4) - void deleteBookAuthor() { - BookAuthor bookAuthor = bookAuthorRepository.findAll().get(0); - Author author = bookAuthor.getAuthor(); - author.getBookAuthors().remove(bookAuthor); - author = authorRepository.save(author); - Book book = bookAuthor.getBook(); - book.getAuthors().remove(bookAuthor); - BookshelfPublisher publisher = book.getPublisher(); - publisher.getBooks().remove(book); - bookshelfPublisherRepository.save(publisher); - book = bookRepository.save(book); - bookshelfPublisherRepository.delete(publisher); - assertEquals(TestConstants.PUBLISHER_COUNT, bookshelfPublisherRepository.findAll().size()); - bookAuthorRepository.delete(bookAuthor); - assertEquals(TestConstants.BOOKAUTHOR_COUNT, bookAuthorRepository.findAll().size()); - authorRepository.delete(author); - assertEquals(TestConstants.AUTHOR_COUNT, authorRepository.findAll().size()); - bookRepository.delete(book); - assertEquals(TestConstants.BOOK_COUNT, bookRepository.findAll().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookAuthorTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookAuthorTest.java deleted file mode 100644 index dc79341..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookAuthorTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import de.thpeetz.kontor.bookshelf.TestConstants; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.TransactionSystemException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -@SpringBootTest -@Disabled -class BookAuthorTest { - - @Autowired - BookRepository bookRepository; - - @Autowired - AuthorRepository authorRepository; - - @Autowired - BookAuthorRepository bookAuthorRepository; - - @Autowired - BookshelfPublisherRepository bookshelfPublisherRepository; - - @Test - void checkInitialLoad() { - assertEquals(TestConstants.BOOKAUTHOR_COUNT, bookAuthorRepository.findAll().size()); - } - - @Test - void exceptionThrownWhenSavingEmptyValues() { - BookAuthor bookAuthor = new BookAuthor(); - assertThrows(TransactionSystemException.class, () -> { - bookAuthorRepository.save(bookAuthor); - }); - } - - @Test - void exceptionThrownWhenSavingIdenticalEntry() { - Author author = new Author(); - author.setFirstName(TestConstants.AUTHOR_FIRSTNAME); - author.setLastName(TestConstants.AUTHOR_LASTNAME); - Author savedAuthor = authorRepository.save(author); - BookshelfPublisher publisher = new BookshelfPublisher(); - publisher.setName(TestConstants.PUBLISHER_NAME); - BookshelfPublisher savedPublisher = bookshelfPublisherRepository.save(publisher); - Book book = new Book(); - book.setTitle(TestConstants.BOOK_TITLE); - book.setIsbn(TestConstants.BOOK_ISBN); - book.setPublisher(publisher); - Book savedBook = bookRepository.save(book); - BookAuthor bookAuthor = new BookAuthor(); - bookAuthor.setBook(book); - bookAuthor.setAuthor(author); - BookAuthor savedBookAuthor = bookAuthorRepository.save(bookAuthor); - BookAuthor bookAuthor1 = new BookAuthor(); - bookAuthor1.setBook(book); - bookAuthor1.setAuthor(author); - assertThrows(DataIntegrityViolationException.class, () -> { - bookAuthorRepository.save(bookAuthor1); - }); - savedAuthor.getBookAuthors().remove(savedBookAuthor); - authorRepository.save(savedAuthor); - savedBook.getAuthors().remove(savedBookAuthor); - bookRepository.save(savedBook); - savedPublisher.getBooks().remove(savedBook); - bookshelfPublisherRepository.save(savedPublisher); - authorRepository.delete(savedAuthor); - assertEquals(TestConstants.AUTHOR_COUNT, authorRepository.findAll().size()); - bookRepository.delete(savedBook); - assertEquals(TestConstants.ARTICLE_COUNT, bookRepository.findAll().size()); - bookshelfPublisherRepository.delete(savedPublisher); - assertEquals(TestConstants.PUBLISHER_COUNT, bookshelfPublisherRepository.findAll().size()); - bookAuthorRepository.delete(savedBookAuthor); - assertEquals(TestConstants.ARTICLEAUTHOR_COUNT, bookAuthorRepository.findAll().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookRepositoryTest.java deleted file mode 100644 index 969d465..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookRepositoryTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import de.thpeetz.kontor.bookshelf.TestConstants; -import org.junit.jupiter.api.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -@SpringBootTest -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -@Disabled -class BookRepositoryTest { - - @Autowired - BookRepository bookRepository; - - @Autowired - BookshelfPublisherRepository bookshelfPublisherRepository; - - @Test - @Order(1) - void checkInitialLoad(){ - assertEquals(TestConstants.BOOK_COUNT, bookRepository.findAll().size()); - } - - @Test - @Order(2) - void saveBook() { - BookshelfPublisher publisher = new BookshelfPublisher(); - publisher.setName(TestConstants.PUBLISHER_NAME); - bookshelfPublisherRepository.save(publisher); - Book book = new Book(); - book.setTitle(TestConstants.BOOK_TITLE); - book.setIsbn(TestConstants.BOOK_ISBN); - book.setPublisher(publisher); - bookRepository.save(book); - assertEquals(TestConstants.BOOK_COUNT+1, bookRepository.findAll().size()); - } - - @Test - @Order(3) - void search() { - List books = bookRepository.search(TestConstants.BOOK_TITLE.substring(2,5)); - assertEquals(1, books.size()); - assertEquals(1, bookRepository.search(TestConstants.BOOK_ISBN.substring(3,7)).size()); - assertEquals(0, bookRepository.search("Article").size()); - } - - @Test - @Order(4) - void findByTitle() { - List books = bookRepository.findByTitle(TestConstants.BOOK_TITLE); - assertEquals(1, books.size()); - assertEquals(TestConstants.BOOK_ISBN, books.get(0).getIsbn()); - } - - @Test - @Order(5) - void findByTitleIgnoreCase() { - List books = bookRepository.findByTitleIgnoreCase(TestConstants.BOOK_TITLE.toLowerCase()); - assertEquals(1, books.size()); - assertEquals(TestConstants.BOOK_ISBN, books.get(0).getIsbn()); - } - - @Test - @Order(6) - void findByIsbn() { - List books = bookRepository.findByIsbn(TestConstants.BOOK_ISBN); - assertEquals(1, books.size()); - assertEquals(TestConstants.BOOK_TITLE, books.get(0).getTitle()); - } - - @Test - @Order(7) - void deleteBook() { - List books = bookRepository.findByIsbn(TestConstants.BOOK_ISBN); - Book book = books.get(0); - BookshelfPublisher publisher = book.getPublisher(); - bookshelfPublisherRepository.delete(publisher); - bookRepository.delete(book); - assertEquals(TestConstants.BOOK_COUNT, bookRepository.findAll().size()); - assertEquals(TestConstants.PUBLISHER_COUNT, bookshelfPublisherRepository.findAll().size()); - } -} \ No newline at end of file diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookTest.java deleted file mode 100644 index 0ac3324..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import de.thpeetz.kontor.bookshelf.TestConstants; -import de.thpeetz.kontor.comics.data.Publisher; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.orm.jpa.JpaSystemException; -import org.springframework.transaction.TransactionSystemException; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest -class BookTest { - - @Autowired - BookRepository bookRepository; - - @Autowired - BookshelfPublisherRepository bookshelfPublisherRepository; - - @Test - void checkInitialLoad() { - assertEquals(TestConstants.BOOK_COUNT, bookRepository.findAll().size()); - } - - @Test - void exceptionThrownWhenSavingEmptyFields() { - Book book = new Book(); - assertThrows(TransactionSystemException.class, () -> { - bookRepository.save(book); - }); - } - - @Test - void exceptionThrownWhenSavingIdenticalISBN() { - BookshelfPublisher publisher = new BookshelfPublisher(); - publisher.setName(TestConstants.PUBLISHER_NAME); - BookshelfPublisher savedPublisher = bookshelfPublisherRepository.save(publisher); - Book book = new Book(); - book.setTitle(TestConstants.BOOK_TITLE); - book.setIsbn(TestConstants.BOOK_ISBN); - book.setPublisher(savedPublisher); - Book savedBook = bookRepository.save(book); - Book book1 = new Book(); - book1.setTitle(book.getTitle()); - book1.setIsbn(book.getIsbn()); - assertThrows(TransactionSystemException.class, ()-> { - bookRepository.save(book1); - }); - bookRepository.delete(book); - assertEquals(TestConstants.BOOK_COUNT, bookRepository.findAll().size()); - bookshelfPublisherRepository.delete(savedPublisher); - assertEquals(TestConstants.PUBLISHER_COUNT, bookshelfPublisherRepository.findAll().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookshelfPublisherRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookshelfPublisherRepositoryTest.java deleted file mode 100644 index 98b60fa..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookshelfPublisherRepositoryTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.bookshelf.TestConstants; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -class BookshelfPublisherRepositoryTest { - - @Autowired - private BookshelfPublisherRepository publisherRepository; - - @Test - @Order(1) - void checkInitialLoad() { - assertEquals(TestConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); - } - - @Test - @Order(2) - void savePublisher() { - BookshelfPublisher publisher = new BookshelfPublisher(); - publisher.setName(TestConstants.PUBLISHER_NAME); - publisherRepository.save(publisher); - assertEquals(TestConstants.PUBLISHER_COUNT + 1, publisherRepository.findAll().size()); - } - - @Test - @Order(3) - void findPublisherByName() { - assertEquals(TestConstants.PUBLISHER_COUNT + 1, publisherRepository.findAll().size()); - log.info("Liste der Publisher: {}", publisherRepository.findAll()); - BookshelfPublisher publisher = publisherRepository.findByName(TestConstants.PUBLISHER_NAME); - assertNotNull(publisher); - assertEquals(TestConstants.PUBLISHER_NAME, publisher.getName()); - BookshelfPublisher notFound = publisherRepository.findByName(TestConstants.PUBLISHER_SEARCH); - assertNull(notFound); - List publishers = publisherRepository - .findByNameIgnoreCase(TestConstants.PUBLISHER_NAME.toLowerCase()); - assertEquals(1, publishers.size()); - assertEquals(TestConstants.PUBLISHER_NAME, publishers.get(0).getName()); - } - - @Test - @Order(4) - void searchPublisher() { - List publishers = publisherRepository.search(TestConstants.PUBLISHER_NAME.substring(2, 6)); - assertEquals(1, publishers.size()); - assertEquals(TestConstants.PUBLISHER_NAME, publishers.get(0).getName()); - } - - @Test - @Order(5) - void deletePublisher() { - BookshelfPublisher publisher = publisherRepository.findByName(TestConstants.PUBLISHER_NAME); - assertNotNull(publisher); - publisherRepository.delete(publisher); - assertEquals(TestConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookshelfPublisherTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookshelfPublisherTest.java deleted file mode 100644 index 7a73ae1..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/data/BookshelfPublisherTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.thpeetz.kontor.bookshelf.data; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.bookshelf.TestConstants; - -@SpringBootTest -class BookshelfPublisherTest { - - @Autowired - private BookshelfPublisherRepository publisherRepository; - - @Test - void checkInitialDataLoad() { - assertEquals(TestConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); - } - - @Test - void throwExceptionWhenPublisherSavedWithEmptyName() { - BookshelfPublisher publisher = new BookshelfPublisher(); - assertThrows(TransactionSystemException.class, () -> { - publisherRepository.save(publisher); - }); - } - - @Test - void savePublisherWithIdenticalName() { - BookshelfPublisher publisher1 = new BookshelfPublisher(); - publisher1.setName(TestConstants.PUBLISHER_NAME); - publisherRepository.save(publisher1); - BookshelfPublisher publisher2 = new BookshelfPublisher(); - publisher2.setName(TestConstants.PUBLISHER_NAME); - assertThrows(DataIntegrityViolationException.class, () -> { - publisherRepository.save(publisher2); - }); - publisherRepository.delete(publisher1); - assertEquals(TestConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/services/BookshelfServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/services/BookshelfServiceTest.java deleted file mode 100644 index b78a899..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/bookshelf/services/BookshelfServiceTest.java +++ /dev/null @@ -1,102 +0,0 @@ -package de.thpeetz.kontor.bookshelf.services; - -import de.thpeetz.kontor.bookshelf.TestConstants; -import de.thpeetz.kontor.bookshelf.data.Author; -import de.thpeetz.kontor.bookshelf.data.Book; -import de.thpeetz.kontor.bookshelf.data.BookshelfPublisher; -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -class BookshelfServiceTest { - - @Autowired - private BookshelfService bookshelfService; - - @Test - @Order(1) - void testFindAllPublishers() { - List publishers = bookshelfService.findAllPublishers(null); - assertEquals(TestConstants.PUBLISHER_COUNT, publishers.size()); - } - - @Test - @Order(2) - void testSavePublisher() { - BookshelfPublisher publisher = new BookshelfPublisher(); - publisher.setName(TestConstants.PUBLISHER_NAME); - bookshelfService.savePublisher(publisher); - assertEquals(TestConstants.PUBLISHER_COUNT + 1, bookshelfService.findAllPublishers(null).size()); - } - - @Test - @Order(3) - void testFindPublisherByName() { - assertEquals(TestConstants.PUBLISHER_COUNT + 1, bookshelfService.findAllPublishers(null).size()); - BookshelfPublisher publisher = bookshelfService.findPublisherByName(TestConstants.PUBLISHER_NAME); - assertNotNull(publisher); - } - - @Test - @Order(4) - void testDeletePublisher() { - List publishers = bookshelfService.findAllPublishers(TestConstants.PUBLISHER_NAME); - assertEquals(1, publishers.size()); - bookshelfService.deletePublisher(publishers.get(0)); - assertEquals(TestConstants.PUBLISHER_COUNT, bookshelfService.findAllPublishers(null).size()); - } - - @Test - @Order(5) - void testFindAllAuthors() { - assertEquals(TestConstants.AUTHOR_COUNT, bookshelfService.findAllAuthors(null).size()); - } - - @Test - @Order(6) - void testSaveAuthor() { - Author author = new Author(); - author.setFirstName(TestConstants.AUTHOR_FIRSTNAME); - author.setLastName(TestConstants.AUTHOR_LASTNAME); - bookshelfService.saveAuthor(author); - assertEquals(TestConstants.AUTHOR_COUNT+1, bookshelfService.findAllAuthors(null).size()); - } - - @Test - @Order(7) - void testDeleteAuthor() { - List authors = bookshelfService.findAllAuthors(TestConstants.AUTHOR_FIRSTNAME); - assertEquals(1, authors.size()); - bookshelfService.deleteAuthor(authors.get(0)); - assertEquals(TestConstants.AUTHOR_COUNT, bookshelfService.findAllAuthors(null).size()); - } - - @Test - @Order(8) - void findAllBooks() { - assertEquals(TestConstants.BOOK_COUNT, bookshelfService.findAllBooks(null).size()); - } - - @Test - @Order(9) - void saveBook() { - assertEquals(TestConstants.BOOK_COUNT, bookshelfService.findAllBooks(null).size()); - } - - @Test - @Order(10) - void deleteBook() { - List books = bookshelfService.findAllBooks(null); - assertEquals(0, books.size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/ComicConstantsTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/ComicConstantsTest.java deleted file mode 100644 index b1e50ce..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/ComicConstantsTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.thpeetz.kontor.comics; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; - -class ComicConstantsTest { - - @Test - void getArtistConstants() { - assertEquals("Artist", ComicConstants.ARTIST); - assertEquals("comics/artist", ComicConstants.ARTIST_ROUTE); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/TestConstants.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/TestConstants.java deleted file mode 100644 index b77f55d..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/TestConstants.java +++ /dev/null @@ -1,67 +0,0 @@ -package de.thpeetz.kontor.comics; - -import de.thpeetz.kontor.comics.data.Artist; -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.Publisher; -import de.thpeetz.kontor.comics.data.Worktype; -import de.thpeetz.kontor.comics.services.ComicService; - -public class TestConstants { - public static final String ARTIST_NAME = "Lastname, Firstname"; - public static final String COMIC_TITLE = "TestComic"; - public static final String WORKTYPE_INKER = "Inker"; - public static final String ISSUE_ISSUENUMBER = "Issuenumber"; - public static final String PUBLISHER_NAME = "Publisher"; - public static final String SOJOURN_TPB_COMIC_TITLE = "Sojourn"; - public static final String SOJOURN_TPB_NAME = "The Dragons Tale"; - public static final String STORYARC_NAME = "StoryArc"; - public static final String TRADEPAPERBACK_NAME = "TradePaperback"; - public static final String VOLUME_NAME = "Volume"; - public static final String WORKTYPE_NAME = "Worktype"; - public static final int ARTIST_COUNT = 5; - public static final int BATTLE_POPE_ISSUE_COUNT = 12; - public static final int COMIC_COUNT = 169; - public static final int COMICWORK_COUNT = 18; - public static final int ISSUE_COUNT = 750; - public static final int MARVEL_COMIC_COUNT = 50; - public static final int PUBLISHER_COUNT = 18; - public static final int SOJOURN_TPB_COUNT = 4; - public static final int SOJOURN_TPB_START = 7; - public static final int SOJOURN_TPB_END = 12; - public static final int STORYARC_COUNT = 3; - public static final int TRADEPAPERBACK_COUNT = 40; - public static final int VOLUME_COUNT = 0; - public static final int WORKTYPE_COUNT = 3; - - public static Comic getComicWithStoryArcs(ComicService service) { - return service.findComicByTitle("Emma Frost"); - } - - public static Comic getComicWithTradePaperbacks(ComicService service) { - return service.findComicByTitle(SOJOURN_TPB_COMIC_TITLE); - } - - public static Comic getComicWithIssues(ComicService service) { - return service.findComicByTitle("Battle Pope"); - } - - public static Comic getComicWithoutReferences(ComicService service) { - return service.findComicByTitle("Gen13"); - } - - public static Artist getArtistWithoutReferences(ComicService service) { - return service.findArtistByName("Marz, Ron"); - } - - public static Worktype getWorktypeWithoutReferences(ComicService service) { - return service.findWorktypeByName(WORKTYPE_INKER); - } - - public static Publisher getPublisherForComicTests(ComicService service) { - return service.findPublisherByName("Marvel"); - } - - public static Publisher getAnotherPublisherForComicTests(ComicService service) { - return service.findPublisherByName("DC"); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/ArtistTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/ArtistTest.java deleted file mode 100644 index f12c679..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/ArtistTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.comics.repository.*; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.comics.TestConstants; - -@SpringBootTest -class ArtistTest { - - @Autowired - private ArtistRepository artistRepository; - - @Test - void checkInitialDataLoad() { - List artists = artistRepository.findAll(); - assertEquals(TestConstants.ARTIST_COUNT, artists.size()); - } - - @Test - void throwExceptionWhenArtistSavedWithEmptyName() { - Artist artist1 = new Artist(); - assertThrows(TransactionSystemException.class, () -> { - artistRepository.save(artist1); - }); - } - - @Test - void saveArtistWithIdenticalName() { - String artistName = "Lastname, Firstname"; - Artist artist1 = new Artist(); - artist1.setName(artistName); - artistRepository.save(artist1); - Artist artist2 = new Artist(); - artist2.setName(artistName); - assertThrows(DataIntegrityViolationException.class, () -> { - artistRepository.save(artist2); - }); - artistRepository.delete(artist1); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/ComicTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/ComicTest.java deleted file mode 100644 index cfc78ca..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/ComicTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.comics.repository.*; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.comics.TestConstants; -import de.thpeetz.kontor.comics.services.ComicService; - -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -class ComicTest { - - @Autowired - private ComicRepository comicRepository; - - @Autowired - private ComicService comicService; - - @Test - @Order(1) - void checkInitialDataLoad() { - List comics = comicRepository.findAll(); - assertEquals(TestConstants.COMIC_COUNT, comics.size()); - } - - @Test - @Order(2) - void exceptionThrownWhenSavingComicWithoutPublisher() { - Comic comic = new Comic(); - comic.setTitle(TestConstants.COMIC_TITLE); - assertThrows(TransactionSystemException.class, () -> { - comicRepository.save(comic); - }); - } - - @Test - @Order(3) - void exceptionThrownWhenSavingComicWithEmptyTitle() { - Comic comic = new Comic(); - Publisher publisher = TestConstants.getPublisherForComicTests(comicService); - comic.setPublisher(publisher); - assertNull(comic.getTitle()); - assertThrows(TransactionSystemException.class, () -> { - comicRepository.save(comic); - }); - comic.setTitle(""); - assertTrue(comic.getTitle().isEmpty()); - assertThrows(TransactionSystemException.class, () -> { - comicRepository.save(comic); - }); - } - - @Test - @Order(4) - void exceptionThrownWhenSavingComicWithSameNameFromDifferentPublishers() { - Publisher publisher = TestConstants.getPublisherForComicTests(comicService); - Comic comic = new Comic(); - comic.setTitle(TestConstants.SOJOURN_TPB_COMIC_TITLE); - comic.setPublisher(publisher); - assertThrows(DataIntegrityViolationException.class, () -> { - comicRepository.save(comic); - }); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/ComicWorkTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/ComicWorkTest.java deleted file mode 100644 index ac2eac2..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/ComicWorkTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.comics.services.ComicService; - -@SpringBootTest -public class ComicWorkTest { - - @Autowired - private ComicService comicService; - - @Test - void checkInitialDataLoad() { - List comicWorks = comicService.findAllComicWorks(); - assertEquals(18, comicWorks.size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/IssueTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/IssueTest.java deleted file mode 100644 index e600084..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/IssueTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.comics.repository.*; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.comics.TestConstants; -import de.thpeetz.kontor.comics.services.ComicService; - -@SpringBootTest -class IssueTest { - - @Autowired - private IssueRepository issueRepository; - - @Autowired - private ComicService comicService; - - @Test - void checkInitialDataLoad() { - List issues = comicService.findAllIssues(); - assertEquals(TestConstants.ISSUE_COUNT, issues.size()); - } - - @Test - void exceptionThrownWhenSavingIssueWithEmptyNumber() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - assertNotNull(comic); - Issue issue = new Issue(); - issue.setComic(comic); - assertThrows(TransactionSystemException.class, () -> { - issueRepository.save(issue); - }); - } - - @Test - void exceptionThrownWhenSavingStoryArcWithoutComic() { - Issue issue = new Issue(); - issue.setIssueNumber(TestConstants.ISSUE_ISSUENUMBER); - assertThrows(TransactionSystemException.class, () -> { - issueRepository.save(issue); - }); - } - - @Test - void saveStoryArc() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - assertEquals(0, comic.getStoryArcs().size()); - Issue issue = new Issue(); - issue.setComic(comic); - issue.setIssueNumber(TestConstants.ISSUE_ISSUENUMBER); - Issue savedInstance = issueRepository.save(issue); - assertNotNull(savedInstance); - comicService.deleteIssue(savedInstance); - assertEquals(0, comic.getStoryArcs().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/PublisherTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/PublisherTest.java deleted file mode 100644 index 028ef5a..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/PublisherTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import static org.junit.jupiter.api.Assertions.*; - -import de.thpeetz.kontor.comics.repository.*; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.comics.TestConstants; - -@SpringBootTest -class PublisherTest { - - @Autowired - private PublisherRepository publisherRepository; - - @Test - void checkInitialDataLoad() { - assertEquals(TestConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); - } - - @Test - void throwExceptionWhenPublisherSavedWithEmptyName() { - Publisher publisher = new Publisher(); - assertThrows(TransactionSystemException.class, () -> { - publisherRepository.save(publisher); - }); - } - - @Test - void savePublisherWithIdenticalName() { - Publisher publisher1 = new Publisher(); - publisher1.setName(TestConstants.PUBLISHER_NAME); - publisherRepository.save(publisher1); - Publisher publisher2 = new Publisher(); - publisher2.setName(TestConstants.PUBLISHER_NAME); - assertThrows(DataIntegrityViolationException.class, () -> { - publisherRepository.save(publisher2); - }); - publisherRepository.delete(publisher1); - assertEquals(TestConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/StoryArcTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/StoryArcTest.java deleted file mode 100644 index 1e0b598..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/StoryArcTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import static org.junit.jupiter.api.Assertions.*; - -import de.thpeetz.kontor.comics.repository.*; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.comics.TestConstants; -import de.thpeetz.kontor.comics.services.ComicService; - -@SpringBootTest -class StoryArcTest { - - @Autowired - private StoryArcRepository storyArcRepository; - - @Autowired - private ComicService comicService; - - @Test - void checkInitialLoad() { - assertEquals(TestConstants.STORYARC_COUNT, storyArcRepository.findAll().size()); - } - - @Test - void exceptionThrownWhenSavingStoryArcWithEmptyName() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - assertNotNull(comic); - StoryArc storyArc = new StoryArc(); - storyArc.setComic(comic); - assertThrows(TransactionSystemException.class, () -> { - storyArcRepository.save(storyArc); - }); - } - - @Test - void exceptionThrownWhenSavingStoryArcWithoutComic() { - StoryArc storyArc = new StoryArc(); - storyArc.setName(TestConstants.STORYARC_NAME); - assertThrows(TransactionSystemException.class, () -> { - storyArcRepository.save(storyArc); - }); - } - - @Test - void saveStoryArc() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - assertEquals(0, comic.getStoryArcs().size()); - StoryArc storyArc = new StoryArc(); - storyArc.setName(TestConstants.STORYARC_NAME); - storyArc.setComic(comic); - StoryArc savedInstance = storyArcRepository.save(storyArc); - assertNotNull(savedInstance); - comicService.deleteStoryArc(savedInstance); - assertEquals(0, comic.getStoryArcs().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/TradePaperbackTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/TradePaperbackTest.java deleted file mode 100644 index 0c0a11f..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/TradePaperbackTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import static org.junit.jupiter.api.Assertions.*; - -import de.thpeetz.kontor.comics.repository.*; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.comics.TestConstants; -import de.thpeetz.kontor.comics.services.ComicService; - -@SpringBootTest -class TradePaperbackTest { - - @Autowired - private TradePaperbackRepository tradePaperbackRepository; - - @Autowired - private ComicService comicService; - - @Test - void checkInitialDataLoad() { - assertEquals(TestConstants.TRADEPAPERBACK_COUNT, tradePaperbackRepository.findAll().size()); - } - - @Test - void exceptionThrownWhenSavingTradePaperbackWithEmptyName() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - assertNotNull(comic); - TradePaperback tradePaperback = new TradePaperback(); - tradePaperback.setComic(comic); - assertThrows(TransactionSystemException.class, () -> { - tradePaperbackRepository.save(tradePaperback); - }); - } - - @Test - void exceptionThrownWhenSavingTradePaperbackWithoutComic() { - TradePaperback tradePaperback = new TradePaperback(); - tradePaperback.setName(TestConstants.TRADEPAPERBACK_NAME); - assertThrows(TransactionSystemException.class, () -> { - tradePaperbackRepository.save(tradePaperback); - }); - } - - @Test - void saveTradePaperback() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - assertEquals(0, comic.getTradePaperbacks().size()); - TradePaperback tradePaperback = new TradePaperback(); - tradePaperback.setName(TestConstants.TRADEPAPERBACK_NAME); - tradePaperback.setComic(comic); - TradePaperback savedInstance = tradePaperbackRepository.save(tradePaperback); - assertNotNull(savedInstance); - comicService.deleteTradePaperBack(savedInstance); - assertEquals(0, comic.getTradePaperbacks().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/VolumeTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/VolumeTest.java deleted file mode 100644 index 399d094..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/VolumeTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import static org.junit.jupiter.api.Assertions.*; - -import de.thpeetz.kontor.comics.repository.*; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.comics.TestConstants; -import de.thpeetz.kontor.comics.services.ComicService; - -@SpringBootTest -class VolumeTest { - - @Autowired - private VolumeRepository volumeRepository; - - @Autowired - private ComicRepository comicRepository; - - @Autowired - private ComicService comicService; - - @Test - void checkInitialDataLoad() { - assertEquals(TestConstants.VOLUME_COUNT, volumeRepository.count()); - } - - @Test - void exceptionThrownWhenSavingVolumeWithEmptyName() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - Volume volume = new Volume(); - volume.setComic(comic); - assertThrows(TransactionSystemException.class, () -> { - volumeRepository.save(volume); - }); - } - - @Test - void exceptionThrownWhenSavingVolumeWithoutComic() { - Volume volume = new Volume(); - volume.setName(TestConstants.VOLUME_NAME); - assertThrows(TransactionSystemException.class, () -> { - volumeRepository.save(volume); - }); - } - - @Test - void saveVolume() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - assertEquals(0, comic.getVolumes().size()); - Volume volume = new Volume(); - volume.setName(TestConstants.VOLUME_NAME); - volume.setComic(comic); - Volume savedInstance = volumeRepository.save(volume); - assertNotNull(savedInstance); - comicService.deleteVolume(savedInstance); - assertEquals(0, comic.getVolumes().size()); - assertEquals(TestConstants.VOLUME_COUNT, volumeRepository.count()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/WorktypeTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/WorktypeTest.java deleted file mode 100644 index 050bde9..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/data/WorktypeTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package de.thpeetz.kontor.comics.data; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.comics.repository.*; -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.comics.TestConstants; - -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -class WorktypeTest { - - @Autowired - private WorktypeRepository worktypeRepository; - - @Test - @Order(1) - void checkInitialDataLoad() { - List worktypes = worktypeRepository.findAll(); - assertEquals(3, worktypes.size()); - } - - @Test - @Order(2) - void findWorktypeByName() { - Worktype found = worktypeRepository.findByName(TestConstants.WORKTYPE_INKER); - assertNotNull(found); - assertEquals(TestConstants.WORKTYPE_INKER, found.getName()); - Worktype notFound = worktypeRepository.findByName("er"); - assertNull(notFound); - } - - @Test - @Order(3) - void throwExceptionWhenArtistSavedWithEmptyName() { - Worktype worktype1 = new Worktype(); - assertThrows(TransactionSystemException.class, () -> { - worktypeRepository.save(worktype1); - }); - } - - @Test - @Order(4) - void saveWorktypeWithIdenticalName() { - Worktype worktype1 = new Worktype(); - worktype1.setName(TestConstants.WORKTYPE_NAME); - worktypeRepository.save(worktype1); - Worktype worktype2 = new Worktype(); - worktype2.setName(TestConstants.WORKTYPE_NAME); - assertThrows(DataIntegrityViolationException.class, () -> { - worktypeRepository.save(worktype2); - }); - worktypeRepository.delete(worktype1); - } - - @Test - @Order(5) - void saveWorktype() { - Worktype worktype = new Worktype(); - worktype.setName(TestConstants.WORKTYPE_NAME); - worktypeRepository.save(worktype); - assertEquals(TestConstants.WORKTYPE_COUNT + 1, worktypeRepository.count()); - } - - @Test - @Order(6) - void deleteWorktype() { - Worktype worktype = worktypeRepository.findByName(TestConstants.WORKTYPE_NAME); - assertNotNull(worktype); - worktypeRepository.delete(worktype); - assertEquals(TestConstants.WORKTYPE_COUNT, worktypeRepository.count()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/ArtistRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/ArtistRepositoryTest.java deleted file mode 100644 index 2a3f9e0..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/ArtistRepositoryTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -class ArtistRepositoryTest { - - private Artist stanLee; - private static final String ARTISTNAME = "Lee, Stan"; - - @Autowired - ArtistRepository artistRepository; - - @BeforeEach - void setupData() { - stanLee = new Artist(); - stanLee.setName(ARTISTNAME); - } - - @Test - @Order(1) - void checkInitialLoad() { - int count = artistRepository.findAll().size(); - assertEquals(5, count); - } - - @Test - @Order(2) - void saveArtist() { - int count = artistRepository.findAll().size(); - artistRepository.save(stanLee); - assertEquals(count+1, artistRepository.findAll().size()); - } - - @Test - @Order(3) - void findArtist() { - List artists = artistRepository.findByNameIgnoreCase("lEE, sTAN"); - assertTrue(artists.size() > 0); - assertEquals(artists.get(0).getName(), stanLee.getName()); - } - - @Test - @Order(4) - void searchArtist() { - List artists = artistRepository.search("Lee"); - assertEquals(1, artists.size()); - assertEquals(ARTISTNAME, artists.get(0).getName()); - List artists2 = artistRepository.search("Stan"); - assertEquals(1, artists2.size()); - assertEquals(ARTISTNAME, artists2.get(0).getName()); - } - - @Test - @Order(5) - void deleteArtist() { - int count = artistRepository.findAll().size(); - Artist artist = artistRepository.findByName(ARTISTNAME); - artistRepository.delete(artist); - assertEquals(count-1, artistRepository.findAll().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/ComicRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/ComicRepositoryTest.java deleted file mode 100644 index 9f54868..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/ComicRepositoryTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; -import java.util.stream.Collectors; - -import de.thpeetz.kontor.comics.data.*; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class ComicRepositoryTest { - - @Autowired - private ComicRepository comicRepository; - - @Autowired - private PublisherRepository publisherRepository; - - @Test - void testFindByTitle() { - List comics = comicRepository.findByTitle("Emma Frost"); - assertEquals(1, comics.size()); - assertEquals("Emma Frost", comics.get(0).getTitle()); - Publisher publisher = comics.get(0).getPublisher(); - assertEquals("Marvel", publisher.getName()); - } - - @Test - void testFindByTitleIgnoreCase() { - List comics = comicRepository.findByTitleIgnoreCase("x-men"); - assertEquals(1, comics.size()); - assertEquals("X-Men", comics.get(0).getTitle()); - } - @Test - void testFindByTitleAndPublisher() { - Publisher publisher = publisherRepository.findByName("Marvel"); - assertNotNull(publisher); - Comic found = comicRepository.findByTitleAndPublisher("Emma Frost", publisher); - assertNotNull(found); - assertEquals("Emma Frost", found.getTitle()); - assertEquals("Marvel", found.getPublisher().getName()); - - } - - @Test - void testSearch() { - List comics = comicRepository.search("X-men"); - assertEquals(11, comics.size()); - assertTrue(comics.stream().map(comic -> comic.getTitle()).collect(Collectors.toList()).contains("Astonishing X-Men")); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/ComicWorkRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/ComicWorkRepositoryTest.java deleted file mode 100644 index a640057..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/ComicWorkRepositoryTest.java +++ /dev/null @@ -1,84 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import static org.junit.jupiter.api.Assertions.*; - -import de.thpeetz.kontor.comics.data.*; -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.comics.services.ComicService; - -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -class ComicWorkRepositoryTest { - - @Autowired - private ComicWorkRepository comicWorkRepository; - - @Autowired - private ComicRepository comicRepository; - - @Autowired - private WorktypeRepository worktypeRepository; - - @Autowired - private ArtistRepository artistRepository; - - @Autowired - private ComicService comicService; - - @Test - @Order(1) - void checkInitialLoad() { - int count = comicWorkRepository.findAll().size(); - assertEquals(18, count); - } - - @Test - @Order(2) - void saveComicWork() { - int count = comicWorkRepository.findAll().size(); - Artist artist = artistRepository.findByName("Turner, Michael"); - Worktype worktype = worktypeRepository.findByName("Writer"); - Comic comic = comicRepository.findByTitle("Emma Frost").get(0); - ComicWork comicWork = new ComicWork(); - comicWork.setArtist(artist); - comicWork.setComic(comic); - comicWork.setWorkType(worktype); - comicWorkRepository.save(comicWork); - assertEquals(count + 1, comicWorkRepository.findAll().size()); - } - - @Test - @Order(3) - void findByComicAndArtistAndComicWork() { - assertEquals(19, comicWorkRepository.count()); - Artist artist = artistRepository.findByName("Turner, Michael"); - Worktype worktype = worktypeRepository.findByName("Writer"); - Comic comic = comicRepository.findByTitle("Emma Frost").get(0); - ComicWork comicWork = comicWorkRepository.findbyComicAndArtistAndWorktype(comic, artist, worktype); - assertNotNull(comicWork); - assertEquals(comicWork.getArtist().getName(), artist.getName()); - assertEquals(comicWork.getComic().getTitle(), comic.getTitle()); - assertEquals(comicWork.getWorkType().getName(), worktype.getName()); - ComicWork notFound = comicWorkRepository.findbyComicAndArtistAndWorktype(comic, artist, null); - assertNull(notFound); - } - - @Test - @Order(4) - void deleteComicWork() { - long count = comicWorkRepository.count(); - Artist artist = artistRepository.findByName("Turner, Michael"); - Worktype worktype = worktypeRepository.findByName("Writer"); - Comic comic = comicRepository.findByTitle("Emma Frost").get(0); - ComicWork comicWork = comicWorkRepository.findbyComicAndArtistAndWorktype(comic, artist, worktype); - assertNotNull(comicWork); - comicService.deleteComicWork(comicWork); - assertEquals(count - 1, comicWorkRepository.count()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/IssueRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/IssueRepositoryTest.java deleted file mode 100644 index 8235b34..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/IssueRepositoryTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.comics.TestConstants; -import de.thpeetz.kontor.comics.services.ComicService; - -@SpringBootTest -class IssueRepositoryTest { - - @Autowired - private IssueRepository issueRepository; - - @Autowired - private ComicService comicService; - - @Test - void testFindByComic() { - Comic comic = TestConstants.getComicWithIssues(comicService); - List issues = issueRepository.findByComic(comic); - assertEquals(TestConstants.BATTLE_POPE_ISSUE_COUNT, issues.size()); - } - - @Test - void testFindByComicAndIssueNumber() { - Comic comic = TestConstants.getComicWithIssues(comicService); - Issue issue = issueRepository.findByComicAndIssueNumber(comic, "12"); - assertNotNull(issue); - assertFalse(issue.getIsRead()); - } - - @Test - void testSearch() { - List issues = issueRepository.search("2"); - assertEquals(187, issues.size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/PublisherRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/PublisherRepositoryTest.java deleted file mode 100644 index 01dcc8e..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/PublisherRepositoryTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.comics.TestConstants; - -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -class PublisherRepositoryTest { - - @Autowired - private PublisherRepository publisherRepository; - - @Test - @Order(1) - void checkInitialLoad() { - assertEquals(TestConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); - } - - @Test - @Order(2) - void savePublisher() { - Publisher publisher = new Publisher(); - publisher.setName(TestConstants.PUBLISHER_NAME); - publisherRepository.save(publisher); - assertEquals(TestConstants.PUBLISHER_COUNT + 1, publisherRepository.findAll().size()); - } - - @Test - @Order(3) - void findPublisherByName() { - Publisher publisher = publisherRepository.findByName(TestConstants.PUBLISHER_NAME); - assertNotNull(publisher); - assertEquals(TestConstants.PUBLISHER_NAME, publisher.getName()); - Publisher notFound = publisherRepository.findByName("Cow"); - assertNull(notFound); - List publishers = publisherRepository - .findByNameIgnoreCase(TestConstants.PUBLISHER_NAME.toLowerCase()); - assertEquals(1, publishers.size()); - assertEquals(TestConstants.PUBLISHER_NAME, publishers.get(0).getName()); - } - - @Test - @Order(4) - void searchPublisher() { - List publishers = publisherRepository.search("Cow"); - assertEquals(1, publishers.size()); - assertEquals("Top Cow Productions", publishers.get(0).getName()); - } - - @Test - @Order(5) - void deletePublisher() { - Publisher publisher = publisherRepository.findByName(TestConstants.PUBLISHER_NAME); - assertNotNull(publisher); - publisherRepository.delete(publisher); - assertEquals(TestConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/StoryArcRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/StoryArcRepositoryTest.java deleted file mode 100644 index 367faba..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/StoryArcRepositoryTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.comics.TestConstants; -import de.thpeetz.kontor.comics.services.ComicService; - -@SpringBootTest -class StoryArcRepositoryTest { - - @Autowired - private StoryArcRepository storyArcRepository; - - @Autowired - private ComicService comicService; - - @Test - void testSearch() { - List storyArcs = storyArcRepository.search("Learn"); - assertNotNull(storyArcs); - assertEquals(1, storyArcs.size()); - } - - @Test - void findByComic() { - Comic comic = TestConstants.getComicWithStoryArcs(comicService); - List storyArcs = storyArcRepository.findByComic(comic); - assertNotNull(storyArcs); - assertEquals(3, storyArcs.size()); - } - - @Test - void findByNameAndComic() { - Comic comic = TestConstants.getComicWithStoryArcs(comicService); - StoryArc storyArc = storyArcRepository.findByNameAndComic("Higher Learning", comic); - assertNotNull(storyArc); - assertEquals("Emma Frost", storyArc.getComic().getTitle()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/TradePaperbackRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/TradePaperbackRepositoryTest.java deleted file mode 100644 index 4f9dade..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/TradePaperbackRepositoryTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.comics.TestConstants; -import de.thpeetz.kontor.comics.services.ComicService; - -@SpringBootTest -class TradePaperbackRepositoryTest { - - @Autowired - private TradePaperbackRepository tradePaperbackRepository; - - @Autowired - private ComicService comicService; - - @Test - void testSearch() { - List tradePaperbacks = tradePaperbackRepository.search("Dragon"); - assertNotNull(tradePaperbacks); - assertEquals(1, tradePaperbacks.size()); - } - - @Test - void testFindByComic() { - Comic comic = TestConstants.getComicWithTradePaperbacks(comicService); - List tradePaperbacks = tradePaperbackRepository.findByComic(comic); - assertNotNull(tradePaperbacks); - assertEquals(TestConstants.SOJOURN_TPB_COUNT, tradePaperbacks.size()); - } - - @Test - void testFindByNameAndComic() { - Comic comic = TestConstants.getComicWithTradePaperbacks(comicService); - List tradePaperbacks = tradePaperbackRepository - .findByNameAndComic(TestConstants.SOJOURN_TPB_NAME, comic); - assertNotNull(tradePaperbacks); - assertTrue(tradePaperbacks.size() > 0); - assertEquals(TestConstants.SOJOURN_TPB_COMIC_TITLE, tradePaperbacks.get(0).getComic().getTitle()); - } - - @Test - void testFindByFields() { - Comic comic = TestConstants.getComicWithTradePaperbacks(comicService); - TradePaperback tradePaperback = tradePaperbackRepository.findByFields(TestConstants.SOJOURN_TPB_NAME, - comic, TestConstants.SOJOURN_TPB_START, TestConstants.SOJOURN_TPB_END); - assertNotNull(tradePaperback); - assertEquals(TestConstants.SOJOURN_TPB_COMIC_TITLE, tradePaperback.getComic().getTitle()); - assertEquals(TestConstants.SOJOURN_TPB_END, tradePaperback.getIssueEnd()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/VolumeRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/VolumeRepositoryTest.java deleted file mode 100644 index 33a699a..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/VolumeRepositoryTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.comics.data.*; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.comics.TestConstants; -import de.thpeetz.kontor.comics.services.ComicService; - -@SpringBootTest -class VolumeRepositoryTest { - - @Autowired - private VolumeRepository volumeRepository; - - @Autowired - private ComicRepository comicRepository; - - @Autowired - private ComicService comicService; - - @Test - void testFindByComic() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - assertEquals(0, comic.getVolumes().size()); - Volume volume = new Volume(); - volume.setName(TestConstants.VOLUME_NAME); - volume.setComic(comic); - Volume savedInstance = volumeRepository.save(volume); - assertNotNull(savedInstance); - - List found = volumeRepository.findByComic(comic); - assertEquals(1, found.size()); - - comicService.deleteVolume(found.get(0)); - assertEquals(0, comic.getVolumes().size()); - assertEquals(TestConstants.VOLUME_COUNT, volumeRepository.count()); - } - - @Test - void testFindByName() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - assertEquals(0, comic.getVolumes().size()); - Volume volume = new Volume(); - volume.setName(TestConstants.VOLUME_NAME); - volume.setComic(comic); - Volume savedInstance = volumeRepository.save(volume); - assertNotNull(savedInstance); - - List found = volumeRepository.findByName(TestConstants.VOLUME_NAME); - assertEquals(1, found.size()); - - comicService.deleteVolume(found.get(0)); - assertEquals(0, comic.getVolumes().size()); - assertEquals(TestConstants.VOLUME_COUNT, volumeRepository.count()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/WorktypeRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/WorktypeRepositoryTest.java deleted file mode 100644 index d9b641e..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/repository/WorktypeRepositoryTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.thpeetz.kontor.comics.repository; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; -import java.util.stream.Collectors; - -import de.thpeetz.kontor.comics.data.*; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class WorktypeRepositoryTest { - - @Autowired - private WorktypeRepository worktypeRepository; - - @Test - void findWorktypeByName() { - Worktype found = worktypeRepository.findByName("Writer"); - assertNotNull(found); - Worktype notFound = worktypeRepository.findByName("er"); - assertNull(notFound); - } - - @Test - void findWorktypeByNameIgnoreCase() { - List worktypes = worktypeRepository.findByNameIgnoreCase("Writer".toLowerCase()); - assertNotNull(worktypes); - assertEquals(1, worktypes.size()); - assertEquals("Writer", worktypes.get(0).getName()); - } - - @Test - void searchWorktype() { - List worktypes = worktypeRepository.search("er"); - assertEquals(3, worktypes.size()); - assertTrue(worktypes.stream().map(worktype -> worktype.getName()).collect(Collectors.toList()).contains("Writer")); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/services/ComicServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/comics/services/ComicServiceTest.java deleted file mode 100644 index d449298..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/comics/services/ComicServiceTest.java +++ /dev/null @@ -1,350 +0,0 @@ -package de.thpeetz.kontor.comics.services; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.comics.TestConstants; -import de.thpeetz.kontor.comics.data.Artist; -import de.thpeetz.kontor.comics.data.Comic; -import de.thpeetz.kontor.comics.data.ComicWork; -import de.thpeetz.kontor.comics.data.Issue; -import de.thpeetz.kontor.comics.data.Publisher; -import de.thpeetz.kontor.comics.data.StoryArc; -import de.thpeetz.kontor.comics.data.TradePaperback; -import de.thpeetz.kontor.comics.data.Volume; -import de.thpeetz.kontor.comics.data.Worktype; - -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -class ComicServiceTest { - - private static final Logger log = LoggerFactory.getLogger(ComicServiceTest.class); - @Autowired - private ComicService comicService; - - @Test - @Order(1) - void testFindAllArtists() { - assertEquals(TestConstants.ARTIST_COUNT, comicService.findAllArtists(null).size()); - assertEquals(1, comicService.findAllArtists("Turn").size()); - } - - @Test - @Order(1) - void testFindArtistByName() { - assertNull(comicService.findArtistByName("Lee, Stan")); - Artist artist = comicService.findArtistByName("Turner, Michael"); - assertNotNull(artist); - assertNotNull(artist.getComicWorks()); - assertFalse(artist.getComicWorks().isEmpty()); - } - - @Test - @Order(2) - void testSaveArtist() { - Artist artist = new Artist(); - artist.setName(TestConstants.ARTIST_NAME); - comicService.saveArtist(artist); - assertEquals(TestConstants.ARTIST_COUNT + 1, comicService.findAllArtists(null).size()); - } - - @Test - @Order(3) - void testDeleteArtist() { - List artists = comicService.findAllArtists(TestConstants.ARTIST_NAME); - assertEquals(1, artists.size()); - comicService.deleteArtist(artists.get(0)); - assertEquals(TestConstants.ARTIST_COUNT, comicService.findAllArtists(null).size()); - } - - @Test - @Order(4) - void testFindAllPublishers() { - assertEquals(TestConstants.PUBLISHER_COUNT, comicService.findAllPublishers(null).size()); - assertEquals(1, comicService.findAllPublishers("Cow").size()); - } - - @Test - @Order(4) - void testFindPublisherByName() { - Publisher publisher = comicService.findPublisherByName("Marvel"); - assertNotNull(publisher); - assertNotNull(publisher.getComics()); - assertEquals(TestConstants.MARVEL_COMIC_COUNT, publisher.getComics().size()); - assertNull(comicService.findPublisherByName(TestConstants.PUBLISHER_NAME)); - } - - @Test - @Order(5) - void testSavePublisher() { - Publisher publisher = new Publisher(); - publisher.setName(TestConstants.PUBLISHER_NAME); - comicService.savePublisher(publisher); - assertEquals(TestConstants.PUBLISHER_COUNT + 1, comicService.findAllPublishers(null).size()); - } - - @Test - @Order(6) - void testDeletePublisher() { - List publishers = comicService.findAllPublishers(TestConstants.PUBLISHER_NAME); - assertEquals(1, publishers.size()); - comicService.deletePublisher(publishers.get(0)); - assertEquals(TestConstants.PUBLISHER_COUNT, comicService.findAllPublishers(null).size()); - } - - @Test - @Order(7) - void testFindAllWorktypes() { - assertEquals(TestConstants.WORKTYPE_COUNT, comicService.findAllWorktypes(null).size()); - assertEquals(1, comicService.findAllWorktypes("ite").size()); - } - - @Test - @Order(7) - void testFindWorktypeByName() { - Worktype worktype = comicService.findWorktypeByName("Writer"); - assertNotNull(worktype); - assertNotNull(worktype.getComicWorks()); - assertFalse(worktype.getComicWorks().isEmpty()); - worktype = comicService.findWorktypeByName("Inker"); - assertNotNull(worktype); - assertNotNull(worktype.getComicWorks()); - assertTrue(worktype.getComicWorks().isEmpty()); - assertNull(comicService.findWorktypeByName(TestConstants.WORKTYPE_NAME)); - } - - @Test - @Order(8) - void testSaveWorktype() { - Worktype worktype = new Worktype(); - worktype.setName(TestConstants.WORKTYPE_NAME); - comicService.saveWorktype(worktype); - assertEquals(TestConstants.WORKTYPE_COUNT + 1, comicService.findAllWorktypes(null).size()); - } - - @Test - @Order(9) - void testDeleteWorktype() { - List worktypes = comicService.findAllWorktypes(TestConstants.WORKTYPE_NAME); - assertEquals(1, worktypes.size()); - comicService.deleteWorktype(worktypes.get(0)); - assertEquals(TestConstants.WORKTYPE_COUNT, comicService.findAllWorktypes(null).size()); - } - - @Test - @Order(10) - void testFindComicByTitle() { - assertNull(comicService.findComicByTitle(null)); - assertNotNull(comicService.findComicByTitle("Danger Girl")); - assertNull(comicService.findComicByTitle("x-men")); - } - - @Test - @Order(11) - void testSaveComic() { - Publisher marvel = comicService.findAllPublishers("Marvel").get(0); - Comic comic = new Comic(); - comic.setTitle(TestConstants.COMIC_TITLE); - comic.setPublisher(marvel); - comicService.saveComic(comic); - assertEquals(TestConstants.COMIC_COUNT + 1, comicService.findAllComics(null).size()); - } - - @Test - @Order(12) - void testDeleteComic() { - assertEquals(TestConstants.COMIC_COUNT + 1, comicService.findAllComics(null).size()); - List comics = comicService.findAllComics(TestConstants.COMIC_TITLE); - assertEquals(1, comics.size()); - Comic comic = comicService.findComicByTitle(TestConstants.COMIC_TITLE); - assertNotNull(comic); - comicService.deleteComic(comic); - Publisher marvel = comicService.findPublisherByName("Marvel"); - assertNotNull(marvel.getComics()); - assertEquals(TestConstants.MARVEL_COMIC_COUNT, marvel.getComics().size()); - assertEquals(0, comicService.findAllComics(TestConstants.COMIC_TITLE).size()); - assertEquals(TestConstants.COMIC_COUNT, comicService.findAllComics(null).size()); - } - - @Test - @Order(13) - void testFindAllIssues() { - assertEquals(TestConstants.ISSUE_COUNT, comicService.findAllIssues().size()); - } - - @Test - @Order(14) - void testFindAllIssuesForComic() { - Comic comic = TestConstants.getComicWithIssues(comicService); - List issues = comicService.findAllIssuesForComic(comic); - assertEquals(12, issues.size()); - } - - @Test - @Order(15) - void testSaveIssue() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - Issue issue = new Issue(); - issue.setComic(comic); - issue.setIssueNumber(TestConstants.ISSUE_ISSUENUMBER); - comicService.saveIssue(issue); - assertEquals(TestConstants.ISSUE_COUNT + 1, comicService.findAllIssues().size()); - comic = TestConstants.getComicWithoutReferences(comicService); - assertNotNull(comic.getIssues()); - assertEquals(1, comic.getIssues().size()); - } - - @Test - @Order(16) - void testDeleteIssue() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - List issues = comicService.findAllIssuesForComic(comic); - assertEquals(1, issues.size()); - comicService.deleteIssue(issues.get(0)); - assertEquals(TestConstants.ISSUE_COUNT, comicService.findAllIssues().size()); - } - - @Test - @Order(17) - void testFindAllTradePaperbacks() { - assertEquals(TestConstants.TRADEPAPERBACK_COUNT, comicService.findAllTradePaperbacks(null).size()); - assertEquals(7, comicService.findAllTradePaperbacks("of").size()); - } - - @Test - @Order(18) - void testSaveTradePaperBack() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - TradePaperback tradePaperback = new TradePaperback(); - tradePaperback.setComic(comic); - tradePaperback.setName(TestConstants.TRADEPAPERBACK_NAME); - comicService.saveTradePaperBack(tradePaperback); - assertEquals(TestConstants.TRADEPAPERBACK_COUNT + 1, comicService.findAllTradePaperbacks(null).size()); - } - - @Test - @Order(19) - void testDeleteTradePaperBack() { - List tradePaperbacks = comicService.findAllTradePaperbacks(TestConstants.TRADEPAPERBACK_NAME); - assertEquals(1, tradePaperbacks.size()); - comicService.deleteTradePaperBack(tradePaperbacks.get(0)); - assertEquals(TestConstants.TRADEPAPERBACK_COUNT, comicService.findAllTradePaperbacks(null).size()); - } - - @Test - @Order(20) - void testFindAllStoryArcs() { - assertEquals(TestConstants.STORYARC_COUNT, comicService.findAllStoryArcs().size()); - } - - @Test - @Order(21) - void testFindAllStoryArcsForComic() { - assertEquals(TestConstants.STORYARC_COUNT, comicService.findAllStoryArcsForComic(null).size()); - Comic comic = TestConstants.getComicWithStoryArcs(comicService); - assertEquals(3, comicService.findAllStoryArcsForComic(comic).size()); - } - - @Test - @Order(22) - void testSaveStoryArc() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - StoryArc storyArc = new StoryArc(); - storyArc.setName(TestConstants.STORYARC_NAME); - storyArc.setComic(comic); - comicService.saveStoryArc(storyArc); - assertEquals(TestConstants.STORYARC_COUNT + 1, comicService.findAllStoryArcs().size()); - } - - @Test - @Order(23) - void testDeleteStoryArc() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - List storyArcs = comicService.findAllStoryArcsForComic(comic); - assertEquals(1, storyArcs.size()); - comicService.deleteStoryArc(storyArcs.get(0)); - assertEquals(TestConstants.STORYARC_COUNT, comicService.findAllStoryArcs().size()); - } - - @Test - @Order(24) - void testFindAllVolumes() { - assertEquals(TestConstants.VOLUME_COUNT, comicService.findAllVolumes().size()); - } - - @Test - @Order(25) - void testSaveVolume() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - Volume volume = new Volume(); - volume.setName(TestConstants.VOLUME_NAME); - volume.setComic(comic); - comicService.saveVolume(volume); - assertEquals(TestConstants.VOLUME_COUNT + 1, comicService.findAllVolumes().size()); - } - - @Test - @Order(26) - void testFindAllVolumesForComic() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - List volumes = comicService.findAllVolumesForComic(comic); - assertEquals(1, volumes.size()); - } - - @Test - @Order(27) - void testDeleteVolume() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - List volumes = comicService.findAllVolumesForComic(comic); - comicService.deleteVolume(volumes.get(0)); - assertEquals(TestConstants.VOLUME_COUNT, comicService.findAllVolumes().size()); - } - - @Test - @Order(28) - void testFindAllComicWorks() { - assertEquals(TestConstants.COMICWORK_COUNT, comicService.findAllComicWorks().size()); - } - - @Test - @Order(29) - void testSaveComicWork() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - Artist artist = TestConstants.getArtistWithoutReferences(comicService); - Worktype worktype = TestConstants.getWorktypeWithoutReferences(comicService); - ComicWork comicWork = new ComicWork(); - comicWork.setComic(comic); - comicWork.setArtist(artist); - comicWork.setWorkType(worktype); - comicService.saveComicWork(comicWork); - assertEquals(TestConstants.COMICWORK_COUNT + 1, comicService.findAllComicWorks().size()); - } - - @Test - @Order(30) - void testDeleteComicWork() { - Comic comic = TestConstants.getComicWithoutReferences(comicService); - Artist artist = TestConstants.getArtistWithoutReferences(comicService); - Worktype worktype = TestConstants.getWorktypeWithoutReferences(comicService); - List comicWorks = comic.getComicWorks(); - assertNotNull(comicWorks); - assertNotNull(artist.getComicWorks()); - assertNotNull(worktype.getComicWorks()); - assertEquals(1, comicWorks.size()); - assertEquals(1, artist.getComicWorks().size()); - assertEquals(1, worktype.getComicWorks().size()); - ComicWork comicWork = comicWorks.get(0); - comicService.deleteComicWork(comicWork); - assertEquals(TestConstants.COMICWORK_COUNT, comicService.findAllComicWorks().size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/constants/ComicConstantsTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/constants/ComicConstantsTest.java new file mode 100644 index 0000000..8e96abe --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/constants/ComicConstantsTest.java @@ -0,0 +1,14 @@ +package de.thpeetz.kontor.constants; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class ComicConstantsTest { + + @Test + void getArtistConstants() { + assertEquals("Artist", ComicConstants.ARTIST); + assertEquals("comics/artist", ComicConstants.ARTIST_ROUTE); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/constants/TestBookshelfConstants.java b/kontor-spring/src/test/java/de/thpeetz/kontor/constants/TestBookshelfConstants.java new file mode 100644 index 0000000..ecbc333 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/constants/TestBookshelfConstants.java @@ -0,0 +1,19 @@ +package de.thpeetz.kontor.constants; + +public class TestBookshelfConstants { + + public static final Integer ARTICLEAUTHOR_COUNT = 0; + public static final Integer ARTICLE_COUNT = 0; + public static final Integer AUTHOR_COUNT = 1; + public static final Integer BOOKAUTHOR_COUNT = 0; + public static final Integer BOOK_COUNT = 0; + public static final Integer PUBLISHER_COUNT = 0; + public static final String ARTICLE_TITLE = "Title"; + public static final String AUTHOR_FIRSTNAME = "Firstname"; + public static final String AUTHOR_LASTNAME = "Lastname"; + public static final String PUBLISHER_NIKOL = "Nikol Verlags GmbH"; + public static final String PUBLISHER_NAME = "Publisher"; + public static final String PUBLISHER_SEARCH = "kol"; + public static final String BOOK_TITLE = "Book Title"; + public static final String BOOK_ISBN = "978-3-123-467-890"; +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/constants/TestComicConstants.java b/kontor-spring/src/test/java/de/thpeetz/kontor/constants/TestComicConstants.java new file mode 100644 index 0000000..9348d32 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/constants/TestComicConstants.java @@ -0,0 +1,67 @@ +package de.thpeetz.kontor.constants; + +import de.thpeetz.kontor.data.comics.Artist; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.Publisher; +import de.thpeetz.kontor.data.comics.Worktype; +import de.thpeetz.kontor.services.ComicService; + +public class TestComicConstants { + public static final String ARTIST_NAME = "Lastname, Firstname"; + public static final String COMIC_TITLE = "TestComic"; + public static final String WORKTYPE_INKER = "Inker"; + public static final String ISSUE_ISSUENUMBER = "Issuenumber"; + public static final String PUBLISHER_NAME = "Publisher"; + public static final String SOJOURN_TPB_COMIC_TITLE = "Sojourn"; + public static final String SOJOURN_TPB_NAME = "The Dragons Tale"; + public static final String STORYARC_NAME = "StoryArc"; + public static final String TRADEPAPERBACK_NAME = "TradePaperback"; + public static final String VOLUME_NAME = "Volume"; + public static final String WORKTYPE_NAME = "Worktype"; + public static final int ARTIST_COUNT = 5; + public static final int BATTLE_POPE_ISSUE_COUNT = 12; + public static final int COMIC_COUNT = 169; + public static final int COMICWORK_COUNT = 18; + public static final int ISSUE_COUNT = 750; + public static final int MARVEL_COMIC_COUNT = 50; + public static final int PUBLISHER_COUNT = 18; + public static final int SOJOURN_TPB_COUNT = 4; + public static final int SOJOURN_TPB_START = 7; + public static final int SOJOURN_TPB_END = 12; + public static final int STORYARC_COUNT = 3; + public static final int TRADEPAPERBACK_COUNT = 40; + public static final int VOLUME_COUNT = 0; + public static final int WORKTYPE_COUNT = 3; + + public static Comic getComicWithStoryArcs(ComicService service) { + return service.findComicByTitle("Emma Frost"); + } + + public static Comic getComicWithTradePaperbacks(ComicService service) { + return service.findComicByTitle(SOJOURN_TPB_COMIC_TITLE); + } + + public static Comic getComicWithIssues(ComicService service) { + return service.findComicByTitle("Battle Pope"); + } + + public static Comic getComicWithoutReferences(ComicService service) { + return service.findComicByTitle("Gen13"); + } + + public static Artist getArtistWithoutReferences(ComicService service) { + return service.findArtistByName("Marz, Ron"); + } + + public static Worktype getWorktypeWithoutReferences(ComicService service) { + return service.findWorktypeByName(WORKTYPE_INKER); + } + + public static Publisher getPublisherForComicTests(ComicService service) { + return service.findPublisherByName("Marvel"); + } + + public static Publisher getAnotherPublisherForComicTests(ComicService service) { + return service.findPublisherByName("DC"); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/constants/TestMediaConstants.java b/kontor-spring/src/test/java/de/thpeetz/kontor/constants/TestMediaConstants.java new file mode 100644 index 0000000..a8d432e --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/constants/TestMediaConstants.java @@ -0,0 +1,5 @@ +package de.thpeetz.kontor.constants; + +public class TestMediaConstants { + public static final String URL = "https://example.com/link.mp4"; +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/constants/TestTyscConstants.java b/kontor-spring/src/test/java/de/thpeetz/kontor/constants/TestTyscConstants.java new file mode 100644 index 0000000..7477274 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/constants/TestTyscConstants.java @@ -0,0 +1,39 @@ +package de.thpeetz.kontor.constants; + +public class TestTyscConstants { + + public static final Integer CARD_COUNT = 10; + public static final Integer CARD_CARDNUMBER = 999; + public static final Integer CARD_YEAR = 2000; + public static final Integer CARDSET_COUNT = 15; + public static final Integer FOOTBALL_TEAM_COUNT = 33; + public static final Integer FOOTBALL_POSITION_COUNT = 25; + public static final Integer PLAYER_COUNT = 38; + public static final Integer PLAYER_CHRIS_COUNT = 3; + public static final Integer POSITION_COUNT = 44; + public static final Integer POSITION_CENTER_COUNT = 3; + public static final Integer ROOSTER_COUNT = 11; + public static final Integer ROOSTER_YEAR = 1900; + public static final Integer SPORT_COUNT = 4; + public static final Integer TEAM_COUNT = 122; + public static final Integer VENDOR_COUNT = 9; + public static final String CARDSET_NAME = "CardSet"; + public static final String CARDSET_MYSTIQUE_NAME = "Mystique"; + public static final String DOLPHINS_NAME = "Miami Dolphins"; + public static final Object DOLPHINS_SHORT = "Dolphins"; + public static final String FOOTBALL_NAME = "Football"; + public static final String PLAYER_FIRSTNAME = "FirstName"; + public static final String PLAYER_LASTNAME = "LastName"; + public static final String PLAYER_CHRIS_NAME = "Chris"; + public static final String POSITION_CENTER = "Center"; + public static final String POSITION_NAME = "Position"; + public static final String POSITION_SHORTNAME = "POS"; + public static final String QUARTERBACK_NAME = "Quarterback"; + public static final String QUARTERBACK_SHORTNAME = "QB"; + public static final String SPORT_NAME = "Sport"; + public static final String TEAM_NAME = "Musterstadt Team"; + public static final String TEAM_SHORTNAME = "Team"; + public static final String TOPPS_NAME = "Topps"; + public static final String VENDOR_FLEER = "Fleer"; + public static final String VENDOR_NAME = "Vendor"; +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/ArticleAuthorTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/ArticleAuthorTest.java new file mode 100644 index 0000000..532e9b6 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/ArticleAuthorTest.java @@ -0,0 +1,81 @@ +package de.thpeetz.kontor.data.bookshelf; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.repository.bookshelf.ArticleAuthorRepository; +import de.thpeetz.kontor.repository.bookshelf.ArticleRepository; +import de.thpeetz.kontor.repository.bookshelf.AuthorRepository; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.TransactionSystemException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +@Disabled +class ArticleAuthorTest { + + @Autowired + ArticleRepository articleRepository; + + @Autowired + AuthorRepository authorRepository; + + @Autowired + ArticleAuthorRepository articleAuthorRepository; + + @Test + @Order(1) + void checkInitialLoad() { + assertEquals(TestBookshelfConstants.ARTICLEAUTHOR_COUNT, articleAuthorRepository.findAll().size()); + } + + @Test + @Order(2) + void exceptionThrownWhenSavingEmptyValues() { + ArticleAuthor articleAuthor = new ArticleAuthor(); + assertThrows(TransactionSystemException.class, () -> { + articleAuthorRepository.save(articleAuthor); + }); + } + + @Test + @Order(3) + void exceptionThrownWhenSavingIdenticalEntry() { + Author author = new Author(); + author.setFirstName(TestBookshelfConstants.AUTHOR_FIRSTNAME); + author.setLastName(TestBookshelfConstants.AUTHOR_LASTNAME); + Author savedAuthor = authorRepository.save(author); + Article article = new Article(); + article.setTitle(TestBookshelfConstants.ARTICLE_TITLE); + Article savedArticle = articleRepository.save(article); + ArticleAuthor articleAuthor = new ArticleAuthor(); + articleAuthor.setArticle(article); + articleAuthor.setAuthor(author); + ArticleAuthor savedArticleAuthor = articleAuthorRepository.save(articleAuthor); + ArticleAuthor articleAuthor1 = new ArticleAuthor(); + articleAuthor1.setArticle(article); + articleAuthor1.setAuthor(author); + assertThrows(DataIntegrityViolationException.class, () -> { + articleAuthorRepository.save(articleAuthor1); + }); + articleAuthorRepository.delete(savedArticleAuthor); + assertEquals(TestBookshelfConstants.ARTICLEAUTHOR_COUNT, articleAuthorRepository.findAll().size()); + savedAuthor.getArticleAuthors().remove(savedArticleAuthor); + authorRepository.save(savedAuthor); + authorRepository.delete(savedAuthor); + assertEquals(TestBookshelfConstants.AUTHOR_COUNT, authorRepository.findAll().size()); + savedArticle.getAuthors().remove(savedArticleAuthor); + articleRepository.save(savedArticle); + articleRepository.delete(savedArticle); + assertEquals(TestBookshelfConstants.ARTICLE_COUNT, articleRepository.findAll().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/ArticleTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/ArticleTest.java new file mode 100644 index 0000000..a449052 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/ArticleTest.java @@ -0,0 +1,47 @@ +package de.thpeetz.kontor.data.bookshelf; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.repository.bookshelf.ArticleRepository; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.TransactionSystemException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@SpringBootTest +class ArticleTest { + + @Autowired + ArticleRepository articleRepository; + + @Test + void checkInitialLoad() { + assertEquals(TestBookshelfConstants.BOOK_COUNT, articleRepository.findAll().size()); + } + + @Test + void exceptionThrownWhenSavingEmptyFields() { + Article article = new Article(); + assertThrows(TransactionSystemException.class, () -> { + articleRepository.save(article); + }); + } + + @Test + void exceptionThrownWhenSavingIdenticalTitle() { + Article article = new Article(); + article.setTitle(TestBookshelfConstants.ARTICLE_TITLE); + Article savedArticle = articleRepository.save(article); + Article article1 = new Article(); + article1.setTitle(article.getTitle()); + assertThrows(DataIntegrityViolationException.class, ()-> { + articleRepository.save(article1); + }); + articleRepository.delete(savedArticle); + assertEquals(TestBookshelfConstants.ARTICLE_COUNT, articleRepository.findAll().size()); + } +} \ No newline at end of file diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/AuthorTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/AuthorTest.java new file mode 100644 index 0000000..f5653d9 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/AuthorTest.java @@ -0,0 +1,46 @@ +package de.thpeetz.kontor.data.bookshelf; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.repository.bookshelf.AuthorRepository; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.TransactionSystemException; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +class AuthorTest { + + @Autowired + private AuthorRepository authorRepository; + + @Test + void throwExceptionWhenPlayerSavedWithEmptyName() { + Author author = new Author(); + assertThrows(TransactionSystemException.class, () -> { + authorRepository.save(author); + }); + } + + @Test + void throwExceptionWhenPlayerSavedWithExistingName() { + assertEquals(TestBookshelfConstants.AUTHOR_COUNT, authorRepository.findAll().size()); + Author existingAuthor = new Author(); + existingAuthor.setFirstName(TestBookshelfConstants.AUTHOR_FIRSTNAME); + existingAuthor.setLastName(TestBookshelfConstants.AUTHOR_LASTNAME); + existingAuthor = authorRepository.save(existingAuthor); + assertEquals(TestBookshelfConstants.AUTHOR_COUNT+1, authorRepository.findAll().size()); + Author author = new Author(); + author.setFirstName(existingAuthor.getFirstName()); + author.setLastName(existingAuthor.getLastName()); + assertThrows(DataIntegrityViolationException.class, () -> { + authorRepository.save(author); + }); + assertNotNull(existingAuthor); + authorRepository.delete(existingAuthor); + assertEquals(TestBookshelfConstants.AUTHOR_COUNT, authorRepository.findAll().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/BookAuthorTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/BookAuthorTest.java new file mode 100644 index 0000000..e3e1a93 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/BookAuthorTest.java @@ -0,0 +1,87 @@ +package de.thpeetz.kontor.data.bookshelf; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.repository.bookshelf.AuthorRepository; +import de.thpeetz.kontor.repository.bookshelf.BookAuthorRepository; +import de.thpeetz.kontor.repository.bookshelf.BookRepository; +import de.thpeetz.kontor.repository.bookshelf.BookshelfPublisherRepository; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.TransactionSystemException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@SpringBootTest +@Disabled +class BookAuthorTest { + + @Autowired + BookRepository bookRepository; + + @Autowired + AuthorRepository authorRepository; + + @Autowired + BookAuthorRepository bookAuthorRepository; + + @Autowired + BookshelfPublisherRepository bookshelfPublisherRepository; + + @Test + void checkInitialLoad() { + assertEquals(TestBookshelfConstants.BOOKAUTHOR_COUNT, bookAuthorRepository.findAll().size()); + } + + @Test + void exceptionThrownWhenSavingEmptyValues() { + BookAuthor bookAuthor = new BookAuthor(); + assertThrows(TransactionSystemException.class, () -> { + bookAuthorRepository.save(bookAuthor); + }); + } + + @Test + void exceptionThrownWhenSavingIdenticalEntry() { + Author author = new Author(); + author.setFirstName(TestBookshelfConstants.AUTHOR_FIRSTNAME); + author.setLastName(TestBookshelfConstants.AUTHOR_LASTNAME); + Author savedAuthor = authorRepository.save(author); + BookshelfPublisher publisher = new BookshelfPublisher(); + publisher.setName(TestBookshelfConstants.PUBLISHER_NAME); + BookshelfPublisher savedPublisher = bookshelfPublisherRepository.save(publisher); + Book book = new Book(); + book.setTitle(TestBookshelfConstants.BOOK_TITLE); + book.setIsbn(TestBookshelfConstants.BOOK_ISBN); + book.setPublisher(publisher); + Book savedBook = bookRepository.save(book); + BookAuthor bookAuthor = new BookAuthor(); + bookAuthor.setBook(book); + bookAuthor.setAuthor(author); + BookAuthor savedBookAuthor = bookAuthorRepository.save(bookAuthor); + BookAuthor bookAuthor1 = new BookAuthor(); + bookAuthor1.setBook(book); + bookAuthor1.setAuthor(author); + assertThrows(DataIntegrityViolationException.class, () -> { + bookAuthorRepository.save(bookAuthor1); + }); + savedAuthor.getBookAuthors().remove(savedBookAuthor); + authorRepository.save(savedAuthor); + savedBook.getAuthors().remove(savedBookAuthor); + bookRepository.save(savedBook); + savedPublisher.getBooks().remove(savedBook); + bookshelfPublisherRepository.save(savedPublisher); + authorRepository.delete(savedAuthor); + assertEquals(TestBookshelfConstants.AUTHOR_COUNT, authorRepository.findAll().size()); + bookRepository.delete(savedBook); + assertEquals(TestBookshelfConstants.ARTICLE_COUNT, bookRepository.findAll().size()); + bookshelfPublisherRepository.delete(savedPublisher); + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT, bookshelfPublisherRepository.findAll().size()); + bookAuthorRepository.delete(savedBookAuthor); + assertEquals(TestBookshelfConstants.ARTICLEAUTHOR_COUNT, bookAuthorRepository.findAll().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/BookTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/BookTest.java new file mode 100644 index 0000000..fba9bee --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/BookTest.java @@ -0,0 +1,57 @@ +package de.thpeetz.kontor.data.bookshelf; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.repository.bookshelf.BookRepository; +import de.thpeetz.kontor.repository.bookshelf.BookshelfPublisherRepository; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.TransactionSystemException; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +class BookTest { + + @Autowired + BookRepository bookRepository; + + @Autowired + BookshelfPublisherRepository bookshelfPublisherRepository; + + @Test + void checkInitialLoad() { + assertEquals(TestBookshelfConstants.BOOK_COUNT, bookRepository.findAll().size()); + } + + @Test + void exceptionThrownWhenSavingEmptyFields() { + Book book = new Book(); + assertThrows(TransactionSystemException.class, () -> { + bookRepository.save(book); + }); + } + + @Test + void exceptionThrownWhenSavingIdenticalISBN() { + BookshelfPublisher publisher = new BookshelfPublisher(); + publisher.setName(TestBookshelfConstants.PUBLISHER_NAME); + BookshelfPublisher savedPublisher = bookshelfPublisherRepository.save(publisher); + Book book = new Book(); + book.setTitle(TestBookshelfConstants.BOOK_TITLE); + book.setIsbn(TestBookshelfConstants.BOOK_ISBN); + book.setPublisher(savedPublisher); + //TODO Book savedBook = bookRepository.save(book); + Book book1 = new Book(); + book1.setTitle(book.getTitle()); + book1.setIsbn(book.getIsbn()); + assertThrows(TransactionSystemException.class, ()-> { + bookRepository.save(book1); + }); + bookRepository.delete(book); + assertEquals(TestBookshelfConstants.BOOK_COUNT, bookRepository.findAll().size()); + bookshelfPublisherRepository.delete(savedPublisher); + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT, bookshelfPublisherRepository.findAll().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/BookshelfPublisherTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/BookshelfPublisherTest.java new file mode 100644 index 0000000..61568da --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/bookshelf/BookshelfPublisherTest.java @@ -0,0 +1,46 @@ +package de.thpeetz.kontor.data.bookshelf; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.TransactionSystemException; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.repository.bookshelf.BookshelfPublisherRepository; + +@SpringBootTest +class BookshelfPublisherTest { + + @Autowired + private BookshelfPublisherRepository publisherRepository; + + @Test + void checkInitialDataLoad() { + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); + } + + @Test + void throwExceptionWhenPublisherSavedWithEmptyName() { + BookshelfPublisher publisher = new BookshelfPublisher(); + assertThrows(TransactionSystemException.class, () -> { + publisherRepository.save(publisher); + }); + } + + @Test + void savePublisherWithIdenticalName() { + BookshelfPublisher publisher1 = new BookshelfPublisher(); + publisher1.setName(TestBookshelfConstants.PUBLISHER_NAME); + publisherRepository.save(publisher1); + BookshelfPublisher publisher2 = new BookshelfPublisher(); + publisher2.setName(TestBookshelfConstants.PUBLISHER_NAME); + assertThrows(DataIntegrityViolationException.class, () -> { + publisherRepository.save(publisher2); + }); + publisherRepository.delete(publisher1); + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/ArtistTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/ArtistTest.java new file mode 100644 index 0000000..68c27f4 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/ArtistTest.java @@ -0,0 +1,49 @@ +package de.thpeetz.kontor.data.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.repository.comics.ArtistRepository; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.TransactionSystemException; + +@SpringBootTest +class ArtistTest { + + @Autowired + private ArtistRepository artistRepository; + + @Test + void checkInitialDataLoad() { + List artists = artistRepository.findAll(); + assertEquals(TestComicConstants.ARTIST_COUNT, artists.size()); + } + + @Test + void throwExceptionWhenArtistSavedWithEmptyName() { + Artist artist1 = new Artist(); + assertThrows(TransactionSystemException.class, () -> { + artistRepository.save(artist1); + }); + } + + @Test + void saveArtistWithIdenticalName() { + String artistName = "Lastname, Firstname"; + Artist artist1 = new Artist(); + artist1.setName(artistName); + artistRepository.save(artist1); + Artist artist2 = new Artist(); + artist2.setName(artistName); + assertThrows(DataIntegrityViolationException.class, () -> { + artistRepository.save(artist2); + }); + artistRepository.delete(artist1); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/ComicTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/ComicTest.java new file mode 100644 index 0000000..34af697 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/ComicTest.java @@ -0,0 +1,75 @@ +package de.thpeetz.kontor.data.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.TransactionSystemException; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.repository.comics.ComicRepository; +import de.thpeetz.kontor.services.ComicService; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +class ComicTest { + + @Autowired + private ComicRepository comicRepository; + + @Autowired + private ComicService comicService; + + @Test + @Order(1) + void checkInitialDataLoad() { + List comics = comicRepository.findAll(); + assertEquals(TestComicConstants.COMIC_COUNT, comics.size()); + } + + @Test + @Order(2) + void exceptionThrownWhenSavingComicWithoutPublisher() { + Comic comic = new Comic(); + comic.setTitle(TestComicConstants.COMIC_TITLE); + assertThrows(TransactionSystemException.class, () -> { + comicRepository.save(comic); + }); + } + + @Test + @Order(3) + void exceptionThrownWhenSavingComicWithEmptyTitle() { + Comic comic = new Comic(); + Publisher publisher = TestComicConstants.getPublisherForComicTests(comicService); + comic.setPublisher(publisher); + assertNull(comic.getTitle()); + assertThrows(TransactionSystemException.class, () -> { + comicRepository.save(comic); + }); + comic.setTitle(""); + assertTrue(comic.getTitle().isEmpty()); + assertThrows(TransactionSystemException.class, () -> { + comicRepository.save(comic); + }); + } + + @Test + @Order(4) + void exceptionThrownWhenSavingComicWithSameNameFromDifferentPublishers() { + Publisher publisher = TestComicConstants.getPublisherForComicTests(comicService); + Comic comic = new Comic(); + comic.setTitle(TestComicConstants.SOJOURN_TPB_COMIC_TITLE); + comic.setPublisher(publisher); + assertThrows(DataIntegrityViolationException.class, () -> { + comicRepository.save(comic); + }); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/ComicWorkTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/ComicWorkTest.java new file mode 100644 index 0000000..4d080ae --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/ComicWorkTest.java @@ -0,0 +1,24 @@ +package de.thpeetz.kontor.data.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.services.ComicService; + +@SpringBootTest +public class ComicWorkTest { + + @Autowired + private ComicService comicService; + + @Test + void checkInitialDataLoad() { + List comicWorks = comicService.findAllComicWorks(); + assertEquals(18, comicWorks.size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/IssueTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/IssueTest.java new file mode 100644 index 0000000..43b1ff9 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/IssueTest.java @@ -0,0 +1,63 @@ +package de.thpeetz.kontor.data.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.TransactionSystemException; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.repository.comics.IssueRepository; +import de.thpeetz.kontor.services.ComicService; + +@SpringBootTest +class IssueTest { + + @Autowired + private IssueRepository issueRepository; + + @Autowired + private ComicService comicService; + + @Test + void checkInitialDataLoad() { + List issues = comicService.findAllIssues(); + assertEquals(TestComicConstants.ISSUE_COUNT, issues.size()); + } + + @Test + void exceptionThrownWhenSavingIssueWithEmptyNumber() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + assertNotNull(comic); + Issue issue = new Issue(); + issue.setComic(comic); + assertThrows(TransactionSystemException.class, () -> { + issueRepository.save(issue); + }); + } + + @Test + void exceptionThrownWhenSavingStoryArcWithoutComic() { + Issue issue = new Issue(); + issue.setIssueNumber(TestComicConstants.ISSUE_ISSUENUMBER); + assertThrows(TransactionSystemException.class, () -> { + issueRepository.save(issue); + }); + } + + @Test + void saveStoryArc() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + assertEquals(0, comic.getStoryArcs().size()); + Issue issue = new Issue(); + issue.setComic(comic); + issue.setIssueNumber(TestComicConstants.ISSUE_ISSUENUMBER); + Issue savedInstance = issueRepository.save(issue); + assertNotNull(savedInstance); + comicService.deleteIssue(savedInstance); + assertEquals(0, comic.getStoryArcs().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/PublisherTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/PublisherTest.java new file mode 100644 index 0000000..28249f3 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/PublisherTest.java @@ -0,0 +1,46 @@ +package de.thpeetz.kontor.data.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.repository.comics.PublisherRepository; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.TransactionSystemException; + +@SpringBootTest +class PublisherTest { + + @Autowired + private PublisherRepository publisherRepository; + + @Test + void checkInitialDataLoad() { + assertEquals(TestComicConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); + } + + @Test + void throwExceptionWhenPublisherSavedWithEmptyName() { + Publisher publisher = new Publisher(); + assertThrows(TransactionSystemException.class, () -> { + publisherRepository.save(publisher); + }); + } + + @Test + void savePublisherWithIdenticalName() { + Publisher publisher1 = new Publisher(); + publisher1.setName(TestComicConstants.PUBLISHER_NAME); + publisherRepository.save(publisher1); + Publisher publisher2 = new Publisher(); + publisher2.setName(TestComicConstants.PUBLISHER_NAME); + assertThrows(DataIntegrityViolationException.class, () -> { + publisherRepository.save(publisher2); + }); + publisherRepository.delete(publisher1); + assertEquals(TestComicConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/StoryArcTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/StoryArcTest.java new file mode 100644 index 0000000..545b21b --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/StoryArcTest.java @@ -0,0 +1,60 @@ +package de.thpeetz.kontor.data.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.TransactionSystemException; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.repository.comics.StoryArcRepository; +import de.thpeetz.kontor.services.ComicService; + +@SpringBootTest +class StoryArcTest { + + @Autowired + private StoryArcRepository storyArcRepository; + + @Autowired + private ComicService comicService; + + @Test + void checkInitialLoad() { + assertEquals(TestComicConstants.STORYARC_COUNT, storyArcRepository.findAll().size()); + } + + @Test + void exceptionThrownWhenSavingStoryArcWithEmptyName() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + assertNotNull(comic); + StoryArc storyArc = new StoryArc(); + storyArc.setComic(comic); + assertThrows(TransactionSystemException.class, () -> { + storyArcRepository.save(storyArc); + }); + } + + @Test + void exceptionThrownWhenSavingStoryArcWithoutComic() { + StoryArc storyArc = new StoryArc(); + storyArc.setName(TestComicConstants.STORYARC_NAME); + assertThrows(TransactionSystemException.class, () -> { + storyArcRepository.save(storyArc); + }); + } + + @Test + void saveStoryArc() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + assertEquals(0, comic.getStoryArcs().size()); + StoryArc storyArc = new StoryArc(); + storyArc.setName(TestComicConstants.STORYARC_NAME); + storyArc.setComic(comic); + StoryArc savedInstance = storyArcRepository.save(storyArc); + assertNotNull(savedInstance); + comicService.deleteStoryArc(savedInstance); + assertEquals(0, comic.getStoryArcs().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/TradePaperbackTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/TradePaperbackTest.java new file mode 100644 index 0000000..fdb469c --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/TradePaperbackTest.java @@ -0,0 +1,60 @@ +package de.thpeetz.kontor.data.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.TransactionSystemException; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.repository.comics.TradePaperbackRepository; +import de.thpeetz.kontor.services.ComicService; + +@SpringBootTest +class TradePaperbackTest { + + @Autowired + private TradePaperbackRepository tradePaperbackRepository; + + @Autowired + private ComicService comicService; + + @Test + void checkInitialDataLoad() { + assertEquals(TestComicConstants.TRADEPAPERBACK_COUNT, tradePaperbackRepository.findAll().size()); + } + + @Test + void exceptionThrownWhenSavingTradePaperbackWithEmptyName() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + assertNotNull(comic); + TradePaperback tradePaperback = new TradePaperback(); + tradePaperback.setComic(comic); + assertThrows(TransactionSystemException.class, () -> { + tradePaperbackRepository.save(tradePaperback); + }); + } + + @Test + void exceptionThrownWhenSavingTradePaperbackWithoutComic() { + TradePaperback tradePaperback = new TradePaperback(); + tradePaperback.setName(TestComicConstants.TRADEPAPERBACK_NAME); + assertThrows(TransactionSystemException.class, () -> { + tradePaperbackRepository.save(tradePaperback); + }); + } + + @Test + void saveTradePaperback() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + assertEquals(0, comic.getTradePaperbacks().size()); + TradePaperback tradePaperback = new TradePaperback(); + tradePaperback.setName(TestComicConstants.TRADEPAPERBACK_NAME); + tradePaperback.setComic(comic); + TradePaperback savedInstance = tradePaperbackRepository.save(tradePaperback); + assertNotNull(savedInstance); + comicService.deleteTradePaperBack(savedInstance); + assertEquals(0, comic.getTradePaperbacks().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/VolumeTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/VolumeTest.java new file mode 100644 index 0000000..b0413b6 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/VolumeTest.java @@ -0,0 +1,60 @@ +package de.thpeetz.kontor.data.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.TransactionSystemException; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.repository.comics.VolumeRepository; +import de.thpeetz.kontor.services.ComicService; + +@SpringBootTest +class VolumeTest { + + @Autowired + private VolumeRepository volumeRepository; + + @Autowired + private ComicService comicService; + + @Test + void checkInitialDataLoad() { + assertEquals(TestComicConstants.VOLUME_COUNT, volumeRepository.count()); + } + + @Test + void exceptionThrownWhenSavingVolumeWithEmptyName() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + Volume volume = new Volume(); + volume.setComic(comic); + assertThrows(TransactionSystemException.class, () -> { + volumeRepository.save(volume); + }); + } + + @Test + void exceptionThrownWhenSavingVolumeWithoutComic() { + Volume volume = new Volume(); + volume.setName(TestComicConstants.VOLUME_NAME); + assertThrows(TransactionSystemException.class, () -> { + volumeRepository.save(volume); + }); + } + + @Test + void saveVolume() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + assertEquals(0, comic.getVolumes().size()); + Volume volume = new Volume(); + volume.setName(TestComicConstants.VOLUME_NAME); + volume.setComic(comic); + Volume savedInstance = volumeRepository.save(volume); + assertNotNull(savedInstance); + comicService.deleteVolume(savedInstance); + assertEquals(0, comic.getVolumes().size()); + assertEquals(TestComicConstants.VOLUME_COUNT, volumeRepository.count()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/WorktypeTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/WorktypeTest.java new file mode 100644 index 0000000..f3c2d02 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/comics/WorktypeTest.java @@ -0,0 +1,83 @@ +package de.thpeetz.kontor.data.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.repository.comics.WorktypeRepository; + +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.TransactionSystemException; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +class WorktypeTest { + + @Autowired + private WorktypeRepository worktypeRepository; + + @Test + @Order(1) + void checkInitialDataLoad() { + List worktypes = worktypeRepository.findAll(); + assertEquals(3, worktypes.size()); + } + + @Test + @Order(2) + void findWorktypeByName() { + Worktype found = worktypeRepository.findByName(TestComicConstants.WORKTYPE_INKER); + assertNotNull(found); + assertEquals(TestComicConstants.WORKTYPE_INKER, found.getName()); + Worktype notFound = worktypeRepository.findByName("er"); + assertNull(notFound); + } + + @Test + @Order(3) + void throwExceptionWhenArtistSavedWithEmptyName() { + Worktype worktype1 = new Worktype(); + assertThrows(TransactionSystemException.class, () -> { + worktypeRepository.save(worktype1); + }); + } + + @Test + @Order(4) + void saveWorktypeWithIdenticalName() { + Worktype worktype1 = new Worktype(); + worktype1.setName(TestComicConstants.WORKTYPE_NAME); + worktypeRepository.save(worktype1); + Worktype worktype2 = new Worktype(); + worktype2.setName(TestComicConstants.WORKTYPE_NAME); + assertThrows(DataIntegrityViolationException.class, () -> { + worktypeRepository.save(worktype2); + }); + worktypeRepository.delete(worktype1); + } + + @Test + @Order(5) + void saveWorktype() { + Worktype worktype = new Worktype(); + worktype.setName(TestComicConstants.WORKTYPE_NAME); + worktypeRepository.save(worktype); + assertEquals(TestComicConstants.WORKTYPE_COUNT + 1, worktypeRepository.count()); + } + + @Test + @Order(6) + void deleteWorktype() { + Worktype worktype = worktypeRepository.findByName(TestComicConstants.WORKTYPE_NAME); + assertNotNull(worktype); + worktypeRepository.delete(worktype); + assertEquals(TestComicConstants.WORKTYPE_COUNT, worktypeRepository.count()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/media/MediaArticleTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/media/MediaArticleTest.java new file mode 100644 index 0000000..7f80de4 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/media/MediaArticleTest.java @@ -0,0 +1,33 @@ +package de.thpeetz.kontor.data.media; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.repository.media.MediaArticleRepository; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; + +@SpringBootTest +public class MediaArticleTest { + + @Autowired + private MediaArticleRepository mediaArticleRepository; + + @Test + void checkInitialLoad() { + assertTrue(mediaArticleRepository.findAll().isEmpty()); + } + + @Test + void checkDefaultValues() { + MediaArticle mediaArticle = new MediaArticle(); + assertNull(mediaArticle.getUrl()); + assertNull(mediaArticle.getTitle()); + assertNull(mediaArticle.getCreatedDate()); + assertNull(mediaArticle.getLastModifiedDate()); + assertNull(mediaArticle.getId()); + assertFalse(mediaArticle.isReview()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/media/MediaFileTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/media/MediaFileTest.java new file mode 100644 index 0000000..02d7a28 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/media/MediaFileTest.java @@ -0,0 +1,39 @@ +package de.thpeetz.kontor.data.media; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.repository.media.MediaFileRepository; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +public class MediaFileTest { + + @Autowired + private MediaFileRepository mediaFileRepository; + + @Test + void checkInitialDataLoad() { + List mediaFileList = mediaFileRepository.findAll(); + assertTrue(mediaFileList.isEmpty()); + } + + @Test + void checkDefaultValues() { + MediaFile mediaFile = new MediaFile(); + assertNull(mediaFile.getUrl()); + assertNull(mediaFile.getTitle()); + assertNull(mediaFile.getFileName()); + assertNull(mediaFile.getPath()); + assertNull(mediaFile.getCloudLink()); + assertNull(mediaFile.getCreatedDate()); + assertNull(mediaFile.getLastModifiedDate()); + assertNull(mediaFile.getId()); + assertFalse(mediaFile.isReview()); + assertFalse(mediaFile.isShouldDownload()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/CardSetTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/CardSetTest.java new file mode 100644 index 0000000..a28e478 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/CardSetTest.java @@ -0,0 +1,22 @@ +package de.thpeetz.kontor.data.tysc; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.services.CardService; + +@SpringBootTest +class CardSetTest { + + @Autowired + private CardService cardService; + + @Test + void checkInitialDataLoad() { + assertEquals(TestTyscConstants.CARDSET_COUNT, cardService.findAllCardSets(null).size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/CardTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/CardTest.java new file mode 100644 index 0000000..990bfa8 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/CardTest.java @@ -0,0 +1,22 @@ +package de.thpeetz.kontor.data.tysc; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.services.CardService; + +@SpringBootTest +class CardTest { + + @Autowired + private CardService cardService; + + @Test + void checkInitialDataLoad() { + assertEquals(TestTyscConstants.CARD_COUNT, cardService.findAllCards(null).size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/FieldPositionTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/FieldPositionTest.java new file mode 100644 index 0000000..342aa67 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/FieldPositionTest.java @@ -0,0 +1,45 @@ +package de.thpeetz.kontor.data.tysc; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.TransactionSystemException; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.repository.tysc.FieldPositionRepository; + +@SpringBootTest +class FieldPositionTest { + + @Autowired + private FieldPositionRepository fieldPositionRepository; + + @Test + void checkInitialDataLoad() { + assertEquals(Integer.toUnsignedLong(TestTyscConstants.POSITION_COUNT), fieldPositionRepository.count()); + } + + @Test + void throwExceptionWhenPositionSavedWithEmptyName() { + FieldPosition fieldPosition = new FieldPosition(); + assertThrows(TransactionSystemException.class, () -> { + fieldPositionRepository.save(fieldPosition); + }); + fieldPosition.setName("Position"); + assertThrows(TransactionSystemException.class, () -> { + fieldPositionRepository.save(fieldPosition); + }); + } + + @Test + void throwExceptionWhenPositionSavedWithExistingName() { + FieldPosition existingFieldPosition = fieldPositionRepository.findAll().get(11); + FieldPosition fieldPosition = new FieldPosition(); + fieldPosition.setName(existingFieldPosition.getName()); + assertThrows(TransactionSystemException.class, () -> { + fieldPositionRepository.save(fieldPosition); + }); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/PlayerTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/PlayerTest.java new file mode 100644 index 0000000..4935d30 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/PlayerTest.java @@ -0,0 +1,54 @@ +package de.thpeetz.kontor.data.tysc; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.TransactionSystemException; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.repository.tysc.PlayerRepository; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +class PlayerTest { + + @Autowired + private PlayerRepository playerRepository; + + @Test + @Order(1) + void checkInitialDataLoad() { + List players = playerRepository.findAll(); + assertEquals(TestTyscConstants.PLAYER_COUNT, players.size()); + } + + @Test + @Order(2) + void throwExceptionWhenPlayerSavedWithEmptyName() { + Player player = new Player(); + assertThrows(TransactionSystemException.class, () -> { + playerRepository.save(player); + }); + } + + @Test + @Order(3) + void throwExceptionWhenPlayerSavedWithExistingName() { + Player existingPlayer = playerRepository.findAll().get(10); + assertNotNull(existingPlayer); + Player player = new Player(); + player.setFirstName(existingPlayer.getFirstName()); + player.setLastName(existingPlayer.getLastName()); + assertThrows(DataIntegrityViolationException.class, () -> { + playerRepository.save(player); + }); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/RoosterTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/RoosterTest.java new file mode 100644 index 0000000..36cffa1 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/RoosterTest.java @@ -0,0 +1,48 @@ +package de.thpeetz.kontor.data.tysc; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.repository.tysc.RoosterRepository; + +@SpringBootTest +class RoosterTest { + + @Autowired + private RoosterRepository roosterRepository; + + @Test + void checkInitialDataLoad() { + List roosters = roosterRepository.findAll(); + assertEquals(TestTyscConstants.ROOSTER_COUNT, roosters.size()); + } + + @Test + void checkFetchingData() { + Rooster rooster = roosterRepository.findAll().get(4); + assertNotNull(rooster.getTeam()); + assertNotNull(rooster.getPlayer()); + assertNotNull(rooster.getPosition()); + } + + @Test + void exceptionThrownWhenSavingDuplicateRooster() { + List roosters = roosterRepository.findAll(); + Rooster existingRooster = roosters.get(5); + Rooster rooster = new Rooster(); + rooster.setPlayer(existingRooster.getPlayer()); + rooster.setTeam(existingRooster.getTeam()); + rooster.setPosition(existingRooster.getPosition()); + rooster.setYear(existingRooster.getYear()); + assertThrows(DataIntegrityViolationException.class, () -> { + roosterRepository.save(rooster); + }); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/SportTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/SportTest.java new file mode 100644 index 0000000..4a6e837 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/SportTest.java @@ -0,0 +1,45 @@ +package de.thpeetz.kontor.data.tysc; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.TransactionSystemException; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.repository.tysc.SportRepository; + +@SpringBootTest +class SportTest { + + @Autowired + private SportRepository sportRepository; + + @Test + void checkInitialDataLoad() { + List sports = sportRepository.findAll(); + assertEquals(TestTyscConstants.SPORT_COUNT, sports.size()); + } + + @Test + void exceptionThrownWhenSavingSportWithEmptyName() { + Sport sport = new Sport(); + assertThrows(TransactionSystemException.class, () -> { + sportRepository.save(sport); + }); + } + + @Test + void exceptionThrownWhenSavingSportWithExistingName() { + Sport existingSport = sportRepository.findAll().get(0); + Sport sport = new Sport(); + sport.setName(existingSport.getName()); + assertThrows(DataIntegrityViolationException.class, () -> { + sportRepository.save(sport); + }); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/TeamTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/TeamTest.java new file mode 100644 index 0000000..87ac54c --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/TeamTest.java @@ -0,0 +1,54 @@ +package de.thpeetz.kontor.data.tysc; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.TransactionSystemException; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.repository.tysc.TeamRepository; + +@SpringBootTest +class TeamTest { + + @Autowired + private TeamRepository teamRepository; + + @Test + void checkInitialDataLoad() { + List teams = teamRepository.findAll(); + assertEquals(TestTyscConstants.TEAM_COUNT, teams.size()); + } + + @Test + void throwExceptionWhenTeamSavedWithEmptyName() { + Team team = new Team(); + assertThrows(TransactionSystemException.class, () -> { + teamRepository.save(team); + }); + } + + @Test + void throwExceptionWhenTeamSavedWithoutSport() { + Team team = new Team(); + team.setName(TestTyscConstants.TEAM_NAME); + assertThrows(TransactionSystemException.class, () -> { + teamRepository.save(team); + }); + } + + @Test + void throwExceptionWhenTeamSavedWithExistingName() { + Team existingTeam = teamRepository.findAll().get(11); + Team team = new Team(); + team.setName(existingTeam.getName()); + team.setSport(existingTeam.getSport()); + assertThrows(TransactionSystemException.class, () -> { + teamRepository.save(team); + }); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/VendorTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/VendorTest.java new file mode 100644 index 0000000..002a680 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/data/tysc/VendorTest.java @@ -0,0 +1,45 @@ +package de.thpeetz.kontor.data.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.TransactionSystemException; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.repository.tysc.VendorRepository; + +@SpringBootTest +class VendorTest { + + @Autowired + private VendorRepository vendorRepository; + + @Test + void checkInitialDataLoad() { + List vendors = vendorRepository.findAll(); + assertEquals(TestTyscConstants.VENDOR_COUNT, vendors.size()); + } + + @Test + void exceptionThrownWhenSavingVendortWithEmptyName() { + Vendor vendor = new Vendor(); + assertThrows(TransactionSystemException.class, () -> { + vendorRepository.save(vendor); + }); + } + + @Test + void exceptionThrownWhenSavingSportWithExistingName() { + Vendor vendor = new Vendor(); + vendor.setName(TestTyscConstants.TOPPS_NAME); + assertThrows(DataIntegrityViolationException.class, () -> { + vendorRepository.save(vendor); + }); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/media/TestConstants.java b/kontor-spring/src/test/java/de/thpeetz/kontor/media/TestConstants.java deleted file mode 100644 index 32ee883..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/media/TestConstants.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.thpeetz.kontor.media; - -public class TestConstants { - public static final String URL = "https://example.com/link.mp4"; -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaArticleTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaArticleTest.java deleted file mode 100644 index 365968f..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaArticleTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package de.thpeetz.kontor.media.data; - -import de.thpeetz.kontor.media.repository.MediaArticleRepository; -import de.thpeetz.kontor.media.services.MediaArticleService; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import static org.junit.jupiter.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.assertFalse; - -@SpringBootTest -public class MediaArticleTest { - - @Autowired - private MediaArticleRepository mediaArticleRepository; - - @Test - void checkInitialLoad() { - assertTrue(mediaArticleRepository.findAll().isEmpty()); - } - - @Test - void checkDefaultValues() { - MediaArticle mediaArticle = new MediaArticle(); - assertNull(mediaArticle.getUrl()); - assertNull(mediaArticle.getTitle()); - assertNull(mediaArticle.getCreatedDate()); - assertNull(mediaArticle.getLastModifiedDate()); - assertNull(mediaArticle.getId()); - assertFalse(mediaArticle.isReview()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaFileTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaFileTest.java deleted file mode 100644 index e1055ac..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaFileTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package de.thpeetz.kontor.media.data; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.media.repository.MediaFileRepository; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest -public class MediaFileTest { - - @Autowired - private MediaFileRepository mediaFileRepository; - - @Test - void checkInitialDataLoad() { - List mediaFileList = mediaFileRepository.findAll(); - assertTrue(mediaFileList.isEmpty()); - } - - @Test - void checkDefaultValues() { - MediaFile mediaFile = new MediaFile(); - assertNull(mediaFile.getUrl()); - assertNull(mediaFile.getTitle()); - assertNull(mediaFile.getFileName()); - assertNull(mediaFile.getPath()); - assertNull(mediaFile.getCloudLink()); - assertNull(mediaFile.getCreatedDate()); - assertNull(mediaFile.getLastModifiedDate()); - assertNull(mediaFile.getId()); - assertFalse(mediaFile.isReview()); - assertFalse(mediaFile.isShouldDownload()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaVideoTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaVideoTest.java deleted file mode 100644 index 73809d8..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/media/data/MediaVideoTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package de.thpeetz.kontor.media.data; - -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.media.repository.MediaVideoRepository; - -import static org.junit.jupiter.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.assertFalse; - -@SpringBootTest -public class MediaVideoTest { - - @Autowired - private MediaVideoRepository mediaVideoRepository; - - @Test - @Order(1) - void checkInitialLoad() { - assertTrue(mediaVideoRepository.findAll().isEmpty()); - } - - @Test - @Order(2) - void checkDefaultValues() { - MediaVideo mediaVideo = new MediaVideo(); - assertNull(mediaVideo.getUrl()); - assertNull(mediaVideo.getTitle()); - assertNull(mediaVideo.getFileName()); - assertNull(mediaVideo.getPath()); - assertNull(mediaVideo.getCloudLink()); - assertNull(mediaVideo.getCreatedDate()); - assertNull(mediaVideo.getLastModifiedDate()); - assertNull(mediaVideo.getId()); - assertFalse(mediaVideo.isReview()); - assertFalse(mediaVideo.isShouldDownload()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/media/services/MediaArticleServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/media/services/MediaArticleServiceTest.java deleted file mode 100644 index 6178aa8..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/media/services/MediaArticleServiceTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package de.thpeetz.kontor.media.services; - -import de.thpeetz.kontor.media.TestConstants; -import de.thpeetz.kontor.media.data.MediaArticle; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.MethodOrderer; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -@Slf4j -@SpringBootTest -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -class MediaArticleServiceTest { - - @Autowired - MediaArticleService mediaArticleService; - - @Test - @Order(1) - void findAllMediaArticles() { - assertTrue(mediaArticleService.findAllMediaArticles(null).isEmpty()); - } - - @Test - @Order(2) - void saveMediaArticle() { - int mediaArticleCount = mediaArticleService.findAllMediaArticles(null).size(); - MediaArticle mediaArticle = new MediaArticle(); - mediaArticle.setUrl(TestConstants.URL); - mediaArticleService.saveMediaArticle(mediaArticle); - assertEquals(++mediaArticleCount, mediaArticleService.findAllMediaArticles(null).size()); - } - - @Test - @Order(3) - void deleteMediaArticle() { - int mediaArticleCount = mediaArticleService.findAllMediaArticles(null).size(); - List mediaArticleList = mediaArticleService.findAllMediaArticles(TestConstants.URL); - assertEquals(1, mediaArticleService.findAllMediaArticles(null).size()); - mediaArticleService.deleteMediaArticle(mediaArticleList.get(0)); - assertEquals(--mediaArticleCount, mediaArticleService.findAllMediaArticles(null).size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/media/services/MediaFileServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/media/services/MediaFileServiceTest.java deleted file mode 100644 index e08193d..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/media/services/MediaFileServiceTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package de.thpeetz.kontor.media.services; - -import de.thpeetz.kontor.common.views.SearchFilter; -import de.thpeetz.kontor.media.TestConstants; -import de.thpeetz.kontor.media.data.MediaFile; -import org.junit.jupiter.api.MethodOrderer; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -public class MediaFileServiceTest { - - @Autowired - private MediaFileService mediaFileService; - - @Test - @Order(1) - void testFindAllMediaFiles() { - assertTrue(mediaFileService.findAllMediaFiles(null).isEmpty()); - } - - @Test - @Order(2) - void testSaveMediaFile() { - int mediaFileCount = mediaFileService.findAllMediaFiles(null).size(); - MediaFile mediaFile = new MediaFile(); - mediaFile.setUrl(TestConstants.URL); - mediaFileService.saveMediaFile(mediaFile); - assertEquals(mediaFileCount +1, mediaFileService.findAllMediaFiles(null).size()); - } - - @Test - @Order(3) - void testDeleteMediaFile() { - int mediaFileCount = mediaFileService.findAllMediaFiles(null).size(); - SearchFilter searchFilter = new SearchFilter(); - searchFilter.setSearchTerm(TestConstants.URL); - List mediaFileList = mediaFileService.findAllMediaFiles(searchFilter); - assertEquals(1, mediaFileList.size()); - mediaFileService.deleteMediaFile(mediaFileList.get(0)); - assertEquals(--mediaFileCount, mediaFileService.findAllMediaFiles(null).size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/media/services/MediaVideoServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/media/services/MediaVideoServiceTest.java deleted file mode 100644 index 36a6fb1..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/media/services/MediaVideoServiceTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.thpeetz.kontor.media.services; - -import de.thpeetz.kontor.media.TestConstants; -import de.thpeetz.kontor.media.data.MediaArticle; -import de.thpeetz.kontor.media.data.MediaVideo; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.MethodOrderer; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -@Slf4j -@SpringBootTest -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -public class MediaVideoServiceTest { - - @Autowired - private MediaVideoService mediaVideoService; - - @Test - void findAllMediaVideos() { - assertTrue(mediaVideoService.findAllMediaVideos(null).isEmpty()); - } - - @Test - void saveMediaVideo() { - int mediaVideoCount = mediaVideoService.findAllMediaVideos(null).size(); - MediaVideo mediaVideo = new MediaVideo(); - mediaVideo.setUrl(TestConstants.URL); - mediaVideoService.saveMediaVideo(mediaVideo); - assertEquals(++mediaVideoCount, mediaVideoService.findAllMediaVideos(null).size()); - } - - @Test - void deleteMediaVideo() { - int mediaVideoCount = mediaVideoService.findAllMediaVideos(null).size(); - List mediaVideoList = mediaVideoService.findAllMediaVideos(TestConstants.URL); - assertEquals(1, mediaVideoList.size()); - mediaVideoService.deleteMediaVideo(mediaVideoList.get(0)); - assertEquals(--mediaVideoCount, mediaVideoService.findAllMediaVideos(null).size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/ArticleAuthorRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/ArticleAuthorRepositoryTest.java new file mode 100644 index 0000000..e768aad --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/ArticleAuthorRepositoryTest.java @@ -0,0 +1,78 @@ +package de.thpeetz.kontor.repository.bookshelf; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.data.bookshelf.Article; +import de.thpeetz.kontor.data.bookshelf.ArticleAuthor; +import de.thpeetz.kontor.data.bookshelf.Author; + +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@Disabled +class ArticleAuthorRepositoryTest { + + @Autowired + ArticleAuthorRepository articleAuthorRepository; + + @Autowired + AuthorRepository authorRepository; + + @Autowired + ArticleRepository articleRepository; + + @Test + @Order(1) + void saveArticleAuthor() { + Author author = new Author(); + author.setFirstName(TestBookshelfConstants.AUTHOR_FIRSTNAME); + author.setLastName(TestBookshelfConstants.AUTHOR_LASTNAME); + //TODO Author savedAuthor = authorRepository.save(author); + assertEquals(TestBookshelfConstants.AUTHOR_COUNT+1, authorRepository.findAll().size()); + Article article = new Article(); + article.setTitle(TestBookshelfConstants.ARTICLE_TITLE); + //TODO Article savedArticle = articleRepository.save(article); + ArticleAuthor articleAuthor = new ArticleAuthor(); + articleAuthor.setArticle(article); + articleAuthor.setAuthor(author); + //TODO ArticleAuthor savedArticleAuthor = articleAuthorRepository.save(articleAuthor); + assertEquals(TestBookshelfConstants.ARTICLEAUTHOR_COUNT+1, articleAuthorRepository.findAll().size()); + } + + @Test + @Order(2) + void testFindByArticle() { + Article article = articleRepository.findByTitle(TestBookshelfConstants.ARTICLE_TITLE).get(0); + assertEquals(1, articleAuthorRepository.findByArticle(article).size()); + } + + @Test + @Order(3) + void testFindByAuthor() { + Author author = authorRepository.findByFirstNameAndLastName(TestBookshelfConstants.AUTHOR_FIRSTNAME, TestBookshelfConstants.AUTHOR_LASTNAME); + assertEquals(1, articleAuthorRepository.findByAuthor(author).size()); + } + + @Test + @Order(4) + void deleteArticleAuthor() { + assertEquals(1, articleAuthorRepository.findAll().size()); + ArticleAuthor articleAuthor = articleAuthorRepository.findAll().get(0); + Author author = articleAuthor.getAuthor(); + author.getArticleAuthors().remove(articleAuthor); + author = authorRepository.save(author); + Article article = articleAuthor.getArticle(); + article.getAuthors().remove(articleAuthor); + article = articleRepository.save(article); + articleAuthorRepository.delete(articleAuthor); + assertEquals(TestBookshelfConstants.ARTICLEAUTHOR_COUNT, articleAuthorRepository.findAll().size()); + authorRepository.delete(author); + assertEquals(TestBookshelfConstants.AUTHOR_COUNT, authorRepository.findAll().size()); + articleRepository.delete(article); + assertEquals(TestBookshelfConstants.ARTICLE_COUNT, articleRepository.findAll().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/ArticleRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/ArticleRepositoryTest.java new file mode 100644 index 0000000..62614f3 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/ArticleRepositoryTest.java @@ -0,0 +1,63 @@ +package de.thpeetz.kontor.repository.bookshelf; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.data.bookshelf.Article; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +class ArticleRepositoryTest { + + @Autowired + ArticleRepository articleRepository; + + @Test + @Order(1) + void checkInitialLoad() { + assertEquals(TestBookshelfConstants.ARTICLE_COUNT, articleRepository.findAll().size()); + } + + @Test + @Order(2) + void saveArticle() { + Article article = new Article(); + article.setTitle(TestBookshelfConstants.ARTICLE_TITLE); + articleRepository.save(article); + assertEquals(TestBookshelfConstants.ARTICLE_COUNT+1, articleRepository.findAll().size()); + } + + @Test + @Order(3) + void search() { + List
    articles = articleRepository.search(TestBookshelfConstants.ARTICLE_TITLE.substring(2,5)); + assertEquals(1, articles.size()); + assertEquals(0, articleRepository.search(TestBookshelfConstants.BOOK_TITLE).size()); + } + + @Test + @Order(4) + void findByTitle() { + List
    articles = articleRepository.search(TestBookshelfConstants.ARTICLE_TITLE); + assertEquals(1, articles.size()); + } + + @Test + @Order(5) + void deleteArticle() { + List
    articles = articleRepository.findAll(); + assertEquals(1, articles.size()); + assertEquals(0, articles.get(0).getAuthors().size()); + articleRepository.delete(articles.get(0)); + assertEquals(TestBookshelfConstants.ARTICLE_COUNT, articleRepository.findAll().size()); + } +} \ No newline at end of file diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/AuthorRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/AuthorRepositoryTest.java new file mode 100644 index 0000000..fcb399b --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/AuthorRepositoryTest.java @@ -0,0 +1,71 @@ +package de.thpeetz.kontor.repository.bookshelf; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.data.bookshelf.Author; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +@Disabled +class AuthorRepositoryTest { + + @Autowired + AuthorRepository authorRepository; + + @Test + @Order(1) + void checkInitialLoad() { + assertEquals(TestBookshelfConstants.AUTHOR_COUNT, authorRepository.findAll().size()); + } + + @Test + @Order(2) + void saveAutor() { + Author author = new Author(); + author.setFirstName(TestBookshelfConstants.AUTHOR_FIRSTNAME); + author.setLastName(TestBookshelfConstants.AUTHOR_LASTNAME); + authorRepository.save(author); + assertEquals(TestBookshelfConstants.AUTHOR_COUNT+1, authorRepository.findAll().size()); + } + + @Test + @Order(3) + void findAuthor() { + Author existingAuthor = authorRepository.findAll().get(0); + assertNotNull(existingAuthor); + Author found = authorRepository.findByFirstNameAndLastName(existingAuthor.getFirstName(), existingAuthor.getLastName()); + assertEquals(existingAuthor, found); + } + + @Test + @Order(4) + void searchAuthor() { + List authors = authorRepository.search("glas"); + assertEquals(1, authors.size()); + assertEquals("Douglas", authors.get(0).getFirstName()); + List authors2 = authorRepository.search("dams"); + assertEquals(1, authors2.size()); + assertEquals("Adams", authors2.get(0).getLastName()); + } + + @Test + @Order(5) + void deleteAuthor() { + Author existingAuthor = authorRepository.findByFirstNameAndLastName(TestBookshelfConstants.AUTHOR_FIRSTNAME, TestBookshelfConstants.AUTHOR_LASTNAME); + assertNotNull(existingAuthor); + authorRepository.delete(existingAuthor); + assertEquals(TestBookshelfConstants.AUTHOR_COUNT, authorRepository.findAll().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/BookAuthorRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/BookAuthorRepositoryTest.java new file mode 100644 index 0000000..0fb3a81 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/BookAuthorRepositoryTest.java @@ -0,0 +1,99 @@ +package de.thpeetz.kontor.repository.bookshelf; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.data.bookshelf.Author; +import de.thpeetz.kontor.data.bookshelf.Book; +import de.thpeetz.kontor.data.bookshelf.BookAuthor; +import de.thpeetz.kontor.data.bookshelf.BookshelfPublisher; + +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@Disabled +class BookAuthorRepositoryTest { + + @Autowired + BookRepository bookRepository; + + @Autowired + AuthorRepository authorRepository; + + @Autowired + BookAuthorRepository bookAuthorRepository; + + @Autowired + BookshelfPublisherRepository bookshelfPublisherRepository; + + @Test + @Order(1) + void saveBookAuthor() { + Author author = new Author(); + author.setFirstName(TestBookshelfConstants.AUTHOR_FIRSTNAME); + author.setLastName(TestBookshelfConstants.AUTHOR_LASTNAME); + Author savedAuthor = authorRepository.save(author); + assertEquals(TestBookshelfConstants.AUTHOR_COUNT+1, authorRepository.findAll().size()); + BookshelfPublisher publisher = new BookshelfPublisher(); + publisher.setName(TestBookshelfConstants.PUBLISHER_NAME); + BookshelfPublisher savedPublisher = bookshelfPublisherRepository.save(publisher); + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT+1, bookshelfPublisherRepository.findAll().size()); + Book book = new Book(); + book.setTitle(TestBookshelfConstants.ARTICLE_TITLE); + book.setIsbn(TestBookshelfConstants.BOOK_ISBN); + book.setPublisher(savedPublisher); + Book savedBook = bookRepository.save(book); + assertEquals(TestBookshelfConstants.BOOK_COUNT+1, bookRepository.findAll().size()); + BookAuthor bookAuthor = new BookAuthor(); + bookAuthor.setBook(savedBook); + bookAuthor.setAuthor(savedAuthor); + //TODO BookAuthor savedBookAuthor = bookAuthorRepository.save(bookAuthor); + assertEquals(TestBookshelfConstants.BOOKAUTHOR_COUNT+1, bookAuthorRepository.findAll().size()); + } + + @Test + @Order(2) + void testFindByBook() { + List bookAuthors = bookAuthorRepository.findAll(); + assertEquals(1, bookAuthors.size()); + Book book = bookAuthors.get(0).getBook(); + assertEquals(1, bookAuthorRepository.findByBook(book).size()); + } + + @Test + @Order(3) + void testFindByAuthor() { + List bookAuthors = bookAuthorRepository.findAll(); + assertEquals(1, bookAuthors.size()); + Author author = bookAuthors.get(0).getAuthor(); + assertEquals(1, bookAuthorRepository.findByAuthor(author).size()); + } + + @Test + @Order(4) + void deleteBookAuthor() { + BookAuthor bookAuthor = bookAuthorRepository.findAll().get(0); + Author author = bookAuthor.getAuthor(); + author.getBookAuthors().remove(bookAuthor); + author = authorRepository.save(author); + Book book = bookAuthor.getBook(); + book.getAuthors().remove(bookAuthor); + BookshelfPublisher publisher = book.getPublisher(); + publisher.getBooks().remove(book); + bookshelfPublisherRepository.save(publisher); + book = bookRepository.save(book); + bookshelfPublisherRepository.delete(publisher); + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT, bookshelfPublisherRepository.findAll().size()); + bookAuthorRepository.delete(bookAuthor); + assertEquals(TestBookshelfConstants.BOOKAUTHOR_COUNT, bookAuthorRepository.findAll().size()); + authorRepository.delete(author); + assertEquals(TestBookshelfConstants.AUTHOR_COUNT, authorRepository.findAll().size()); + bookRepository.delete(book); + assertEquals(TestBookshelfConstants.BOOK_COUNT, bookRepository.findAll().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/BookRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/BookRepositoryTest.java new file mode 100644 index 0000000..3f10de2 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/BookRepositoryTest.java @@ -0,0 +1,90 @@ +package de.thpeetz.kontor.repository.bookshelf; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.data.bookshelf.Book; +import de.thpeetz.kontor.data.bookshelf.BookshelfPublisher; + +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +@Disabled +class BookRepositoryTest { + + @Autowired + BookRepository bookRepository; + + @Autowired + BookshelfPublisherRepository bookshelfPublisherRepository; + + @Test + @Order(1) + void checkInitialLoad(){ + assertEquals(TestBookshelfConstants.BOOK_COUNT, bookRepository.findAll().size()); + } + + @Test + @Order(2) + void saveBook() { + BookshelfPublisher publisher = new BookshelfPublisher(); + publisher.setName(TestBookshelfConstants.PUBLISHER_NAME); + bookshelfPublisherRepository.save(publisher); + Book book = new Book(); + book.setTitle(TestBookshelfConstants.BOOK_TITLE); + book.setIsbn(TestBookshelfConstants.BOOK_ISBN); + book.setPublisher(publisher); + bookRepository.save(book); + assertEquals(TestBookshelfConstants.BOOK_COUNT+1, bookRepository.findAll().size()); + } + + @Test + @Order(3) + void search() { + List books = bookRepository.search(TestBookshelfConstants.BOOK_TITLE.substring(2,5)); + assertEquals(1, books.size()); + assertEquals(1, bookRepository.search(TestBookshelfConstants.BOOK_ISBN.substring(3,7)).size()); + assertEquals(0, bookRepository.search("Article").size()); + } + + @Test + @Order(4) + void findByTitle() { + List books = bookRepository.findByTitle(TestBookshelfConstants.BOOK_TITLE); + assertEquals(1, books.size()); + assertEquals(TestBookshelfConstants.BOOK_ISBN, books.get(0).getIsbn()); + } + + @Test + @Order(5) + void findByTitleIgnoreCase() { + List books = bookRepository.findByTitleIgnoreCase(TestBookshelfConstants.BOOK_TITLE.toLowerCase()); + assertEquals(1, books.size()); + assertEquals(TestBookshelfConstants.BOOK_ISBN, books.get(0).getIsbn()); + } + + @Test + @Order(6) + void findByIsbn() { + List books = bookRepository.findByIsbn(TestBookshelfConstants.BOOK_ISBN); + assertEquals(1, books.size()); + assertEquals(TestBookshelfConstants.BOOK_TITLE, books.get(0).getTitle()); + } + + @Test + @Order(7) + void deleteBook() { + List books = bookRepository.findByIsbn(TestBookshelfConstants.BOOK_ISBN); + Book book = books.get(0); + BookshelfPublisher publisher = book.getPublisher(); + bookshelfPublisherRepository.delete(publisher); + bookRepository.delete(book); + assertEquals(TestBookshelfConstants.BOOK_COUNT, bookRepository.findAll().size()); + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT, bookshelfPublisherRepository.findAll().size()); + } +} \ No newline at end of file diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/BookshelfPublisherRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/BookshelfPublisherRepositoryTest.java new file mode 100644 index 0000000..882c16e --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/bookshelf/BookshelfPublisherRepositoryTest.java @@ -0,0 +1,73 @@ +package de.thpeetz.kontor.repository.bookshelf; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.data.bookshelf.BookshelfPublisher; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +class BookshelfPublisherRepositoryTest { + + @Autowired + private BookshelfPublisherRepository publisherRepository; + + @Test + @Order(1) + void checkInitialLoad() { + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); + } + + @Test + @Order(2) + void savePublisher() { + BookshelfPublisher publisher = new BookshelfPublisher(); + publisher.setName(TestBookshelfConstants.PUBLISHER_NAME); + publisherRepository.save(publisher); + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT + 1, publisherRepository.findAll().size()); + } + + @Test + @Order(3) + void findPublisherByName() { + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT + 1, publisherRepository.findAll().size()); + log.info("Liste der Publisher: {}", publisherRepository.findAll()); + BookshelfPublisher publisher = publisherRepository.findByName(TestBookshelfConstants.PUBLISHER_NAME); + assertNotNull(publisher); + assertEquals(TestBookshelfConstants.PUBLISHER_NAME, publisher.getName()); + BookshelfPublisher notFound = publisherRepository.findByName(TestBookshelfConstants.PUBLISHER_SEARCH); + assertNull(notFound); + List publishers = publisherRepository + .findByNameIgnoreCase(TestBookshelfConstants.PUBLISHER_NAME.toLowerCase()); + assertEquals(1, publishers.size()); + assertEquals(TestBookshelfConstants.PUBLISHER_NAME, publishers.get(0).getName()); + } + + @Test + @Order(4) + void searchPublisher() { + List publishers = publisherRepository.search(TestBookshelfConstants.PUBLISHER_NAME.substring(2, 6)); + assertEquals(1, publishers.size()); + assertEquals(TestBookshelfConstants.PUBLISHER_NAME, publishers.get(0).getName()); + } + + @Test + @Order(5) + void deletePublisher() { + BookshelfPublisher publisher = publisherRepository.findByName(TestBookshelfConstants.PUBLISHER_NAME); + assertNotNull(publisher); + publisherRepository.delete(publisher); + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/ArtistRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/ArtistRepositoryTest.java new file mode 100644 index 0000000..5cf46e5 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/ArtistRepositoryTest.java @@ -0,0 +1,75 @@ +package de.thpeetz.kontor.repository.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import de.thpeetz.kontor.data.comics.Artist; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +class ArtistRepositoryTest { + + private Artist stanLee; + private static final String ARTISTNAME = "Lee, Stan"; + + @Autowired + ArtistRepository artistRepository; + + @BeforeEach + void setupData() { + stanLee = new Artist(); + stanLee.setName(ARTISTNAME); + } + + @Test + @Order(1) + void checkInitialLoad() { + int count = artistRepository.findAll().size(); + assertEquals(5, count); + } + + @Test + @Order(2) + void saveArtist() { + int count = artistRepository.findAll().size(); + artistRepository.save(stanLee); + assertEquals(count+1, artistRepository.findAll().size()); + } + + @Test + @Order(3) + void findArtist() { + List artists = artistRepository.findByNameIgnoreCase("lEE, sTAN"); + assertTrue(artists.size() > 0); + assertEquals(artists.get(0).getName(), stanLee.getName()); + } + + @Test + @Order(4) + void searchArtist() { + List artists = artistRepository.search("Lee"); + assertEquals(1, artists.size()); + assertEquals(ARTISTNAME, artists.get(0).getName()); + List artists2 = artistRepository.search("Stan"); + assertEquals(1, artists2.size()); + assertEquals(ARTISTNAME, artists2.get(0).getName()); + } + + @Test + @Order(5) + void deleteArtist() { + int count = artistRepository.findAll().size(); + Artist artist = artistRepository.findByName(ARTISTNAME); + artistRepository.delete(artist); + assertEquals(count-1, artistRepository.findAll().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/ComicRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/ComicRepositoryTest.java new file mode 100644 index 0000000..647e6f7 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/ComicRepositoryTest.java @@ -0,0 +1,56 @@ +package de.thpeetz.kontor.repository.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; +import java.util.stream.Collectors; + +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.Publisher; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ComicRepositoryTest { + + @Autowired + private ComicRepository comicRepository; + + @Autowired + private PublisherRepository publisherRepository; + + @Test + void testFindByTitle() { + List comics = comicRepository.findByTitle("Emma Frost"); + assertEquals(1, comics.size()); + assertEquals("Emma Frost", comics.get(0).getTitle()); + Publisher publisher = comics.get(0).getPublisher(); + assertEquals("Marvel", publisher.getName()); + } + + @Test + void testFindByTitleIgnoreCase() { + List comics = comicRepository.findByTitleIgnoreCase("x-men"); + assertEquals(1, comics.size()); + assertEquals("X-Men", comics.get(0).getTitle()); + } + @Test + void testFindByTitleAndPublisher() { + Publisher publisher = publisherRepository.findByName("Marvel"); + assertNotNull(publisher); + Comic found = comicRepository.findByTitleAndPublisher("Emma Frost", publisher); + assertNotNull(found); + assertEquals("Emma Frost", found.getTitle()); + assertEquals("Marvel", found.getPublisher().getName()); + + } + + @Test + void testSearch() { + List comics = comicRepository.search("X-men"); + assertEquals(11, comics.size()); + assertTrue(comics.stream().map(comic -> comic.getTitle()).collect(Collectors.toList()).contains("Astonishing X-Men")); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/ComicWorkRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/ComicWorkRepositoryTest.java new file mode 100644 index 0000000..3b01ee0 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/ComicWorkRepositoryTest.java @@ -0,0 +1,87 @@ +package de.thpeetz.kontor.repository.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.data.comics.Artist; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.ComicWork; +import de.thpeetz.kontor.data.comics.Worktype; +import de.thpeetz.kontor.services.ComicService; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +class ComicWorkRepositoryTest { + + @Autowired + private ComicWorkRepository comicWorkRepository; + + @Autowired + private ComicRepository comicRepository; + + @Autowired + private WorktypeRepository worktypeRepository; + + @Autowired + private ArtistRepository artistRepository; + + @Autowired + private ComicService comicService; + + @Test + @Order(1) + void checkInitialLoad() { + int count = comicWorkRepository.findAll().size(); + assertEquals(18, count); + } + + @Test + @Order(2) + void saveComicWork() { + int count = comicWorkRepository.findAll().size(); + Artist artist = artistRepository.findByName("Turner, Michael"); + Worktype worktype = worktypeRepository.findByName("Writer"); + Comic comic = comicRepository.findByTitle("Emma Frost").get(0); + ComicWork comicWork = new ComicWork(); + comicWork.setArtist(artist); + comicWork.setComic(comic); + comicWork.setWorkType(worktype); + comicWorkRepository.save(comicWork); + assertEquals(count + 1, comicWorkRepository.findAll().size()); + } + + @Test + @Order(3) + void findByComicAndArtistAndComicWork() { + assertEquals(19, comicWorkRepository.count()); + Artist artist = artistRepository.findByName("Turner, Michael"); + Worktype worktype = worktypeRepository.findByName("Writer"); + Comic comic = comicRepository.findByTitle("Emma Frost").get(0); + ComicWork comicWork = comicWorkRepository.findbyComicAndArtistAndWorktype(comic, artist, worktype); + assertNotNull(comicWork); + assertEquals(comicWork.getArtist().getName(), artist.getName()); + assertEquals(comicWork.getComic().getTitle(), comic.getTitle()); + assertEquals(comicWork.getWorkType().getName(), worktype.getName()); + ComicWork notFound = comicWorkRepository.findbyComicAndArtistAndWorktype(comic, artist, null); + assertNull(notFound); + } + + @Test + @Order(4) + void deleteComicWork() { + long count = comicWorkRepository.count(); + Artist artist = artistRepository.findByName("Turner, Michael"); + Worktype worktype = worktypeRepository.findByName("Writer"); + Comic comic = comicRepository.findByTitle("Emma Frost").get(0); + ComicWork comicWork = comicWorkRepository.findbyComicAndArtistAndWorktype(comic, artist, worktype); + assertNotNull(comicWork); + comicService.deleteComicWork(comicWork); + assertEquals(count - 1, comicWorkRepository.count()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/IssueRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/IssueRepositoryTest.java new file mode 100644 index 0000000..6e43525 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/IssueRepositoryTest.java @@ -0,0 +1,47 @@ +package de.thpeetz.kontor.repository.comics; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.Issue; +import de.thpeetz.kontor.services.ComicService; + +@SpringBootTest +class IssueRepositoryTest { + + @Autowired + private IssueRepository issueRepository; + + @Autowired + private ComicService comicService; + + @Test + void testFindByComic() { + Comic comic = TestComicConstants.getComicWithIssues(comicService); + List issues = issueRepository.findByComic(comic); + assertEquals(TestComicConstants.BATTLE_POPE_ISSUE_COUNT, issues.size()); + } + + @Test + void testFindByComicAndIssueNumber() { + Comic comic = TestComicConstants.getComicWithIssues(comicService); + Issue issue = issueRepository.findByComicAndIssueNumber(comic, "12"); + assertNotNull(issue); + assertFalse(issue.getIsRead()); + } + + @Test + void testSearch() { + List issues = issueRepository.search("2"); + assertEquals(187, issues.size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/PublisherRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/PublisherRepositoryTest.java new file mode 100644 index 0000000..84beb2c --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/PublisherRepositoryTest.java @@ -0,0 +1,69 @@ +package de.thpeetz.kontor.repository.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.data.comics.Publisher; + +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +class PublisherRepositoryTest { + + @Autowired + private PublisherRepository publisherRepository; + + @Test + @Order(1) + void checkInitialLoad() { + assertEquals(TestComicConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); + } + + @Test + @Order(2) + void savePublisher() { + Publisher publisher = new Publisher(); + publisher.setName(TestComicConstants.PUBLISHER_NAME); + publisherRepository.save(publisher); + assertEquals(TestComicConstants.PUBLISHER_COUNT + 1, publisherRepository.findAll().size()); + } + + @Test + @Order(3) + void findPublisherByName() { + Publisher publisher = publisherRepository.findByName(TestComicConstants.PUBLISHER_NAME); + assertNotNull(publisher); + assertEquals(TestComicConstants.PUBLISHER_NAME, publisher.getName()); + Publisher notFound = publisherRepository.findByName("Cow"); + assertNull(notFound); + List publishers = publisherRepository + .findByNameIgnoreCase(TestComicConstants.PUBLISHER_NAME.toLowerCase()); + assertEquals(1, publishers.size()); + assertEquals(TestComicConstants.PUBLISHER_NAME, publishers.get(0).getName()); + } + + @Test + @Order(4) + void searchPublisher() { + List publishers = publisherRepository.search("Cow"); + assertEquals(1, publishers.size()); + assertEquals("Top Cow Productions", publishers.get(0).getName()); + } + + @Test + @Order(5) + void deletePublisher() { + Publisher publisher = publisherRepository.findByName(TestComicConstants.PUBLISHER_NAME); + assertNotNull(publisher); + publisherRepository.delete(publisher); + assertEquals(TestComicConstants.PUBLISHER_COUNT, publisherRepository.findAll().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/StoryArcRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/StoryArcRepositoryTest.java new file mode 100644 index 0000000..15c535c --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/StoryArcRepositoryTest.java @@ -0,0 +1,47 @@ +package de.thpeetz.kontor.repository.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.StoryArc; +import de.thpeetz.kontor.services.ComicService; + +@SpringBootTest +class StoryArcRepositoryTest { + + @Autowired + private StoryArcRepository storyArcRepository; + + @Autowired + private ComicService comicService; + + @Test + void testSearch() { + List storyArcs = storyArcRepository.search("Learn"); + assertNotNull(storyArcs); + assertEquals(1, storyArcs.size()); + } + + @Test + void findByComic() { + Comic comic = TestComicConstants.getComicWithStoryArcs(comicService); + List storyArcs = storyArcRepository.findByComic(comic); + assertNotNull(storyArcs); + assertEquals(3, storyArcs.size()); + } + + @Test + void findByNameAndComic() { + Comic comic = TestComicConstants.getComicWithStoryArcs(comicService); + StoryArc storyArc = storyArcRepository.findByNameAndComic("Higher Learning", comic); + assertNotNull(storyArc); + assertEquals("Emma Frost", storyArc.getComic().getTitle()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/TradePaperbackRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/TradePaperbackRepositoryTest.java new file mode 100644 index 0000000..e0bf3e2 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/TradePaperbackRepositoryTest.java @@ -0,0 +1,61 @@ +package de.thpeetz.kontor.repository.comics; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.TradePaperback; +import de.thpeetz.kontor.services.ComicService; + +@SpringBootTest +class TradePaperbackRepositoryTest { + + @Autowired + private TradePaperbackRepository tradePaperbackRepository; + + @Autowired + private ComicService comicService; + + @Test + void testSearch() { + List tradePaperbacks = tradePaperbackRepository.search("Dragon"); + assertNotNull(tradePaperbacks); + assertEquals(1, tradePaperbacks.size()); + } + + @Test + void testFindByComic() { + Comic comic = TestComicConstants.getComicWithTradePaperbacks(comicService); + List tradePaperbacks = tradePaperbackRepository.findByComic(comic); + assertNotNull(tradePaperbacks); + assertEquals(TestComicConstants.SOJOURN_TPB_COUNT, tradePaperbacks.size()); + } + + @Test + void testFindByNameAndComic() { + Comic comic = TestComicConstants.getComicWithTradePaperbacks(comicService); + List tradePaperbacks = tradePaperbackRepository + .findByNameAndComic(TestComicConstants.SOJOURN_TPB_NAME, comic); + assertNotNull(tradePaperbacks); + assertTrue(tradePaperbacks.size() > 0); + assertEquals(TestComicConstants.SOJOURN_TPB_COMIC_TITLE, tradePaperbacks.get(0).getComic().getTitle()); + } + + @Test + void testFindByFields() { + Comic comic = TestComicConstants.getComicWithTradePaperbacks(comicService); + TradePaperback tradePaperback = tradePaperbackRepository.findByFields(TestComicConstants.SOJOURN_TPB_NAME, + comic, TestComicConstants.SOJOURN_TPB_START, TestComicConstants.SOJOURN_TPB_END); + assertNotNull(tradePaperback); + assertEquals(TestComicConstants.SOJOURN_TPB_COMIC_TITLE, tradePaperback.getComic().getTitle()); + assertEquals(TestComicConstants.SOJOURN_TPB_END, tradePaperback.getIssueEnd()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/VolumeRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/VolumeRepositoryTest.java new file mode 100644 index 0000000..df87eb5 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/VolumeRepositoryTest.java @@ -0,0 +1,60 @@ +package de.thpeetz.kontor.repository.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.Volume; +import de.thpeetz.kontor.services.ComicService; + +@SpringBootTest +class VolumeRepositoryTest { + + @Autowired + private VolumeRepository volumeRepository; + + @Autowired + private ComicService comicService; + + @Test + void testFindByComic() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + assertEquals(0, comic.getVolumes().size()); + Volume volume = new Volume(); + volume.setName(TestComicConstants.VOLUME_NAME); + volume.setComic(comic); + Volume savedInstance = volumeRepository.save(volume); + assertNotNull(savedInstance); + + List found = volumeRepository.findByComic(comic); + assertEquals(1, found.size()); + + comicService.deleteVolume(found.get(0)); + assertEquals(0, comic.getVolumes().size()); + assertEquals(TestComicConstants.VOLUME_COUNT, volumeRepository.count()); + } + + @Test + void testFindByName() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + assertEquals(0, comic.getVolumes().size()); + Volume volume = new Volume(); + volume.setName(TestComicConstants.VOLUME_NAME); + volume.setComic(comic); + Volume savedInstance = volumeRepository.save(volume); + assertNotNull(savedInstance); + + List found = volumeRepository.findByName(TestComicConstants.VOLUME_NAME); + assertEquals(1, found.size()); + + comicService.deleteVolume(found.get(0)); + assertEquals(0, comic.getVolumes().size()); + assertEquals(TestComicConstants.VOLUME_COUNT, volumeRepository.count()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/WorktypeRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/WorktypeRepositoryTest.java new file mode 100644 index 0000000..c8c7917 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/comics/WorktypeRepositoryTest.java @@ -0,0 +1,42 @@ +package de.thpeetz.kontor.repository.comics; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; +import java.util.stream.Collectors; + +import de.thpeetz.kontor.data.comics.Worktype; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class WorktypeRepositoryTest { + + @Autowired + private WorktypeRepository worktypeRepository; + + @Test + void findWorktypeByName() { + Worktype found = worktypeRepository.findByName("Writer"); + assertNotNull(found); + Worktype notFound = worktypeRepository.findByName("er"); + assertNull(notFound); + } + + @Test + void findWorktypeByNameIgnoreCase() { + List worktypes = worktypeRepository.findByNameIgnoreCase("Writer".toLowerCase()); + assertNotNull(worktypes); + assertEquals(1, worktypes.size()); + assertEquals("Writer", worktypes.get(0).getName()); + } + + @Test + void searchWorktype() { + List worktypes = worktypeRepository.search("er"); + assertEquals(3, worktypes.size()); + assertTrue(worktypes.stream().map(worktype -> worktype.getName()).collect(Collectors.toList()).contains("Writer")); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/CardRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/CardRepositoryTest.java new file mode 100644 index 0000000..54efc87 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/CardRepositoryTest.java @@ -0,0 +1,40 @@ +package de.thpeetz.kontor.repository.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.List; + +import de.thpeetz.kontor.data.tysc.Card; +import de.thpeetz.kontor.data.tysc.CardSet; +import de.thpeetz.kontor.data.tysc.Rooster; +import de.thpeetz.kontor.data.tysc.Vendor; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class CardRepositoryTest { + + @Autowired + private CardRepository cardRepository; + + @Test + void testSearchByFields() { + List cards = cardRepository.findAll(); + Card existingCard = cards.get(3); + Vendor vendor = existingCard.getVendor(); + CardSet cardSet = existingCard.getCardSet(); + Rooster rooster = existingCard.getRooster(); + int cardNumber = existingCard.getCardNumber(); + int year = existingCard.getYear(); + Card card = cardRepository.search(vendor, cardSet, rooster, cardNumber, year); + assertNotNull(card); + } + + @Test + void testSearch() { + assertEquals(2, cardRepository.search("2").size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/CardSetRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/CardSetRepositoryTest.java new file mode 100644 index 0000000..2efb67b --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/CardSetRepositoryTest.java @@ -0,0 +1,44 @@ +package de.thpeetz.kontor.repository.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.data.tysc.CardSet; +import de.thpeetz.kontor.data.tysc.Vendor; + +@SpringBootTest +class CardSetRepositoryTest { + + @Autowired + private CardSetRepository cardSetRepository; + + @Autowired + private VendorRepository vendorRepository; + + @Test + void testFindByName() { + List cardSets = cardSetRepository.findByName(TestTyscConstants.CARDSET_MYSTIQUE_NAME); + assertEquals(1, cardSets.size()); + } + + @Test + void testFindByNameAndVendor() { + Vendor fleer = vendorRepository.findByName(TestTyscConstants.VENDOR_FLEER); + assertNotNull(fleer); + CardSet cardSet = cardSetRepository.findByNameAndVendor(TestTyscConstants.CARDSET_MYSTIQUE_NAME, fleer); + assertNotNull(cardSet); + } + + @Test + void testSearch() { + List cardSets = cardSetRepository.search("SP"); + assertEquals(3, cardSets.size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/FieldPositionRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/FieldPositionRepositoryTest.java new file mode 100644 index 0000000..c3757f8 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/FieldPositionRepositoryTest.java @@ -0,0 +1,61 @@ +package de.thpeetz.kontor.repository.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.data.tysc.FieldPosition; +import de.thpeetz.kontor.data.tysc.Sport; + +@SpringBootTest +class FieldPositionRepositoryTest { + + @Autowired + private FieldPositionRepository fieldPositionRepository; + + @Autowired + private SportRepository sportRepository; + + @Test + void testFindByShortName() { + FieldPosition position = fieldPositionRepository.findByShortName(TestTyscConstants.QUARTERBACK_SHORTNAME); + assertNotNull(position); + assertEquals(TestTyscConstants.QUARTERBACK_NAME, position.getName()); + } + + @Test + void testFindByShortNameAndSport() { + Sport sport = sportRepository.findByName(TestTyscConstants.FOOTBALL_NAME); + FieldPosition position = fieldPositionRepository.findByShortNameAndSport(TestTyscConstants.QUARTERBACK_SHORTNAME, sport); + assertNotNull(position); + assertEquals(TestTyscConstants.QUARTERBACK_NAME, position.getName()); + } + + @Test + void testFindByShortNameIgnoreCase() { + List positions = fieldPositionRepository + .findByShortNameIgnoreCase(TestTyscConstants.QUARTERBACK_SHORTNAME.toLowerCase()); + assertNotNull(positions); + assertEquals(1, positions.size()); + assertEquals(TestTyscConstants.QUARTERBACK_NAME, positions.get(0).getName()); + } + + @Test + void testFindBySport() { + Sport sport = sportRepository.findByName(TestTyscConstants.FOOTBALL_NAME); + List positions = fieldPositionRepository.findBySport(sport); + assertEquals(TestTyscConstants.FOOTBALL_POSITION_COUNT, positions.size()); + } + + @Test + void testSearch() { + List positions = fieldPositionRepository.search("back"); + assertEquals(8, positions.size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/PlayerRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/PlayerRepositoryTest.java new file mode 100644 index 0000000..c15baf6 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/PlayerRepositoryTest.java @@ -0,0 +1,33 @@ +package de.thpeetz.kontor.repository.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; + +import de.thpeetz.kontor.data.tysc.Player; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class PlayerRepositoryTest { + + @Autowired + private PlayerRepository playerRepository; + + @Test + void testFindByFirstNameAndLastName() { + Player existingPlayer = playerRepository.findAll().get(11); + String firstName = existingPlayer.getFirstName(); + String lastName = existingPlayer.getLastName(); + Player found = playerRepository.findByFirstNameAndLastName(firstName, lastName); + assertEquals(existingPlayer.getFullName(), found.getFullName()); + } + + @Test + void testSearch() { + List players = playerRepository.search("can"); + assertEquals(1, players.size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/RoosterRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/RoosterRepositoryTest.java new file mode 100644 index 0000000..631ebae --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/RoosterRepositoryTest.java @@ -0,0 +1,34 @@ +package de.thpeetz.kontor.repository.tysc; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import de.thpeetz.kontor.data.tysc.FieldPosition; +import de.thpeetz.kontor.data.tysc.Player; +import de.thpeetz.kontor.data.tysc.Rooster; +import de.thpeetz.kontor.data.tysc.Team; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class RoosterRepositoryTest { + + @Autowired + private RoosterRepository roosterRepository; + + @Test + void testFindByReferences() { + List roosters = roosterRepository.findAll(); + Rooster existingRooster = roosters.get(4); + Team team = existingRooster.getTeam(); + Player player = existingRooster.getPlayer(); + FieldPosition position = existingRooster.getPosition(); + int year = existingRooster.getYear(); + Rooster rooster = roosterRepository.findByReferences(player, team, position, year); + assertNotNull(rooster); + assertEquals(existingRooster.getId(), rooster.getId()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/SportRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/SportRepositoryTest.java new file mode 100644 index 0000000..e92ca93 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/SportRepositoryTest.java @@ -0,0 +1,41 @@ +package de.thpeetz.kontor.repository.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.data.tysc.Sport; + +@SpringBootTest +class SportRepositoryTest { + + @Autowired + private SportRepository sportRepository; + + @Test + void testFindByName() { + Sport sport = sportRepository.findByName(TestTyscConstants.FOOTBALL_NAME); + assertNotNull(sport); + assertEquals(TestTyscConstants.FOOTBALL_TEAM_COUNT, sport.getTeams().size()); + assertEquals(TestTyscConstants.FOOTBALL_POSITION_COUNT, sport.getPositions().size()); + } + + @Test + void testFindByNameIgnoreCase() { + List sports = sportRepository.findByNameIgnoreCase(TestTyscConstants.FOOTBALL_NAME.toLowerCase()); + assertNotNull(sports); + assertEquals(TestTyscConstants.FOOTBALL_TEAM_COUNT, sports.get(0).getTeams().size()); + } + + @Test + void testSearch() { + List sports = sportRepository.search("ball"); + assertEquals(3, sports.size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/TeamRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/TeamRepositoryTest.java new file mode 100644 index 0000000..ec3232d --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/TeamRepositoryTest.java @@ -0,0 +1,38 @@ +package de.thpeetz.kontor.repository.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.data.tysc.Team; + +@SpringBootTest +class TeamRepositoryTest { + + @Autowired + private TeamRepository teamRepository; + + @Test + void testFindByName() { + Team team = teamRepository.findByName(TestTyscConstants.DOLPHINS_NAME); + assertEquals(TestTyscConstants.DOLPHINS_SHORT, team.getShortName()); + } + + @Test + void testFindByNameIgnoreCase() { + List teams = teamRepository.findByNameIgnoreCase(TestTyscConstants.DOLPHINS_NAME.toLowerCase()); + assertEquals(1, teams.size()); + assertEquals(TestTyscConstants.DOLPHINS_SHORT, teams.get(0).getShortName()); + } + + @Test + void testSearch() { + List teams = teamRepository.search("dol"); + assertEquals(1, teams.size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/VendorRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/VendorRepositoryTest.java new file mode 100644 index 0000000..08276d5 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/repository/tysc/VendorRepositoryTest.java @@ -0,0 +1,42 @@ +package de.thpeetz.kontor.repository.tysc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.data.tysc.Vendor; + +@SpringBootTest +class VendorRepositoryTest { + + @Autowired + private VendorRepository vendorRepository; + + @Test + void testFindByName() { + Vendor vendor = vendorRepository.findByName(TestTyscConstants.TOPPS_NAME); + assertNotNull(vendor); + assertEquals(TestTyscConstants.TOPPS_NAME, vendor.getName()); + } + + @Test + void testFindByNameIgnoreCase() { + List vendors = vendorRepository.findByNameIgnoreCase(TestTyscConstants.TOPPS_NAME.toLowerCase()); + assertNotNull(vendors); + assertEquals(1, vendors.size()); + assertEquals(TestTyscConstants.TOPPS_NAME, vendors.get(0).getName()); + } + + @Test + void testSearch() { + List vendors = vendorRepository.search("pp"); + assertNotNull(vendors); + assertEquals(2, vendors.size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/services/BookshelfServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/services/BookshelfServiceTest.java new file mode 100644 index 0000000..85d257b --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/services/BookshelfServiceTest.java @@ -0,0 +1,103 @@ +package de.thpeetz.kontor.services; + +import de.thpeetz.kontor.constants.TestBookshelfConstants; +import de.thpeetz.kontor.data.bookshelf.Author; +import de.thpeetz.kontor.data.bookshelf.Book; +import de.thpeetz.kontor.data.bookshelf.BookshelfPublisher; + +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +class BookshelfServiceTest { + + @Autowired + private BookshelfService bookshelfService; + + @Test + @Order(1) + void testFindAllPublishers() { + List publishers = bookshelfService.findAllPublishers(null); + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT, publishers.size()); + } + + @Test + @Order(2) + void testSavePublisher() { + BookshelfPublisher publisher = new BookshelfPublisher(); + publisher.setName(TestBookshelfConstants.PUBLISHER_NAME); + bookshelfService.savePublisher(publisher); + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT + 1, bookshelfService.findAllPublishers(null).size()); + } + + @Test + @Order(3) + void testFindPublisherByName() { + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT + 1, bookshelfService.findAllPublishers(null).size()); + BookshelfPublisher publisher = bookshelfService.findPublisherByName(TestBookshelfConstants.PUBLISHER_NAME); + assertNotNull(publisher); + } + + @Test + @Order(4) + void testDeletePublisher() { + List publishers = bookshelfService.findAllPublishers(TestBookshelfConstants.PUBLISHER_NAME); + assertEquals(1, publishers.size()); + bookshelfService.deletePublisher(publishers.get(0)); + assertEquals(TestBookshelfConstants.PUBLISHER_COUNT, bookshelfService.findAllPublishers(null).size()); + } + + @Test + @Order(5) + void testFindAllAuthors() { + assertEquals(TestBookshelfConstants.AUTHOR_COUNT, bookshelfService.findAllAuthors(null).size()); + } + + @Test + @Order(6) + void testSaveAuthor() { + Author author = new Author(); + author.setFirstName(TestBookshelfConstants.AUTHOR_FIRSTNAME); + author.setLastName(TestBookshelfConstants.AUTHOR_LASTNAME); + bookshelfService.saveAuthor(author); + assertEquals(TestBookshelfConstants.AUTHOR_COUNT+1, bookshelfService.findAllAuthors(null).size()); + } + + @Test + @Order(7) + void testDeleteAuthor() { + List authors = bookshelfService.findAllAuthors(TestBookshelfConstants.AUTHOR_FIRSTNAME); + assertEquals(1, authors.size()); + bookshelfService.deleteAuthor(authors.get(0)); + assertEquals(TestBookshelfConstants.AUTHOR_COUNT, bookshelfService.findAllAuthors(null).size()); + } + + @Test + @Order(8) + void findAllBooks() { + assertEquals(TestBookshelfConstants.BOOK_COUNT, bookshelfService.findAllBooks(null).size()); + } + + @Test + @Order(9) + void saveBook() { + assertEquals(TestBookshelfConstants.BOOK_COUNT, bookshelfService.findAllBooks(null).size()); + } + + @Test + @Order(10) + void deleteBook() { + List books = bookshelfService.findAllBooks(null); + assertEquals(0, books.size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/services/CardServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/services/CardServiceTest.java new file mode 100644 index 0000000..e55ec8b --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/services/CardServiceTest.java @@ -0,0 +1,126 @@ +package de.thpeetz.kontor.services; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.data.tysc.Card; +import de.thpeetz.kontor.data.tysc.CardSet; +import de.thpeetz.kontor.data.tysc.Rooster; +import de.thpeetz.kontor.data.tysc.Vendor; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +class CardServiceTest { + + @Autowired + private CardService cardService; + + @Autowired + private SportService sportService; + + @Test + @Order(1) + void testFindAllVendors() { + assertEquals(TestTyscConstants.VENDOR_COUNT, cardService.findAllVendors(null).size()); + assertEquals(2, cardService.findAllVendors("pp").size()); + } + + @Test + @Order(2) + void testSaveVendor() { + Vendor vendor = new Vendor(); + vendor.setName(TestTyscConstants.VENDOR_NAME); + vendor = cardService.saveVendor(vendor); + assertNotNull(vendor); + assertEquals(TestTyscConstants.VENDOR_COUNT + 1, cardService.findAllVendors(null).size()); + } + + @Test + @Order(3) + void testDeleteVendor() { + List vendors = cardService.findAllVendors(TestTyscConstants.VENDOR_NAME); + assertEquals(1, vendors.size()); + Vendor vendor = vendors.get(0); + cardService.deleteVendor(vendor); + assertEquals(TestTyscConstants.VENDOR_COUNT, cardService.findAllVendors(null).size()); + } + + @Test + @Order(4) + void testFindAllCardSets() { + assertEquals(TestTyscConstants.CARDSET_COUNT, cardService.findAllCardSets(null).size()); + assertEquals(1, cardService.findAllCardSets("Ultra").size()); + } + + @Test + @Order(5) + void testSaveCardSet() { + List vendors = cardService.findAllVendors(TestTyscConstants.VENDOR_FLEER); + assertEquals(1, vendors.size()); + Vendor vendor = vendors.get(0); + CardSet cardSet = new CardSet(); + cardSet.setName(TestTyscConstants.CARDSET_NAME); + cardSet.setVendor(vendor); + cardSet.setInsertSet(false); + cardSet.setParallelSet(false); + cardService.saveCardSet(cardSet); + assertEquals(TestTyscConstants.CARDSET_COUNT + 1, cardService.findAllCardSets(null).size()); + } + + @Test + @Order(6) + void testDeleteCardSet() { + List cardSets = cardService.findAllCardSets(TestTyscConstants.CARDSET_NAME); + assertEquals(1, cardSets.size()); + CardSet cardSet = cardSets.get(0); + cardService.deleteCardSet(cardSet); + assertEquals(TestTyscConstants.CARDSET_COUNT, cardService.findAllCardSets(null).size()); + } + + @Test + @Order(7) + void testFindAllCards() { + assertEquals(TestTyscConstants.CARD_COUNT, cardService.findAllCards(null).size()); + assertEquals(1, cardService.findAllCards("112").size()); + } + + @Test + @Order(8) + void testSaveCard() { + List vendors = cardService.findAllVendors(TestTyscConstants.VENDOR_FLEER); + assertEquals(1, vendors.size()); + Vendor vendor = vendors.get(0); + List cardSets = cardService.findAllCardSets(TestTyscConstants.CARDSET_MYSTIQUE_NAME); + assertEquals(3, cardSets.size()); + CardSet cardSet = cardSets.get(0); + List roosters = sportService.findAllRoosters(); + Rooster rooster = roosters.get(0); + Card card = new Card(); + card.setCardNumber(TestTyscConstants.CARD_CARDNUMBER); + card.setCardSet(cardSet); + card.setVendor(vendor); + card.setRooster(rooster); + card.setYear(TestTyscConstants.CARD_YEAR); + cardService.saveCard(card); + assertEquals(TestTyscConstants.CARD_COUNT + 1, cardService.findAllCards(null).size()); + } + + @Test + @Order(9) + void testDeleteCard() { + List cards = cardService.findAllCards(TestTyscConstants.CARD_CARDNUMBER.toString()); + assertEquals(1, cards.size()); + Card card = cards.get(0); + cardService.deleteCard(card); + assertEquals(TestTyscConstants.CARD_COUNT, cardService.findAllCards(null).size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/services/ComicServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/services/ComicServiceTest.java new file mode 100644 index 0000000..8dcc2ae --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/services/ComicServiceTest.java @@ -0,0 +1,348 @@ +package de.thpeetz.kontor.services; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestComicConstants; +import de.thpeetz.kontor.data.comics.Artist; +import de.thpeetz.kontor.data.comics.Comic; +import de.thpeetz.kontor.data.comics.ComicWork; +import de.thpeetz.kontor.data.comics.Issue; +import de.thpeetz.kontor.data.comics.Publisher; +import de.thpeetz.kontor.data.comics.StoryArc; +import de.thpeetz.kontor.data.comics.TradePaperback; +import de.thpeetz.kontor.data.comics.Volume; +import de.thpeetz.kontor.data.comics.Worktype; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +class ComicServiceTest { + + //TODO private static final Logger log = LoggerFactory.getLogger(ComicServiceTest.class); + @Autowired + private ComicService comicService; + + @Test + @Order(1) + void testFindAllArtists() { + assertEquals(TestComicConstants.ARTIST_COUNT, comicService.findAllArtists(null).size()); + assertEquals(1, comicService.findAllArtists("Turn").size()); + } + + @Test + @Order(1) + void testFindArtistByName() { + assertNull(comicService.findArtistByName("Lee, Stan")); + Artist artist = comicService.findArtistByName("Turner, Michael"); + assertNotNull(artist); + assertNotNull(artist.getComicWorks()); + assertFalse(artist.getComicWorks().isEmpty()); + } + + @Test + @Order(2) + void testSaveArtist() { + Artist artist = new Artist(); + artist.setName(TestComicConstants.ARTIST_NAME); + comicService.saveArtist(artist); + assertEquals(TestComicConstants.ARTIST_COUNT + 1, comicService.findAllArtists(null).size()); + } + + @Test + @Order(3) + void testDeleteArtist() { + List artists = comicService.findAllArtists(TestComicConstants.ARTIST_NAME); + assertEquals(1, artists.size()); + comicService.deleteArtist(artists.get(0)); + assertEquals(TestComicConstants.ARTIST_COUNT, comicService.findAllArtists(null).size()); + } + + @Test + @Order(4) + void testFindAllPublishers() { + assertEquals(TestComicConstants.PUBLISHER_COUNT, comicService.findAllPublishers(null).size()); + assertEquals(1, comicService.findAllPublishers("Cow").size()); + } + + @Test + @Order(4) + void testFindPublisherByName() { + Publisher publisher = comicService.findPublisherByName("Marvel"); + assertNotNull(publisher); + assertNotNull(publisher.getComics()); + assertEquals(TestComicConstants.MARVEL_COMIC_COUNT, publisher.getComics().size()); + assertNull(comicService.findPublisherByName(TestComicConstants.PUBLISHER_NAME)); + } + + @Test + @Order(5) + void testSavePublisher() { + Publisher publisher = new Publisher(); + publisher.setName(TestComicConstants.PUBLISHER_NAME); + comicService.savePublisher(publisher); + assertEquals(TestComicConstants.PUBLISHER_COUNT + 1, comicService.findAllPublishers(null).size()); + } + + @Test + @Order(6) + void testDeletePublisher() { + List publishers = comicService.findAllPublishers(TestComicConstants.PUBLISHER_NAME); + assertEquals(1, publishers.size()); + comicService.deletePublisher(publishers.get(0)); + assertEquals(TestComicConstants.PUBLISHER_COUNT, comicService.findAllPublishers(null).size()); + } + + @Test + @Order(7) + void testFindAllWorktypes() { + assertEquals(TestComicConstants.WORKTYPE_COUNT, comicService.findAllWorktypes(null).size()); + assertEquals(1, comicService.findAllWorktypes("ite").size()); + } + + @Test + @Order(7) + void testFindWorktypeByName() { + Worktype worktype = comicService.findWorktypeByName("Writer"); + assertNotNull(worktype); + assertNotNull(worktype.getComicWorks()); + assertFalse(worktype.getComicWorks().isEmpty()); + worktype = comicService.findWorktypeByName("Inker"); + assertNotNull(worktype); + assertNotNull(worktype.getComicWorks()); + assertTrue(worktype.getComicWorks().isEmpty()); + assertNull(comicService.findWorktypeByName(TestComicConstants.WORKTYPE_NAME)); + } + + @Test + @Order(8) + void testSaveWorktype() { + Worktype worktype = new Worktype(); + worktype.setName(TestComicConstants.WORKTYPE_NAME); + comicService.saveWorktype(worktype); + assertEquals(TestComicConstants.WORKTYPE_COUNT + 1, comicService.findAllWorktypes(null).size()); + } + + @Test + @Order(9) + void testDeleteWorktype() { + List worktypes = comicService.findAllWorktypes(TestComicConstants.WORKTYPE_NAME); + assertEquals(1, worktypes.size()); + comicService.deleteWorktype(worktypes.get(0)); + assertEquals(TestComicConstants.WORKTYPE_COUNT, comicService.findAllWorktypes(null).size()); + } + + @Test + @Order(10) + void testFindComicByTitle() { + assertNull(comicService.findComicByTitle(null)); + assertNotNull(comicService.findComicByTitle("Danger Girl")); + assertNull(comicService.findComicByTitle("x-men")); + } + + @Test + @Order(11) + void testSaveComic() { + Publisher marvel = comicService.findAllPublishers("Marvel").get(0); + Comic comic = new Comic(); + comic.setTitle(TestComicConstants.COMIC_TITLE); + comic.setPublisher(marvel); + comicService.saveComic(comic); + assertEquals(TestComicConstants.COMIC_COUNT + 1, comicService.findAllComics(null).size()); + } + + @Test + @Order(12) + void testDeleteComic() { + assertEquals(TestComicConstants.COMIC_COUNT + 1, comicService.findAllComics(null).size()); + List comics = comicService.findAllComics(TestComicConstants.COMIC_TITLE); + assertEquals(1, comics.size()); + Comic comic = comicService.findComicByTitle(TestComicConstants.COMIC_TITLE); + assertNotNull(comic); + comicService.deleteComic(comic); + Publisher marvel = comicService.findPublisherByName("Marvel"); + assertNotNull(marvel.getComics()); + assertEquals(TestComicConstants.MARVEL_COMIC_COUNT, marvel.getComics().size()); + assertEquals(0, comicService.findAllComics(TestComicConstants.COMIC_TITLE).size()); + assertEquals(TestComicConstants.COMIC_COUNT, comicService.findAllComics(null).size()); + } + + @Test + @Order(13) + void testFindAllIssues() { + assertEquals(TestComicConstants.ISSUE_COUNT, comicService.findAllIssues().size()); + } + + @Test + @Order(14) + void testFindAllIssuesForComic() { + Comic comic = TestComicConstants.getComicWithIssues(comicService); + List issues = comicService.findAllIssuesForComic(comic); + assertEquals(12, issues.size()); + } + + @Test + @Order(15) + void testSaveIssue() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + Issue issue = new Issue(); + issue.setComic(comic); + issue.setIssueNumber(TestComicConstants.ISSUE_ISSUENUMBER); + comicService.saveIssue(issue); + assertEquals(TestComicConstants.ISSUE_COUNT + 1, comicService.findAllIssues().size()); + comic = TestComicConstants.getComicWithoutReferences(comicService); + assertNotNull(comic.getIssues()); + assertEquals(1, comic.getIssues().size()); + } + + @Test + @Order(16) + void testDeleteIssue() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + List issues = comicService.findAllIssuesForComic(comic); + assertEquals(1, issues.size()); + comicService.deleteIssue(issues.get(0)); + assertEquals(TestComicConstants.ISSUE_COUNT, comicService.findAllIssues().size()); + } + + @Test + @Order(17) + void testFindAllTradePaperbacks() { + assertEquals(TestComicConstants.TRADEPAPERBACK_COUNT, comicService.findAllTradePaperbacks(null).size()); + assertEquals(7, comicService.findAllTradePaperbacks("of").size()); + } + + @Test + @Order(18) + void testSaveTradePaperBack() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + TradePaperback tradePaperback = new TradePaperback(); + tradePaperback.setComic(comic); + tradePaperback.setName(TestComicConstants.TRADEPAPERBACK_NAME); + comicService.saveTradePaperBack(tradePaperback); + assertEquals(TestComicConstants.TRADEPAPERBACK_COUNT + 1, comicService.findAllTradePaperbacks(null).size()); + } + + @Test + @Order(19) + void testDeleteTradePaperBack() { + List tradePaperbacks = comicService.findAllTradePaperbacks(TestComicConstants.TRADEPAPERBACK_NAME); + assertEquals(1, tradePaperbacks.size()); + comicService.deleteTradePaperBack(tradePaperbacks.get(0)); + assertEquals(TestComicConstants.TRADEPAPERBACK_COUNT, comicService.findAllTradePaperbacks(null).size()); + } + + @Test + @Order(20) + void testFindAllStoryArcs() { + assertEquals(TestComicConstants.STORYARC_COUNT, comicService.findAllStoryArcs().size()); + } + + @Test + @Order(21) + void testFindAllStoryArcsForComic() { + assertEquals(TestComicConstants.STORYARC_COUNT, comicService.findAllStoryArcsForComic(null).size()); + Comic comic = TestComicConstants.getComicWithStoryArcs(comicService); + assertEquals(3, comicService.findAllStoryArcsForComic(comic).size()); + } + + @Test + @Order(22) + void testSaveStoryArc() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + StoryArc storyArc = new StoryArc(); + storyArc.setName(TestComicConstants.STORYARC_NAME); + storyArc.setComic(comic); + comicService.saveStoryArc(storyArc); + assertEquals(TestComicConstants.STORYARC_COUNT + 1, comicService.findAllStoryArcs().size()); + } + + @Test + @Order(23) + void testDeleteStoryArc() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + List storyArcs = comicService.findAllStoryArcsForComic(comic); + assertEquals(1, storyArcs.size()); + comicService.deleteStoryArc(storyArcs.get(0)); + assertEquals(TestComicConstants.STORYARC_COUNT, comicService.findAllStoryArcs().size()); + } + + @Test + @Order(24) + void testFindAllVolumes() { + assertEquals(TestComicConstants.VOLUME_COUNT, comicService.findAllVolumes().size()); + } + + @Test + @Order(25) + void testSaveVolume() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + Volume volume = new Volume(); + volume.setName(TestComicConstants.VOLUME_NAME); + volume.setComic(comic); + comicService.saveVolume(volume); + assertEquals(TestComicConstants.VOLUME_COUNT + 1, comicService.findAllVolumes().size()); + } + + @Test + @Order(26) + void testFindAllVolumesForComic() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + List volumes = comicService.findAllVolumesForComic(comic); + assertEquals(1, volumes.size()); + } + + @Test + @Order(27) + void testDeleteVolume() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + List volumes = comicService.findAllVolumesForComic(comic); + comicService.deleteVolume(volumes.get(0)); + assertEquals(TestComicConstants.VOLUME_COUNT, comicService.findAllVolumes().size()); + } + + @Test + @Order(28) + void testFindAllComicWorks() { + assertEquals(TestComicConstants.COMICWORK_COUNT, comicService.findAllComicWorks().size()); + } + + @Test + @Order(29) + void testSaveComicWork() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + Artist artist = TestComicConstants.getArtistWithoutReferences(comicService); + Worktype worktype = TestComicConstants.getWorktypeWithoutReferences(comicService); + ComicWork comicWork = new ComicWork(); + comicWork.setComic(comic); + comicWork.setArtist(artist); + comicWork.setWorkType(worktype); + comicService.saveComicWork(comicWork); + assertEquals(TestComicConstants.COMICWORK_COUNT + 1, comicService.findAllComicWorks().size()); + } + + @Test + @Order(30) + void testDeleteComicWork() { + Comic comic = TestComicConstants.getComicWithoutReferences(comicService); + Artist artist = TestComicConstants.getArtistWithoutReferences(comicService); + Worktype worktype = TestComicConstants.getWorktypeWithoutReferences(comicService); + List comicWorks = comic.getComicWorks(); + assertNotNull(comicWorks); + assertNotNull(artist.getComicWorks()); + assertNotNull(worktype.getComicWorks()); + assertEquals(1, comicWorks.size()); + assertEquals(1, artist.getComicWorks().size()); + assertEquals(1, worktype.getComicWorks().size()); + ComicWork comicWork = comicWorks.get(0); + comicService.deleteComicWork(comicWork); + assertEquals(TestComicConstants.COMICWORK_COUNT, comicService.findAllComicWorks().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/services/MediaArticleServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/services/MediaArticleServiceTest.java new file mode 100644 index 0000000..c3c8b90 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/services/MediaArticleServiceTest.java @@ -0,0 +1,50 @@ +package de.thpeetz.kontor.services; + +import de.thpeetz.kontor.constants.TestMediaConstants; +import de.thpeetz.kontor.data.media.MediaArticle; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +@Slf4j +@SpringBootTest +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +class MediaArticleServiceTest { + + @Autowired + MediaArticleService mediaArticleService; + + @Test + @Order(1) + void findAllMediaArticles() { + assertTrue(mediaArticleService.findAllMediaArticles(null).isEmpty()); + } + + @Test + @Order(2) + void saveMediaArticle() { + int mediaArticleCount = mediaArticleService.findAllMediaArticles(null).size(); + MediaArticle mediaArticle = new MediaArticle(); + mediaArticle.setUrl(TestMediaConstants.URL); + mediaArticleService.saveMediaArticle(mediaArticle); + assertEquals(++mediaArticleCount, mediaArticleService.findAllMediaArticles(null).size()); + } + + @Test + @Order(3) + void deleteMediaArticle() { + int mediaArticleCount = mediaArticleService.findAllMediaArticles(null).size(); + List mediaArticleList = mediaArticleService.findAllMediaArticles(TestMediaConstants.URL); + assertEquals(1, mediaArticleService.findAllMediaArticles(null).size()); + mediaArticleService.deleteMediaArticle(mediaArticleList.get(0)); + assertEquals(--mediaArticleCount, mediaArticleService.findAllMediaArticles(null).size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/services/MediaFileServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/services/MediaFileServiceTest.java new file mode 100644 index 0000000..6ac9392 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/services/MediaFileServiceTest.java @@ -0,0 +1,52 @@ +package de.thpeetz.kontor.services; + +import de.thpeetz.kontor.constants.TestMediaConstants; +import de.thpeetz.kontor.data.media.MediaFile; +import de.thpeetz.kontor.views.common.SearchFilter; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class MediaFileServiceTest { + + @Autowired + private MediaFileService mediaFileService; + + @Test + @Order(1) + void testFindAllMediaFiles() { + assertTrue(mediaFileService.findAllMediaFiles(null).isEmpty()); + } + + @Test + @Order(2) + void testSaveMediaFile() { + int mediaFileCount = mediaFileService.findAllMediaFiles(null).size(); + MediaFile mediaFile = new MediaFile(); + mediaFile.setUrl(TestMediaConstants.URL); + mediaFileService.saveMediaFile(mediaFile); + assertEquals(mediaFileCount +1, mediaFileService.findAllMediaFiles(null).size()); + } + + @Test + @Order(3) + void testDeleteMediaFile() { + int mediaFileCount = mediaFileService.findAllMediaFiles(null).size(); + SearchFilter searchFilter = new SearchFilter(); + searchFilter.setSearchTerm(TestMediaConstants.URL); + List mediaFileList = mediaFileService.findAllMediaFiles(searchFilter); + assertEquals(1, mediaFileList.size()); + mediaFileService.deleteMediaFile(mediaFileList.get(0)); + assertEquals(--mediaFileCount, mediaFileService.findAllMediaFiles(null).size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/services/MediaVideoServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/services/MediaVideoServiceTest.java new file mode 100644 index 0000000..aa73009 --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/services/MediaVideoServiceTest.java @@ -0,0 +1,47 @@ +package de.thpeetz.kontor.services; + +import de.thpeetz.kontor.constants.TestMediaConstants; +import de.thpeetz.kontor.data.media.MediaVideo; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Slf4j +@SpringBootTest +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class MediaVideoServiceTest { + + @Autowired + private MediaVideoService mediaVideoService; + + @Test + void findAllMediaVideos() { + assertTrue(mediaVideoService.findAllMediaVideos(null).isEmpty()); + } + + @Test + void saveMediaVideo() { + int mediaVideoCount = mediaVideoService.findAllMediaVideos(null).size(); + MediaVideo mediaVideo = new MediaVideo(); + mediaVideo.setUrl(TestMediaConstants.URL); + mediaVideoService.saveMediaVideo(mediaVideo); + assertEquals(++mediaVideoCount, mediaVideoService.findAllMediaVideos(null).size()); + } + + @Test + void deleteMediaVideo() { + int mediaVideoCount = mediaVideoService.findAllMediaVideos(null).size(); + List mediaVideoList = mediaVideoService.findAllMediaVideos(TestMediaConstants.URL); + assertEquals(1, mediaVideoList.size()); + mediaVideoService.deleteMediaVideo(mediaVideoList.get(0)); + assertEquals(--mediaVideoCount, mediaVideoService.findAllMediaVideos(null).size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/services/SportServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/services/SportServiceTest.java new file mode 100644 index 0000000..c82415d --- /dev/null +++ b/kontor-spring/src/test/java/de/thpeetz/kontor/services/SportServiceTest.java @@ -0,0 +1,200 @@ +package de.thpeetz.kontor.services; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import de.thpeetz.kontor.constants.TestTyscConstants; +import de.thpeetz.kontor.data.tysc.FieldPosition; +import de.thpeetz.kontor.data.tysc.Player; +import de.thpeetz.kontor.data.tysc.Rooster; +import de.thpeetz.kontor.data.tysc.Sport; +import de.thpeetz.kontor.data.tysc.Team; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +class SportServiceTest { + + @Autowired + private SportService sportService; + + + @Test + @Order(1) + void testFindAllSports() { + List sports = sportService.findAllSports(null); + assertEquals(TestTyscConstants.SPORT_COUNT, sports.size()); + assertEquals(3, sportService.findAllSports("ball").size()); + } + + @Test + @Order(2) + void testSaveSport() { + Sport sport = new Sport(); + sport.setName(TestTyscConstants.SPORT_NAME); + sport = sportService.saveSport(sport); + assertNotNull(sport); + assertEquals(TestTyscConstants.SPORT_COUNT+1, sportService.findAllSports(null).size()); + } + + @Test + @Order(3) + void testDeleteSport() { + List sports = sportService.findAllSports(TestTyscConstants.SPORT_NAME); + assertEquals(1, sports.size()); + Sport sport = sports.get(0); + sportService.deleteSport(sport); + assertEquals(TestTyscConstants.SPORT_COUNT, sportService.findAllSports(null).size()); + } + + @Test + @Order(4) + void testFindAllPlayers() { + assertEquals(TestTyscConstants.PLAYER_COUNT, sportService.findAllPlayers(null).size()); + assertEquals(TestTyscConstants.PLAYER_CHRIS_COUNT, sportService.findAllPlayers(TestTyscConstants.PLAYER_CHRIS_NAME).size()); + } + + @Test + @Order(5) + void testSavePlayer() { + Player player = new Player(); + player.setFirstName(TestTyscConstants.PLAYER_FIRSTNAME); + player.setLastName(TestTyscConstants.PLAYER_LASTNAME); + player = sportService.savePlayer(player); + assertNotNull(player); + } + + @Test + @Order(6) + void testDeletePlayer() { + List players = sportService.findAllPlayers(TestTyscConstants.PLAYER_LASTNAME); + assertEquals(1, players.size()); + Player player = players.get(0); + sportService.deletePlayer(player); + assertEquals(TestTyscConstants.PLAYER_COUNT, sportService.findAllPlayers(null).size()); + } + + + @Test + @Order(7) + void testFindAllPositions() { + assertEquals(TestTyscConstants.POSITION_COUNT, sportService.findAllPositions(null).size()); + assertEquals(TestTyscConstants.POSITION_CENTER_COUNT, sportService.findAllPositions(TestTyscConstants.POSITION_CENTER).size()); + } + + @Test + @Order(8) + void testFindAllPositionsForSport() { + List sports = sportService.findAllSports(TestTyscConstants.FOOTBALL_NAME); + assertEquals(1, sports.size()); + Sport football = sports.get(0); + assertEquals(TestTyscConstants.FOOTBALL_POSITION_COUNT, sportService.findAllPositionsForSport(football).size()); + } + + @Test + @Order(9) + void testSavePosition() { + List sports = sportService.findAllSports(TestTyscConstants.FOOTBALL_NAME); + Sport football = sports.get(0); + FieldPosition position = new FieldPosition(); + position.setSport(football); + position.setName(TestTyscConstants.POSITION_NAME); + position.setShortName(TestTyscConstants.POSITION_SHORTNAME); + sportService.savePosition(position); + assertEquals(TestTyscConstants.POSITION_COUNT+1, sportService.findAllPositions(null).size()); + } + + @Test + @Order(10) + void testDeletePosition() { + List positions = sportService.findAllPositions(TestTyscConstants.POSITION_NAME); + assertEquals(1, positions.size()); + FieldPosition position = positions.get(0); + sportService.deletePosition(position); + assertEquals(TestTyscConstants.POSITION_COUNT, sportService.findAllPositions(null).size()); + } + + @Test + @Order(11) + void testFindAllTeams() { + assertEquals(TestTyscConstants.TEAM_COUNT, sportService.findAllTeams(null).size()); + assertEquals(1, sportService.findAllTeams("sharks").size()); + } + + @Test + @Order(12) + void testSaveTeam() { + List sports = sportService.findAllSports(TestTyscConstants.FOOTBALL_NAME); + Sport football = sports.get(0); + Team team = new Team(); + team.setSport(football); + team.setName(TestTyscConstants.TEAM_NAME); + team.setShortName(TestTyscConstants.TEAM_SHORTNAME); + sportService.saveTeam(team); + assertEquals(TestTyscConstants.TEAM_COUNT+1, sportService.findAllTeams(null).size()); + } + + @Test + @Order(13) + void testDeleteTeam() { + List teams = sportService.findAllTeams(TestTyscConstants.TEAM_NAME); + assertEquals(1, teams.size()); + Team team = teams.get(0); + sportService.deleteTeam(team); + assertEquals(TestTyscConstants.TEAM_COUNT, sportService.findAllTeams(null).size()); + } + + @Test + @Order(14) + void testFindAllRoosters() { + assertEquals(TestTyscConstants.ROOSTER_COUNT, sportService.findAllRoosters().size()); + } + + @Test + @Order(15) + void testFindRoosterByFields() { + List roosters = sportService.findAllRoosters(); + Rooster existingRooster = roosters.get(4); + Team team = existingRooster.getTeam(); + Player player = existingRooster.getPlayer(); + FieldPosition position = existingRooster.getPosition(); + int year = existingRooster.getYear(); + Rooster rooster = sportService.findRoosterByFields(team, player, position, year); + assertNotNull(rooster); + assertEquals(existingRooster.getId(), rooster.getId()); + } + + @Test + @Order(16) + void testSaveRooster() { + Rooster rooster = new Rooster(); + Player player = sportService.findAllPlayers(TestTyscConstants.PLAYER_CHRIS_NAME).get(0); + rooster.setPlayer(player); + Team team = sportService.findAllTeams(TestTyscConstants.DOLPHINS_NAME).get(0); + rooster.setTeam(team); + FieldPosition position = sportService.findAllPositions(TestTyscConstants.QUARTERBACK_NAME).get(0); + rooster.setPosition(position); + rooster.setYear(TestTyscConstants.ROOSTER_YEAR); + sportService.saveRooster(rooster); + assertEquals(TestTyscConstants.ROOSTER_COUNT+1, sportService.findAllRoosters().size()); + } + + @Test + @Order(17) + void testDeleteRooster() { + Team team = sportService.findAllTeams(TestTyscConstants.DOLPHINS_NAME).get(0); + Player player = sportService.findAllPlayers(TestTyscConstants.PLAYER_CHRIS_NAME).get(0); + FieldPosition position = sportService.findAllPositions(TestTyscConstants.QUARTERBACK_NAME).get(0); + Rooster rooster = sportService.findRoosterByFields(team, player, position, TestTyscConstants.ROOSTER_YEAR); + assertNotNull(rooster); + sportService.deleteRooster(rooster); + assertEquals(TestTyscConstants.ROOSTER_COUNT, sportService.findAllRoosters().size()); + } +} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/TestConstants.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/TestConstants.java deleted file mode 100644 index a05c1dd..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/TestConstants.java +++ /dev/null @@ -1,39 +0,0 @@ -package de.thpeetz.kontor.tysc; - -public class TestConstants { - - public static final Integer CARD_COUNT = 10; - public static final Integer CARD_CARDNUMBER = 999; - public static final Integer CARD_YEAR = 2000; - public static final Integer CARDSET_COUNT = 15; - public static final Integer FOOTBALL_TEAM_COUNT = 33; - public static final Integer FOOTBALL_POSITION_COUNT = 25; - public static final Integer PLAYER_COUNT = 38; - public static final Integer PLAYER_CHRIS_COUNT = 3; - public static final Integer POSITION_COUNT = 44; - public static final Integer POSITION_CENTER_COUNT = 3; - public static final Integer ROOSTER_COUNT = 11; - public static final Integer ROOSTER_YEAR = 1900; - public static final Integer SPORT_COUNT = 4; - public static final Integer TEAM_COUNT = 122; - public static final Integer VENDOR_COUNT = 9; - public static final String CARDSET_NAME = "CardSet"; - public static final String CARDSET_MYSTIQUE_NAME = "Mystique"; - public static final String DOLPHINS_NAME = "Miami Dolphins"; - public static final Object DOLPHINS_SHORT = "Dolphins"; - public static final String FOOTBALL_NAME = "Football"; - public static final String PLAYER_FIRSTNAME = "FirstName"; - public static final String PLAYER_LASTNAME = "LastName"; - public static final String PLAYER_CHRIS_NAME = "Chris"; - public static final String POSITION_CENTER = "Center"; - public static final String POSITION_NAME = "Position"; - public static final String POSITION_SHORTNAME = "POS"; - public static final String QUARTERBACK_NAME = "Quarterback"; - public static final String QUARTERBACK_SHORTNAME = "QB"; - public static final String SPORT_NAME = "Sport"; - public static final String TEAM_NAME = "Musterstadt Team"; - public static final String TEAM_SHORTNAME = "Team"; - public static final String TOPPS_NAME = "Topps"; - public static final String VENDOR_FLEER = "Fleer"; - public static final String VENDOR_NAME = "Vendor"; -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/CardSetTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/CardSetTest.java deleted file mode 100644 index a5699d6..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/CardSetTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.tysc.TestConstants; -import de.thpeetz.kontor.tysc.services.CardService; - -@SpringBootTest -class CardSetTest { - - @Autowired - private CardService cardService; - - @Test - void checkInitialDataLoad() { - assertEquals(TestConstants.CARDSET_COUNT, cardService.findAllCardSets(null).size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/CardTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/CardTest.java deleted file mode 100644 index 0d71d8d..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/CardTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.tysc.TestConstants; -import de.thpeetz.kontor.tysc.services.CardService; - -@SpringBootTest -class CardTest { - - @Autowired - private CardService cardService; - - @Test - void checkInitialDataLoad() { - assertEquals(TestConstants.CARD_COUNT, cardService.findAllCards(null).size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/FieldPositionTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/FieldPositionTest.java deleted file mode 100644 index 0853371..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/FieldPositionTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import static org.junit.jupiter.api.Assertions.*; - -import de.thpeetz.kontor.tysc.repository.FieldPositionRepository; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.tysc.TestConstants; - -@SpringBootTest -class FieldPositionTest { - - @Autowired - private FieldPositionRepository fieldPositionRepository; - - @Test - void checkInitialDataLoad() { - assertEquals(Integer.toUnsignedLong(TestConstants.POSITION_COUNT), fieldPositionRepository.count()); - } - - @Test - void throwExceptionWhenPositionSavedWithEmptyName() { - FieldPosition fieldPosition = new FieldPosition(); - assertThrows(TransactionSystemException.class, () -> { - fieldPositionRepository.save(fieldPosition); - }); - fieldPosition.setName("Position"); - assertThrows(TransactionSystemException.class, () -> { - fieldPositionRepository.save(fieldPosition); - }); - } - - @Test - void throwExceptionWhenPositionSavedWithExistingName() { - FieldPosition existingFieldPosition = fieldPositionRepository.findAll().get(11); - FieldPosition fieldPosition = new FieldPosition(); - fieldPosition.setName(existingFieldPosition.getName()); - assertThrows(TransactionSystemException.class, () -> { - fieldPositionRepository.save(fieldPosition); - }); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/PlayerTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/PlayerTest.java deleted file mode 100644 index 4941f6f..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/PlayerTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.tysc.repository.PlayerRepository; -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.tysc.TestConstants; - -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -class PlayerTest { - - @Autowired - private PlayerRepository playerRepository; - - @Test - @Order(1) - void checkInitialDataLoad() { - List players = playerRepository.findAll(); - assertEquals(TestConstants.PLAYER_COUNT, players.size()); - } - - @Test - @Order(2) - void throwExceptionWhenPlayerSavedWithEmptyName() { - Player player = new Player(); - assertThrows(TransactionSystemException.class, () -> { - playerRepository.save(player); - }); - } - - @Test - @Order(3) - void throwExceptionWhenPlayerSavedWithExistingName() { - Player existingPlayer = playerRepository.findAll().get(10); - assertNotNull(existingPlayer); - Player player = new Player(); - player.setFirstName(existingPlayer.getFirstName()); - player.setLastName(existingPlayer.getLastName()); - assertThrows(DataIntegrityViolationException.class, () -> { - playerRepository.save(player); - }); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/RoosterTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/RoosterTest.java deleted file mode 100644 index c0e2e6c..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/RoosterTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.tysc.repository.RoosterRepository; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; - -import de.thpeetz.kontor.tysc.TestConstants; - -@SpringBootTest -class RoosterTest { - - @Autowired - private RoosterRepository roosterRepository; - - @Test - void checkInitialDataLoad() { - List roosters = roosterRepository.findAll(); - assertEquals(TestConstants.ROOSTER_COUNT, roosters.size()); - } - - @Test - void checkFetchingData() { - Rooster rooster = roosterRepository.findAll().get(4); - assertNotNull(rooster.getTeam()); - assertNotNull(rooster.getPlayer()); - assertNotNull(rooster.getPosition()); - } - - @Test - void exceptionThrownWhenSavingDuplicateRooster() { - List roosters = roosterRepository.findAll(); - Rooster existingRooster = roosters.get(5); - Rooster rooster = new Rooster(); - rooster.setPlayer(existingRooster.getPlayer()); - rooster.setTeam(existingRooster.getTeam()); - rooster.setPosition(existingRooster.getPosition()); - rooster.setYear(existingRooster.getYear()); - assertThrows(DataIntegrityViolationException.class, () -> { - roosterRepository.save(rooster); - }); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/SportTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/SportTest.java deleted file mode 100644 index c045d12..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/SportTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.tysc.repository.SportRepository; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.tysc.TestConstants; - -@SpringBootTest -class SportTest { - - @Autowired - private SportRepository sportRepository; - - @Test - void checkInitialDataLoad() { - List sports = sportRepository.findAll(); - assertEquals(TestConstants.SPORT_COUNT, sports.size()); - } - - @Test - void exceptionThrownWhenSavingSportWithEmptyName() { - Sport sport = new Sport(); - assertThrows(TransactionSystemException.class, () -> { - sportRepository.save(sport); - }); - } - - @Test - void exceptionThrownWhenSavingSportWithExistingName() { - Sport existingSport = sportRepository.findAll().get(0); - Sport sport = new Sport(); - sport.setName(existingSport.getName()); - assertThrows(DataIntegrityViolationException.class, () -> { - sportRepository.save(sport); - }); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/TeamTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/TeamTest.java deleted file mode 100644 index d183b48..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/TeamTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.tysc.repository.TeamRepository; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.tysc.TestConstants; - -@SpringBootTest -class TeamTest { - - @Autowired - private TeamRepository teamRepository; - - @Test - void checkInitialDataLoad() { - List teams = teamRepository.findAll(); - assertEquals(TestConstants.TEAM_COUNT, teams.size()); - } - - @Test - void throwExceptionWhenTeamSavedWithEmptyName() { - Team team = new Team(); - assertThrows(TransactionSystemException.class, () -> { - teamRepository.save(team); - }); - } - - @Test - void throwExceptionWhenTeamSavedWithoutSport() { - Team team = new Team(); - team.setName(TestConstants.TEAM_NAME); - assertThrows(TransactionSystemException.class, () -> { - teamRepository.save(team); - }); - } - - @Test - void throwExceptionWhenTeamSavedWithExistingName() { - Team existingTeam = teamRepository.findAll().get(11); - Team team = new Team(); - team.setName(existingTeam.getName()); - team.setSport(existingTeam.getSport()); - assertThrows(TransactionSystemException.class, () -> { - teamRepository.save(team); - }); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/VendorTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/VendorTest.java deleted file mode 100644 index ea63c11..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/data/VendorTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.thpeetz.kontor.tysc.data; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.util.List; - -import de.thpeetz.kontor.tysc.repository.VendorRepository; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.transaction.TransactionSystemException; - -import de.thpeetz.kontor.tysc.TestConstants; - -@SpringBootTest -class VendorTest { - - @Autowired - private VendorRepository vendorRepository; - - @Test - void checkInitialDataLoad() { - List vendors = vendorRepository.findAll(); - assertEquals(TestConstants.VENDOR_COUNT, vendors.size()); - } - - @Test - void exceptionThrownWhenSavingVendortWithEmptyName() { - Vendor vendor = new Vendor(); - assertThrows(TransactionSystemException.class, () -> { - vendorRepository.save(vendor); - }); - } - - @Test - void exceptionThrownWhenSavingSportWithExistingName() { - Vendor vendor = new Vendor(); - vendor.setName(TestConstants.TOPPS_NAME); - assertThrows(DataIntegrityViolationException.class, () -> { - vendorRepository.save(vendor); - }); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/CardRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/CardRepositoryTest.java deleted file mode 100644 index 96f9f45..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/CardRepositoryTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.Card; -import de.thpeetz.kontor.tysc.data.CardSet; -import de.thpeetz.kontor.tysc.data.Rooster; -import de.thpeetz.kontor.tysc.data.Vendor; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class CardRepositoryTest { - - @Autowired - private CardRepository cardRepository; - - @Test - void testSearchByFields() { - List cards = cardRepository.findAll(); - Card existingCard = cards.get(3); - Vendor vendor = existingCard.getVendor(); - CardSet cardSet = existingCard.getCardSet(); - Rooster rooster = existingCard.getRooster(); - int cardNumber = existingCard.getCardNumber(); - int year = existingCard.getYear(); - Card card = cardRepository.search(vendor, cardSet, rooster, cardNumber, year); - assertNotNull(card); - } - - @Test - void testSearch() { - assertEquals(2, cardRepository.search("2").size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/CardSetRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/CardSetRepositoryTest.java deleted file mode 100644 index 2790087..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/CardSetRepositoryTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.CardSet; -import de.thpeetz.kontor.tysc.data.Vendor; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.tysc.TestConstants; - -@SpringBootTest -class CardSetRepositoryTest { - - @Autowired - private CardSetRepository cardSetRepository; - - @Autowired - private VendorRepository vendorRepository; - - @Test - void testFindByName() { - List cardSets = cardSetRepository.findByName(TestConstants.CARDSET_MYSTIQUE_NAME); - assertEquals(1, cardSets.size()); - } - - @Test - void testFindByNameAndVendor() { - Vendor fleer = vendorRepository.findByName(TestConstants.VENDOR_FLEER); - assertNotNull(fleer); - CardSet cardSet = cardSetRepository.findByNameAndVendor(TestConstants.CARDSET_MYSTIQUE_NAME, fleer); - assertNotNull(cardSet); - } - - @Test - void testSearch() { - List cardSets = cardSetRepository.search("SP"); - assertEquals(3, cardSets.size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/FieldPositionRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/FieldPositionRepositoryTest.java deleted file mode 100644 index 3c5e26e..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/FieldPositionRepositoryTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.FieldPosition; -import de.thpeetz.kontor.tysc.data.Sport; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.tysc.TestConstants; - -@SpringBootTest -class FieldPositionRepositoryTest { - - @Autowired - private FieldPositionRepository fieldPositionRepository; - - @Autowired - private SportRepository sportRepository; - - @Test - void testFindByShortName() { - FieldPosition position = fieldPositionRepository.findByShortName(TestConstants.QUARTERBACK_SHORTNAME); - assertNotNull(position); - assertEquals(TestConstants.QUARTERBACK_NAME, position.getName()); - } - - @Test - void testFindByShortNameAndSport() { - Sport sport = sportRepository.findByName(TestConstants.FOOTBALL_NAME); - FieldPosition position = fieldPositionRepository.findByShortNameAndSport(TestConstants.QUARTERBACK_SHORTNAME, sport); - assertNotNull(position); - assertEquals(TestConstants.QUARTERBACK_NAME, position.getName()); - } - - @Test - void testFindByShortNameIgnoreCase() { - List positions = fieldPositionRepository - .findByShortNameIgnoreCase(TestConstants.QUARTERBACK_SHORTNAME.toLowerCase()); - assertNotNull(positions); - assertEquals(1, positions.size()); - assertEquals(TestConstants.QUARTERBACK_NAME, positions.get(0).getName()); - } - - @Test - void testFindBySport() { - Sport sport = sportRepository.findByName(TestConstants.FOOTBALL_NAME); - List positions = fieldPositionRepository.findBySport(sport); - assertEquals(TestConstants.FOOTBALL_POSITION_COUNT, positions.size()); - } - - @Test - void testSearch() { - List positions = fieldPositionRepository.search("back"); - assertEquals(8, positions.size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/PlayerRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/PlayerRepositoryTest.java deleted file mode 100644 index 1f602c7..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/PlayerRepositoryTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.Player; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class PlayerRepositoryTest { - - @Autowired - private PlayerRepository playerRepository; - - @Test - void testFindByFirstNameAndLastName() { - Player existingPlayer = playerRepository.findAll().get(11); - String firstName = existingPlayer.getFirstName(); - String lastName = existingPlayer.getLastName(); - Player found = playerRepository.findByFirstNameAndLastName(firstName, lastName); - assertEquals(existingPlayer.getFullName(), found.getFullName()); - } - - @Test - void testSearch() { - List players = playerRepository.search("can"); - assertEquals(1, players.size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/RoosterRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/RoosterRepositoryTest.java deleted file mode 100644 index a310edb..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/RoosterRepositoryTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.FieldPosition; -import de.thpeetz.kontor.tysc.data.Player; -import de.thpeetz.kontor.tysc.data.Rooster; -import de.thpeetz.kontor.tysc.data.Team; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class RoosterRepositoryTest { - - @Autowired - private RoosterRepository roosterRepository; - - @Test - void testFindByReferences() { - List roosters = roosterRepository.findAll(); - Rooster existingRooster = roosters.get(4); - Team team = existingRooster.getTeam(); - Player player = existingRooster.getPlayer(); - FieldPosition position = existingRooster.getPosition(); - int year = existingRooster.getYear(); - Rooster rooster = roosterRepository.findByReferences(player, team, position, year); - assertNotNull(rooster); - assertEquals(existingRooster.getId(), rooster.getId()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/SportRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/SportRepositoryTest.java deleted file mode 100644 index d11fd07..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/SportRepositoryTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.Sport; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.tysc.TestConstants; - -@SpringBootTest -class SportRepositoryTest { - - @Autowired - private SportRepository sportRepository; - - @Test - void testFindByName() { - Sport sport = sportRepository.findByName(TestConstants.FOOTBALL_NAME); - assertNotNull(sport); - assertEquals(TestConstants.FOOTBALL_TEAM_COUNT, sport.getTeams().size()); - assertEquals(TestConstants.FOOTBALL_POSITION_COUNT, sport.getPositions().size()); - } - - @Test - void testFindByNameIgnoreCase() { - List sports = sportRepository.findByNameIgnoreCase(TestConstants.FOOTBALL_NAME.toLowerCase()); - assertNotNull(sports); - assertEquals(TestConstants.FOOTBALL_TEAM_COUNT, sports.get(0).getTeams().size()); - } - - @Test - void testSearch() { - List sports = sportRepository.search("ball"); - assertEquals(3, sports.size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/TeamRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/TeamRepositoryTest.java deleted file mode 100644 index 83061a3..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/TeamRepositoryTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.Team; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.tysc.TestConstants; - -@SpringBootTest -class TeamRepositoryTest { - - @Autowired - private TeamRepository teamRepository; - - @Test - void testFindByName() { - Team team = teamRepository.findByName(TestConstants.DOLPHINS_NAME); - assertEquals(TestConstants.DOLPHINS_SHORT, team.getShortName()); - } - - @Test - void testFindByNameIgnoreCase() { - List teams = teamRepository.findByNameIgnoreCase(TestConstants.DOLPHINS_NAME.toLowerCase()); - assertEquals(1, teams.size()); - assertEquals(TestConstants.DOLPHINS_SHORT, teams.get(0).getShortName()); - } - - @Test - void testSearch() { - List teams = teamRepository.search("dol"); - assertEquals(1, teams.size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/VendorRepositoryTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/VendorRepositoryTest.java deleted file mode 100644 index ef905c8..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/repository/VendorRepositoryTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package de.thpeetz.kontor.tysc.repository; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.Vendor; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.tysc.TestConstants; - -@SpringBootTest -class VendorRepositoryTest { - - @Autowired - private VendorRepository vendorRepository; - - @Test - void testFindByName() { - Vendor vendor = vendorRepository.findByName(TestConstants.TOPPS_NAME); - assertNotNull(vendor); - assertEquals(TestConstants.TOPPS_NAME, vendor.getName()); - } - - @Test - void testFindByNameIgnoreCase() { - List vendors = vendorRepository.findByNameIgnoreCase(TestConstants.TOPPS_NAME.toLowerCase()); - assertNotNull(vendors); - assertEquals(1, vendors.size()); - assertEquals(TestConstants.TOPPS_NAME, vendors.get(0).getName()); - } - - @Test - void testSearch() { - List vendors = vendorRepository.search("pp"); - assertNotNull(vendors); - assertEquals(2, vendors.size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/services/CardServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/services/CardServiceTest.java deleted file mode 100644 index e215217..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/services/CardServiceTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package de.thpeetz.kontor.tysc.services; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.tysc.TestConstants; -import de.thpeetz.kontor.tysc.data.Card; -import de.thpeetz.kontor.tysc.data.CardSet; -import de.thpeetz.kontor.tysc.data.Rooster; -import de.thpeetz.kontor.tysc.data.Vendor; - -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -class CardServiceTest { - - @Autowired - private CardService cardService; - - @Autowired - private SportService sportService; - - @Test - @Order(1) - void testFindAllVendors() { - assertEquals(TestConstants.VENDOR_COUNT, cardService.findAllVendors(null).size()); - assertEquals(2, cardService.findAllVendors("pp").size()); - } - - @Test - @Order(2) - void testSaveVendor() { - Vendor vendor = new Vendor(); - vendor.setName(TestConstants.VENDOR_NAME); - vendor = cardService.saveVendor(vendor); - assertNotNull(vendor); - assertEquals(TestConstants.VENDOR_COUNT + 1, cardService.findAllVendors(null).size()); - } - - @Test - @Order(3) - void testDeleteVendor() { - List vendors = cardService.findAllVendors(TestConstants.VENDOR_NAME); - assertEquals(1, vendors.size()); - Vendor vendor = vendors.get(0); - cardService.deleteVendor(vendor); - assertEquals(TestConstants.VENDOR_COUNT, cardService.findAllVendors(null).size()); - } - - @Test - @Order(4) - void testFindAllCardSets() { - assertEquals(TestConstants.CARDSET_COUNT, cardService.findAllCardSets(null).size()); - assertEquals(1, cardService.findAllCardSets("Ultra").size()); - } - - @Test - @Order(5) - void testSaveCardSet() { - List vendors = cardService.findAllVendors(TestConstants.VENDOR_FLEER); - assertEquals(1, vendors.size()); - Vendor vendor = vendors.get(0); - CardSet cardSet = new CardSet(); - cardSet.setName(TestConstants.CARDSET_NAME); - cardSet.setVendor(vendor); - cardSet.setInsertSet(false); - cardSet.setParallelSet(false); - cardService.saveCardSet(cardSet); - assertEquals(TestConstants.CARDSET_COUNT + 1, cardService.findAllCardSets(null).size()); - } - - @Test - @Order(6) - void testDeleteCardSet() { - List cardSets = cardService.findAllCardSets(TestConstants.CARDSET_NAME); - assertEquals(1, cardSets.size()); - CardSet cardSet = cardSets.get(0); - cardService.deleteCardSet(cardSet); - assertEquals(TestConstants.CARDSET_COUNT, cardService.findAllCardSets(null).size()); - } - - @Test - @Order(7) - void testFindAllCards() { - assertEquals(TestConstants.CARD_COUNT, cardService.findAllCards(null).size()); - assertEquals(1, cardService.findAllCards("112").size()); - } - - @Test - @Order(8) - void testSaveCard() { - List vendors = cardService.findAllVendors(TestConstants.VENDOR_FLEER); - assertEquals(1, vendors.size()); - Vendor vendor = vendors.get(0); - List cardSets = cardService.findAllCardSets(TestConstants.CARDSET_MYSTIQUE_NAME); - assertEquals(3, cardSets.size()); - CardSet cardSet = cardSets.get(0); - List roosters = sportService.findAllRoosters(); - Rooster rooster = roosters.get(0); - Card card = new Card(); - card.setCardNumber(TestConstants.CARD_CARDNUMBER); - card.setCardSet(cardSet); - card.setVendor(vendor); - card.setRooster(rooster); - card.setYear(TestConstants.CARD_YEAR); - cardService.saveCard(card); - assertEquals(TestConstants.CARD_COUNT + 1, cardService.findAllCards(null).size()); - } - - @Test - @Order(9) - void testDeleteCard() { - List cards = cardService.findAllCards(TestConstants.CARD_CARDNUMBER.toString()); - assertEquals(1, cards.size()); - Card card = cards.get(0); - cardService.deleteCard(card); - assertEquals(TestConstants.CARD_COUNT, cardService.findAllCards(null).size()); - } -} diff --git a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/services/SportServiceTest.java b/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/services/SportServiceTest.java deleted file mode 100644 index 30b7ed6..0000000 --- a/kontor-spring/src/test/java/de/thpeetz/kontor/tysc/services/SportServiceTest.java +++ /dev/null @@ -1,200 +0,0 @@ -package de.thpeetz.kontor.tysc.services; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; - -import de.thpeetz.kontor.tysc.data.FieldPosition; -import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import de.thpeetz.kontor.tysc.TestConstants; -import de.thpeetz.kontor.tysc.data.Player; -import de.thpeetz.kontor.tysc.data.Rooster; -import de.thpeetz.kontor.tysc.data.Sport; -import de.thpeetz.kontor.tysc.data.Team; - -@SpringBootTest -@TestMethodOrder(OrderAnnotation.class) -class SportServiceTest { - - @Autowired - private SportService sportService; - - - @Test - @Order(1) - void testFindAllSports() { - List sports = sportService.findAllSports(null); - assertEquals(TestConstants.SPORT_COUNT, sports.size()); - assertEquals(3, sportService.findAllSports("ball").size()); - } - - @Test - @Order(2) - void testSaveSport() { - Sport sport = new Sport(); - sport.setName(TestConstants.SPORT_NAME); - sport = sportService.saveSport(sport); - assertNotNull(sport); - assertEquals(TestConstants.SPORT_COUNT+1, sportService.findAllSports(null).size()); - } - - @Test - @Order(3) - void testDeleteSport() { - List sports = sportService.findAllSports(TestConstants.SPORT_NAME); - assertEquals(1, sports.size()); - Sport sport = sports.get(0); - sportService.deleteSport(sport); - assertEquals(TestConstants.SPORT_COUNT, sportService.findAllSports(null).size()); - } - - @Test - @Order(4) - void testFindAllPlayers() { - assertEquals(TestConstants.PLAYER_COUNT, sportService.findAllPlayers(null).size()); - assertEquals(TestConstants.PLAYER_CHRIS_COUNT, sportService.findAllPlayers(TestConstants.PLAYER_CHRIS_NAME).size()); - } - - @Test - @Order(5) - void testSavePlayer() { - Player player = new Player(); - player.setFirstName(TestConstants.PLAYER_FIRSTNAME); - player.setLastName(TestConstants.PLAYER_LASTNAME); - player = sportService.savePlayer(player); - assertNotNull(player); - } - - @Test - @Order(6) - void testDeletePlayer() { - List players = sportService.findAllPlayers(TestConstants.PLAYER_LASTNAME); - assertEquals(1, players.size()); - Player player = players.get(0); - sportService.deletePlayer(player); - assertEquals(TestConstants.PLAYER_COUNT, sportService.findAllPlayers(null).size()); - } - - - @Test - @Order(7) - void testFindAllPositions() { - assertEquals(TestConstants.POSITION_COUNT, sportService.findAllPositions(null).size()); - assertEquals(TestConstants.POSITION_CENTER_COUNT, sportService.findAllPositions(TestConstants.POSITION_CENTER).size()); - } - - @Test - @Order(8) - void testFindAllPositionsForSport() { - List sports = sportService.findAllSports(TestConstants.FOOTBALL_NAME); - assertEquals(1, sports.size()); - Sport football = sports.get(0); - assertEquals(TestConstants.FOOTBALL_POSITION_COUNT, sportService.findAllPositionsForSport(football).size()); - } - - @Test - @Order(9) - void testSavePosition() { - List sports = sportService.findAllSports(TestConstants.FOOTBALL_NAME); - Sport football = sports.get(0); - FieldPosition position = new FieldPosition(); - position.setSport(football); - position.setName(TestConstants.POSITION_NAME); - position.setShortName(TestConstants.POSITION_SHORTNAME); - sportService.savePosition(position); - assertEquals(TestConstants.POSITION_COUNT+1, sportService.findAllPositions(null).size()); - } - - @Test - @Order(10) - void testDeletePosition() { - List positions = sportService.findAllPositions(TestConstants.POSITION_NAME); - assertEquals(1, positions.size()); - FieldPosition position = positions.get(0); - sportService.deletePosition(position); - assertEquals(TestConstants.POSITION_COUNT, sportService.findAllPositions(null).size()); - } - - @Test - @Order(11) - void testFindAllTeams() { - assertEquals(TestConstants.TEAM_COUNT, sportService.findAllTeams(null).size()); - assertEquals(1, sportService.findAllTeams("sharks").size()); - } - - @Test - @Order(12) - void testSaveTeam() { - List sports = sportService.findAllSports(TestConstants.FOOTBALL_NAME); - Sport football = sports.get(0); - Team team = new Team(); - team.setSport(football); - team.setName(TestConstants.TEAM_NAME); - team.setShortName(TestConstants.TEAM_SHORTNAME); - sportService.saveTeam(team); - assertEquals(TestConstants.TEAM_COUNT+1, sportService.findAllTeams(null).size()); - } - - @Test - @Order(13) - void testDeleteTeam() { - List teams = sportService.findAllTeams(TestConstants.TEAM_NAME); - assertEquals(1, teams.size()); - Team team = teams.get(0); - sportService.deleteTeam(team); - assertEquals(TestConstants.TEAM_COUNT, sportService.findAllTeams(null).size()); - } - - @Test - @Order(14) - void testFindAllRoosters() { - assertEquals(TestConstants.ROOSTER_COUNT, sportService.findAllRoosters().size()); - } - - @Test - @Order(15) - void testFindRoosterByFields() { - List roosters = sportService.findAllRoosters(); - Rooster existingRooster = roosters.get(4); - Team team = existingRooster.getTeam(); - Player player = existingRooster.getPlayer(); - FieldPosition position = existingRooster.getPosition(); - int year = existingRooster.getYear(); - Rooster rooster = sportService.findRoosterByFields(team, player, position, year); - assertNotNull(rooster); - assertEquals(existingRooster.getId(), rooster.getId()); - } - - @Test - @Order(16) - void testSaveRooster() { - Rooster rooster = new Rooster(); - Player player = sportService.findAllPlayers(TestConstants.PLAYER_CHRIS_NAME).get(0); - rooster.setPlayer(player); - Team team = sportService.findAllTeams(TestConstants.DOLPHINS_NAME).get(0); - rooster.setTeam(team); - FieldPosition position = sportService.findAllPositions(TestConstants.QUARTERBACK_NAME).get(0); - rooster.setPosition(position); - rooster.setYear(TestConstants.ROOSTER_YEAR); - sportService.saveRooster(rooster); - assertEquals(TestConstants.ROOSTER_COUNT+1, sportService.findAllRoosters().size()); - } - - @Test - @Order(17) - void testDeleteRooster() { - Team team = sportService.findAllTeams(TestConstants.DOLPHINS_NAME).get(0); - Player player = sportService.findAllPlayers(TestConstants.PLAYER_CHRIS_NAME).get(0); - FieldPosition position = sportService.findAllPositions(TestConstants.QUARTERBACK_NAME).get(0); - Rooster rooster = sportService.findRoosterByFields(team, player, position, TestConstants.ROOSTER_YEAR); - assertNotNull(rooster); - sportService.deleteRooster(rooster); - assertEquals(TestConstants.ROOSTER_COUNT, sportService.findAllRoosters().size()); - } -} diff --git a/kontor-vue/.dockerignore b/kontor-vue/.dockerignore deleted file mode 100644 index fc3a561..0000000 --- a/kontor-vue/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -.git -.gitignore - diff --git a/kontor-vue/.gitattributes b/kontor-vue/.gitattributes deleted file mode 100644 index 6313b56..0000000 --- a/kontor-vue/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -* text=auto eol=lf diff --git a/kontor-vue/.gitignore b/kontor-vue/.gitignore index 5a89817..a547bf3 100644 --- a/kontor-vue/.gitignore +++ b/kontor-vue/.gitignore @@ -1,26 +1,24 @@ -# local env files -.env.local -.env.*.local - -# Log files +# Logs logs *.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* node_modules -/dist -.DS_Store dist dist-ssr -coverage *.local # Editor directories and files -.vscode/ -.idea/ +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? - -*.tsbuildinfo diff --git a/kontor-vue/.prettierrc.json b/kontor-vue/.prettierrc.json deleted file mode 100644 index 29a2402..0000000 --- a/kontor-vue/.prettierrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/prettierrc", - "semi": false, - "singleQuote": true, - "printWidth": 100 -} diff --git a/kontor-vue/Containerfile b/kontor-vue/Containerfile new file mode 100644 index 0000000..1297eff --- /dev/null +++ b/kontor-vue/Containerfile @@ -0,0 +1,15 @@ +FROM docker.io/node:20-alpine AS build +WORKDIR /app +ENV PATH=/app/node_modules/.bin:$PATH +COPY package.json /app/package.json +RUN npm install +RUN npm install -g @vue/cli +COPY . /app +RUN npm run build + +FROM docker.io/library/nginx:stable-alpine +COPY nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=build /app/dist /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] + diff --git a/kontor-vue/Dockerfile b/kontor-vue/Dockerfile deleted file mode 100644 index f139489..0000000 --- a/kontor-vue/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM node:22.18.0-bookworm-slim AS build -WORKDIR /app -ENV PATH=/app/node_modules/.bin:$PATH -COPY package.json /app/package.json -RUN npm install -RUN npm install -g @vue/cli -COPY . /app -RUN npm run build - -FROM nginx:1.29.0-alpine -COPY --from=build /app/dist /usr/share/nginx/html -EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] - diff --git a/kontor-vue/README.md b/kontor-vue/README.md index f33334c..1511959 100644 --- a/kontor-vue/README.md +++ b/kontor-vue/README.md @@ -1,56 +1,5 @@ -# kontor-vue +# Vue 3 + Vite -### Customize configuration -See [Configuration Reference](https://cli.vuejs.org/config/). -This template should help get you started developing with Vue 3 in Vite. +This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` + diff --git a/kontor-vue/jsconfig.json b/kontor-vue/jsconfig.json deleted file mode 100644 index 4aafc5f..0000000 --- a/kontor-vue/jsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "module": "esnext", - "baseUrl": "./", - "moduleResolution": "node", - "paths": { - "@/*": [ - "src/*" - ] - }, - "lib": [ - "esnext", - "dom", - "dom.iterable", - "scripthost" - ] - } -} diff --git a/kontor-vue/nginx.conf b/kontor-vue/nginx.conf new file mode 100644 index 0000000..0427572 --- /dev/null +++ b/kontor-vue/nginx.conf @@ -0,0 +1,38 @@ +server { + listen 8700; + # Root-Verzeichnis für den Server setzen (wir kopieren unsere Anwendung hierher) + root /usr/share/nginx/html; + + # Definieren der Standard-Indexdatei (Angular erstellt die Datei index.html für uns und sie befindet sich im oben genannten Verzeichnis) + index index.html; + + # Cache-Header für Medien-ASsets + location ~* \.(?:cur|jpe?g|gif|htc|ico|png|xml|otf|ttf|eot|woff|woff2|svg)$ { + access_log off; + add_header Pragma "must-revalidate, public"; + add_header Cache-Control "must-revalidate, public"; + expires max; + + tcp_nodelay off; + } + + # Cache-Header für HTML, CSS und JS-Dateien + location ~* \.(?:css|js|html)$ { + access_log off; + add_header Pragma "must-revalidate, public"; + add_header Cache-Control "must-revalidate, public"; + expires 2d; + + tcp_nodelay off; + } + + # Konfiguration für den /-Pfad + location / { + # Zunächst versuchen wir die angeforderte URI auzuliefern + # Klappt das nicht, versuchen wir es mit einem abschließenden Slash + # Klappt auch das nicht, liefern wir die index.html aus. + # Das ist nötig, damit Angular-Routen korrekt augeflöst und ausgeliefert werden + try_files $uri $uri/ /index.html; + } +} + diff --git a/kontor-vue/package-lock.json b/kontor-vue/package-lock.json index e20dcf5..a7c64b4 100644 --- a/kontor-vue/package-lock.json +++ b/kontor-vue/package-lock.json @@ -8,309 +8,22 @@ "name": "kontor-vue", "version": "0.0.0", "dependencies": { - "pinia": "^3.0.3", - "vue": "^3.5.18", - "vue-router": "^4.5.1" + "@fortawesome/fontawesome-svg-core": "^7.2.0", + "@fortawesome/free-solid-svg-icons": "^7.2.0", + "@fortawesome/vue-fontawesome": "^3.1.3", + "axios": "^1.14.0", + "bootstrap": "^5.3.8", + "jquery": "^4.0.0", + "popper.js": "^1.16.1", + "vee-validate": "^4.15.1", + "vue": "^3.5.30", + "vue-router": "^4.6.4", + "vuex": "^4.1.0", + "yup": "^1.7.1" }, "devDependencies": { - "@tsconfig/node22": "^22.0.2", - "@types/jsdom": "^21.1.7", - "@types/node": "^22.16.5", - "@vitejs/plugin-vue": "^6.0.1", - "@vitejs/plugin-vue-jsx": "^5.0.1", - "@vitest/eslint-plugin": "^1.3.4", - "@vue/eslint-config-prettier": "^10.2.0", - "@vue/eslint-config-typescript": "^14.6.0", - "@vue/test-utils": "^2.4.6", - "@vue/tsconfig": "^0.7.0", - "cypress": "^14.5.3", - "eslint": "^9.31.0", - "eslint-plugin-cypress": "^5.1.0", - "eslint-plugin-vue": "~10.3.0", - "jiti": "^2.4.2", - "jsdom": "^26.1.0", - "npm-run-all2": "^8.0.4", - "prettier": "3.6.2", - "start-server-and-test": "^2.0.12", - "typescript": "~5.8.0", - "vite": "^7.0.6", - "vite-plugin-vue-devtools": "^8.0.0", - "vitest": "^3.2.4", - "vue-tsc": "^3.0.4" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@asamuzakjp/css-color": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", - "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@csstools/css-calc": "^2.1.3", - "@csstools/css-color-parser": "^3.0.9", - "@csstools/css-parser-algorithms": "^3.0.4", - "@csstools/css-tokenizer": "^3.0.3", - "lru-cache": "^10.4.3" - } - }, - "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", - "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", - "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.6", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.0", - "@babel/types": "^7.28.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", - "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/types": "^7.28.0", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz", - "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.27.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", - "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", - "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@vitejs/plugin-vue": "^6.0.5", + "vite": "^8.0.1" } }, "node_modules/@babel/helper-string-parser": { @@ -323,45 +36,21 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz", - "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.0" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -370,372 +59,149 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.0.tgz", - "integrity": "sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-decorators": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz", - "integrity": "sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz", - "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", - "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.0", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/types": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@csstools/color-helpers": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", - "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - } - }, - "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-color-parser": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.10.tgz", - "integrity": "sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/color-helpers": "^5.0.2", - "@csstools/css-calc": "^2.1.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@cypress/request": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.9.tgz", - "integrity": "sha512-I3l7FdGRXluAS44/0NguwWlO83J18p0vlr2FYHrJkWdNYhgVoiYo61IXPqaOsL+vNxU1ZqMACzItGK3/KKDsdw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~4.0.4", - "http-signature": "~1.4.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "performance-now": "^2.1.0", - "qs": "6.14.0", - "safe-buffer": "^5.1.2", - "tough-cookie": "^5.0.0", - "tunnel-agent": "^0.6.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@cypress/xvfb": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", - "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.1.0", - "lodash.once": "^4.1.1" - } - }, - "node_modules/@cypress/xvfb/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", - "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", - "cpu": [ - "ppc64" - ], + "node_modules/@emnapi/core": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", + "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" + "peer": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", - "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", - "cpu": [ - "arm" - ], + "node_modules/@emnapi/runtime": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", + "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", "dev": true, "license": "MIT", "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" + "peer": true, + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", - "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-7.2.0.tgz", + "integrity": "sha512-IpR0bER9FY25p+e7BmFH25MZKEwFHTfRAfhOyJubgiDnoJNsSvJ7nigLraHtp4VOG/cy8D7uiV0dLkHOne5Fhw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-7.2.0.tgz", + "integrity": "sha512-6639htZMjEkwskf3J+e6/iar+4cTNM9qhoWuRfj9F3eJD6r7iCzV1SWnQr2Mdv0QT0suuqU8BoJCZUyCtP9R4Q==", + "license": "MIT", + "dependencies": { + "@fortawesome/fontawesome-common-types": "7.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-7.2.0.tgz", + "integrity": "sha512-YTVITFGN0/24PxzXrwqCgnyd7njDuzp5ZvaCx5nq/jg55kUYd94Nj8UTchBdBofi/L0nwRfjGOg0E41d2u9T1w==", + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "7.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/vue-fontawesome": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.1.3.tgz", + "integrity": "sha512-OHHUTLPEzdwP8kcYIzhioUdUOjZ4zzmi+midwa4bqscza4OJCOvTKJEHkXNz8PgZ23kWci1HkKVX0bm8f9t9gQ==", + "license": "MIT", + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6 || ~7", + "vue": ">= 3.0.0 < 4" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.2.tgz", + "integrity": "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.122.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz", + "integrity": "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.12.tgz", + "integrity": "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==", "cpu": [ "arm64" ], @@ -746,30 +212,13 @@ "android" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", - "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", - "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.12.tgz", + "integrity": "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==", "cpu": [ "arm64" ], @@ -780,13 +229,13 @@ "darwin" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", - "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.12.tgz", + "integrity": "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==", "cpu": [ "x64" ], @@ -797,30 +246,13 @@ "darwin" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", - "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", - "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.12.tgz", + "integrity": "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==", "cpu": [ "x64" ], @@ -831,13 +263,13 @@ "freebsd" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", - "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.12.tgz", + "integrity": "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==", "cpu": [ "arm" ], @@ -848,13 +280,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", - "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==", "cpu": [ "arm64" ], @@ -865,15 +297,15 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", - "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.12.tgz", + "integrity": "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==", "cpu": [ - "ia32" + "arm64" ], "dev": true, "license": "MIT", @@ -882,47 +314,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", - "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", - "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", - "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==", "cpu": [ "ppc64" ], @@ -933,30 +331,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", - "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", - "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==", "cpu": [ "s390x" ], @@ -967,13 +348,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", - "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==", "cpu": [ "x64" ], @@ -984,30 +365,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", - "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", - "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.12.tgz", + "integrity": "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==", "cpu": [ "x64" ], @@ -1015,50 +379,16 @@ "license": "MIT", "optional": true, "os": [ - "netbsd" + "linux" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", - "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", - "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", - "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.12.tgz", + "integrity": "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==", "cpu": [ "arm64" ], @@ -1069,30 +399,30 @@ "openharmony" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", - "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.12.tgz", + "integrity": "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==", "cpu": [ - "x64" + "wasm32" ], "dev": true, "license": "MIT", "optional": true, - "os": [ - "sunos" - ], + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.1" + }, "engines": { - "node": ">=18" + "node": ">=14.0.0" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", - "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.12.tgz", + "integrity": "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==", "cpu": [ "arm64" ], @@ -1103,30 +433,13 @@ "win32" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", - "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", - "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.12.tgz", + "integrity": "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==", "cpu": [ "x64" ], @@ -1137,1542 +450,107 @@ "win32" ], "engines": { - "node": ">=18" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", - "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.6", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", - "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", - "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", - "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz", - "integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.15.1", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@one-ini/wasm": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", - "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.29", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", - "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", - "dev": true, - "license": "MIT" - }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.29", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.29.tgz", - "integrity": "sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==", + "version": "1.0.0-rc.2", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.2.tgz", + "integrity": "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==", "dev": true, "license": "MIT" }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz", - "integrity": "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz", - "integrity": "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz", - "integrity": "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz", - "integrity": "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz", - "integrity": "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz", - "integrity": "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz", - "integrity": "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz", - "integrity": "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz", - "integrity": "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz", - "integrity": "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz", - "integrity": "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz", - "integrity": "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz", - "integrity": "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz", - "integrity": "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz", - "integrity": "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz", - "integrity": "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz", - "integrity": "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz", - "integrity": "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz", - "integrity": "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz", - "integrity": "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@sec-ant/readable-stream": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", - "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@sindresorhus/merge-streams": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", - "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@tsconfig/node22": { - "version": "22.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node22/-/node22-22.0.2.tgz", - "integrity": "sha512-Kmwj4u8sDRDrMYRoN9FDEcXD8UpBSaPQQ24Gz+Gamqfm7xxn+GBR7ge/Z7pK8OXNGyUzbSwJj+TH6B+DS/epyA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/chai": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", - "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/deep-eql": "*" - } - }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/jsdom": { - "version": "21.1.7", - "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz", - "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/tough-cookie": "*", - "parse5": "^7.0.0" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.17.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.0.tgz", - "integrity": "sha512-bbAKTCqX5aNVryi7qXVMi+OkB3w/OyblodicMbvE38blyAz7GxXf6XYhklokijuPwwVg9sDLKRxt0ZHXQwZVfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/sinonjs__fake-timers": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", - "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/sizzle": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz", - "integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/tough-cookie": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz", - "integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/type-utils": "8.38.0", - "@typescript-eslint/utils": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.38.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz", - "integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz", - "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.38.0", - "@typescript-eslint/types": "^8.38.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz", - "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz", - "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz", - "integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0", - "@typescript-eslint/utils": "8.38.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz", - "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz", - "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.38.0", - "@typescript-eslint/tsconfig-utils": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz", - "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz", - "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.38.0", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "tslib": "^2.4.0" } }, "node_modules/@vitejs/plugin-vue": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.1.tgz", - "integrity": "sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.5.tgz", + "integrity": "sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg==", "dev": true, "license": "MIT", "dependencies": { - "@rolldown/pluginutils": "1.0.0-beta.29" + "@rolldown/pluginutils": "1.0.0-rc.2" }, "engines": { "node": "^20.19.0 || >=22.12.0" }, "peerDependencies": { - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", "vue": "^3.2.25" } }, - "node_modules/@vitejs/plugin-vue-jsx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-5.0.1.tgz", - "integrity": "sha512-X7qmQMXbdDh+sfHUttXokPD0cjPkMFoae7SgbkF9vi3idGUKmxLcnU2Ug49FHwiKXebfzQRIm5yK3sfCJzNBbg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.7", - "@babel/plugin-transform-typescript": "^7.27.1", - "@rolldown/pluginutils": "^1.0.0-beta.21", - "@vue/babel-plugin-jsx": "^1.4.0" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0", - "vue": "^3.0.0" - } - }, - "node_modules/@vitest/eslint-plugin": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.3.4.tgz", - "integrity": "sha512-EOg8d0jn3BAiKnR55WkFxmxfWA3nmzrbIIuOXyTe6A72duryNgyU+bdBEauA97Aab3ho9kLmAwgPX63Ckj4QEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "^8.24.1" - }, - "peerDependencies": { - "eslint": ">= 8.57.0", - "typescript": ">= 5.0.0", - "vitest": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "vitest": { - "optional": true - } - } - }, - "node_modules/@vitest/expect": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", - "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.4", - "@vitest/utils": "3.2.4", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/mocker": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", - "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "3.2.4", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } - } - }, - "node_modules/@vitest/mocker/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/@vitest/pretty-format": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", - "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", - "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/utils": "3.2.4", - "pathe": "^2.0.3", - "strip-literal": "^3.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", - "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.4", - "magic-string": "^0.30.17", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", - "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyspy": "^4.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", - "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.4", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@volar/language-core": { - "version": "2.4.22", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.22.tgz", - "integrity": "sha512-gp4M7Di5KgNyIyO903wTClYBavRt6UyFNpc5LWfyZr1lBsTUY+QrVZfmbNF2aCyfklBOVk9YC4p+zkwoyT7ECg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@volar/source-map": "2.4.22" - } - }, - "node_modules/@volar/source-map": { - "version": "2.4.22", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.22.tgz", - "integrity": "sha512-L2nVr/1vei0xKRgO2tYVXtJYd09HTRjaZi418e85Q+QdbbqA8h7bBjfNyPPSsjnrOO4l4kaAo78c8SQUAdHvgA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@volar/typescript": { - "version": "2.4.22", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.22.tgz", - "integrity": "sha512-6ZczlJW1/GWTrNnkmZxJp4qyBt/SGVlcTuCWpI5zLrdPdCZsj66Aff9ZsfFaT3TyjG8zVYgBMYPuCm/eRkpcpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@volar/language-core": "2.4.22", - "path-browserify": "^1.0.1", - "vscode-uri": "^3.0.8" - } - }, - "node_modules/@vue/babel-helper-vue-transform-on": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.4.0.tgz", - "integrity": "sha512-mCokbouEQ/ocRce/FpKCRItGo+013tHg7tixg3DUNS+6bmIchPt66012kBMm476vyEIJPafrvOf4E5OYj3shSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@vue/babel-plugin-jsx": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.4.0.tgz", - "integrity": "sha512-9zAHmwgMWlaN6qRKdrg1uKsBKHvnUU+Py+MOCTuYZBoZsopa90Di10QRjB+YPnVss0BZbG/H5XFwJY1fTxJWhA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-plugin-utils": "^7.26.5", - "@babel/plugin-syntax-jsx": "^7.25.9", - "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.9", - "@babel/types": "^7.26.9", - "@vue/babel-helper-vue-transform-on": "1.4.0", - "@vue/babel-plugin-resolve-type": "1.4.0", - "@vue/shared": "^3.5.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - } - } - }, - "node_modules/@vue/babel-plugin-resolve-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.4.0.tgz", - "integrity": "sha512-4xqDRRbQQEWHQyjlYSgZsWj44KfiF6D+ktCuXyZ8EnVDYV3pztmXJDf1HveAjUAXxAnR8daCQT51RneWWxtTyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-plugin-utils": "^7.26.5", - "@babel/parser": "^7.26.9", - "@vue/compiler-sfc": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/sxzz" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@vue/compiler-core": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.18.tgz", - "integrity": "sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.32.tgz", + "integrity": "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.0", - "@vue/shared": "3.5.18", - "entities": "^4.5.0", + "@babel/parser": "^7.29.2", + "@vue/shared": "3.5.32", + "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.18.tgz", - "integrity": "sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.32.tgz", + "integrity": "sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q==", "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.18", - "@vue/shared": "3.5.18" + "@vue/compiler-core": "3.5.32", + "@vue/shared": "3.5.32" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.18.tgz", - "integrity": "sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.32.tgz", + "integrity": "sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.0", - "@vue/compiler-core": "3.5.18", - "@vue/compiler-dom": "3.5.18", - "@vue/compiler-ssr": "3.5.18", - "@vue/shared": "3.5.18", + "@babel/parser": "^7.29.2", + "@vue/compiler-core": "3.5.32", + "@vue/compiler-dom": "3.5.32", + "@vue/compiler-ssr": "3.5.32", + "@vue/shared": "3.5.32", "estree-walker": "^2.0.2", - "magic-string": "^0.30.17", - "postcss": "^8.5.6", + "magic-string": "^0.30.21", + "postcss": "^8.5.8", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.18.tgz", - "integrity": "sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.32.tgz", + "integrity": "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.18", - "@vue/shared": "3.5.18" - } - }, - "node_modules/@vue/compiler-vue2": { - "version": "2.7.16", - "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", - "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", - "dev": true, - "license": "MIT", - "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.2.0" + "@vue/compiler-dom": "3.5.32", + "@vue/shared": "3.5.32" } }, "node_modules/@vue/devtools-api": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.7.tgz", - "integrity": "sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==", - "license": "MIT", - "dependencies": { - "@vue/devtools-kit": "^7.7.7" - } - }, - "node_modules/@vue/devtools-core": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-8.0.0.tgz", - "integrity": "sha512-5bPtF0jAFnaGs4C/4+3vGRR5U+cf6Y8UWK0nJflutEDGepHxl5L9JRaPdHQYCUgrzUaf4cY4waNBEEGXrfcs3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/devtools-kit": "^8.0.0", - "@vue/devtools-shared": "^8.0.0", - "mitt": "^3.0.1", - "nanoid": "^5.1.5", - "pathe": "^2.0.3", - "vite-hot-client": "^2.1.0" - }, - "peerDependencies": { - "vue": "^3.0.0" - } - }, - "node_modules/@vue/devtools-core/node_modules/@vue/devtools-kit": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.0.0.tgz", - "integrity": "sha512-b11OeQODkE0bctdT0RhL684pEV2DPXJ80bjpywVCbFn1PxuL3bmMPDoJKjbMnnoWbrnUYXYzFfmMWBZAMhORkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/devtools-shared": "^8.0.0", - "birpc": "^2.5.0", - "hookable": "^5.5.3", - "mitt": "^3.0.1", - "perfect-debounce": "^1.0.0", - "speakingurl": "^14.0.1", - "superjson": "^2.2.2" - } - }, - "node_modules/@vue/devtools-core/node_modules/@vue/devtools-shared": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.0.0.tgz", - "integrity": "sha512-jrKnbjshQCiOAJanoeJjTU7WaCg0Dz2BUal6SaR6VM/P3hiFdX5Q6Pxl73ZMnrhCxNK9nAg5hvvRGqs+6dtU1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "rfdc": "^1.4.1" - } - }, - "node_modules/@vue/devtools-core/node_modules/nanoid": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz", - "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.js" - }, - "engines": { - "node": "^18 || >=20" - } + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" }, "node_modules/@vue/devtools-kit": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz", - "integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==", + "version": "7.7.9", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz", + "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==", "license": "MIT", "dependencies": { - "@vue/devtools-shared": "^7.7.7", + "@vue/devtools-shared": "^7.7.9", "birpc": "^2.3.0", "hookable": "^5.5.3", "mitt": "^3.0.1", @@ -2682,664 +560,113 @@ } }, "node_modules/@vue/devtools-shared": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz", - "integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==", + "version": "7.7.9", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz", + "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==", "license": "MIT", "dependencies": { "rfdc": "^1.4.1" } }, - "node_modules/@vue/eslint-config-prettier": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-10.2.0.tgz", - "integrity": "sha512-GL3YBLwv/+b86yHcNNfPJxOTtVFJ4Mbc9UU3zR+KVoG7SwGTjPT+32fXamscNumElhcpXW3mT0DgzS9w32S7Bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-config-prettier": "^10.0.1", - "eslint-plugin-prettier": "^5.2.2" - }, - "peerDependencies": { - "eslint": ">= 8.21.0", - "prettier": ">= 3.0.0" - } - }, - "node_modules/@vue/eslint-config-typescript": { - "version": "14.6.0", - "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-14.6.0.tgz", - "integrity": "sha512-UpiRY/7go4Yps4mYCjkvlIbVWmn9YvPGQDxTAlcKLphyaD77LjIu3plH4Y9zNT0GB4f3K5tMmhhtRhPOgrQ/bQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "^8.35.1", - "fast-glob": "^3.3.3", - "typescript-eslint": "^8.35.1", - "vue-eslint-parser": "^10.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": "^9.10.0", - "eslint-plugin-vue": "^9.28.0 || ^10.0.0", - "typescript": ">=4.8.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@vue/language-core": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.0.5.tgz", - "integrity": "sha512-gCEjn9Ik7I/seHVNIEipOm8W+f3/kg60e8s1IgIkMYma2wu9ZGUTMv3mSL2bX+Md2L8fslceJ4SU8j1fgSRoiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@volar/language-core": "2.4.22", - "@vue/compiler-dom": "^3.5.0", - "@vue/compiler-vue2": "^2.7.16", - "@vue/shared": "^3.5.0", - "alien-signals": "^2.0.5", - "muggle-string": "^0.4.1", - "path-browserify": "^1.0.1", - "picomatch": "^4.0.2" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@vue/language-core/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@vue/reactivity": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.18.tgz", - "integrity": "sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.32.tgz", + "integrity": "sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ==", "license": "MIT", "dependencies": { - "@vue/shared": "3.5.18" + "@vue/shared": "3.5.32" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.18.tgz", - "integrity": "sha512-DUpHa1HpeOQEt6+3nheUfqVXRog2kivkXHUhoqJiKR33SO4x+a5uNOMkV487WPerQkL0vUuRvq/7JhRgLW3S+w==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.32.tgz", + "integrity": "sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.18", - "@vue/shared": "3.5.18" + "@vue/reactivity": "3.5.32", + "@vue/shared": "3.5.32" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.18.tgz", - "integrity": "sha512-YwDj71iV05j4RnzZnZtGaXwPoUWeRsqinblgVJwR8XTXYZ9D5PbahHQgsbmzUvCWNF6x7siQ89HgnX5eWkr3mw==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.32.tgz", + "integrity": "sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.18", - "@vue/runtime-core": "3.5.18", - "@vue/shared": "3.5.18", - "csstype": "^3.1.3" + "@vue/reactivity": "3.5.32", + "@vue/runtime-core": "3.5.32", + "@vue/shared": "3.5.32", + "csstype": "^3.2.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.18.tgz", - "integrity": "sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.32.tgz", + "integrity": "sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ==", "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.18", - "@vue/shared": "3.5.18" + "@vue/compiler-ssr": "3.5.32", + "@vue/shared": "3.5.32" }, "peerDependencies": { - "vue": "3.5.18" + "vue": "3.5.32" } }, "node_modules/@vue/shared": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.18.tgz", - "integrity": "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA==", - "license": "MIT" - }, - "node_modules/@vue/test-utils": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.6.tgz", - "integrity": "sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-beautify": "^1.14.9", - "vue-component-type-helpers": "^2.0.0" - } - }, - "node_modules/@vue/tsconfig": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.7.0.tgz", - "integrity": "sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "typescript": "5.x", - "vue": "^3.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "vue": { - "optional": true - } - } - }, - "node_modules/abbrev": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", - "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/alien-signals": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-2.0.6.tgz", - "integrity": "sha512-P3TxJSe31bUHBiblg59oU1PpaWPtmxF9GhJ/cB7OkgJ0qN/ifFSKUI25/v8ZhsT+lIG6ac8DpTOplXxORX6F3Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ansis": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.1.0.tgz", - "integrity": "sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - } - }, - "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.32.tgz", + "integrity": "sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==", "license": "MIT" }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", - "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", - "dev": true, "license": "MIT" }, "node_modules/axios": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", - "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", - "dev": true, + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz", + "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/axios/node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true, - "license": "MIT" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tweetnacl": "^0.14.3" + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" } }, "node_modules/birpc": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.5.0.tgz", - "integrity": "sha512-VSWO/W6nNQdyP520F1mhf+Lc2f8pjGQOtoHHm7Ze8Go1kX7akpVIrtTa0fn+HB0QJEDVacl6aO08YE0PgXfdnQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz", + "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/antfu" } }, - "node_modules/blob-util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", - "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true, - "license": "ISC" - }, - "node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.25.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", - "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", - "dev": true, + "node_modules/bootstrap": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, { "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" + "url": "https://opencollective.com/bootstrap" } ], "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001726", - "electron-to-chromium": "^1.5.173", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/bundle-name": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "run-applescript": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cachedir": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", - "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" + "peerDependencies": { + "@popperjs/core": "^2.11.8" } }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -3349,243 +676,10 @@ "node": ">= 0.4" } }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001731", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz", - "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/chai": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz", - "integrity": "sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, - "node_modules/check-more-types": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", - "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-table3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", - "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "colors": "1.4.0" - } - }, - "node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -3594,342 +688,50 @@ "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/config-chain/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, "node_modules/copy-anything": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", - "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz", + "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==", "license": "MIT", "dependencies": { - "is-what": "^4.1.8" + "is-what": "^5.2.0" }, "engines": { - "node": ">=12.13" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/mesqueeb" } }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssstyle": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", - "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@asamuzakjp/css-color": "^3.2.0", - "rrweb-cssom": "^0.8.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT" }, - "node_modules/cypress": { - "version": "14.5.3", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-14.5.3.tgz", - "integrity": "sha512-syLwKjDeMg77FRRx68bytLdlqHXDT4yBVh0/PPkcgesChYDjUZbwxLqMXuryYKzAyJsPsQHUDW1YU74/IYEUIA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@cypress/request": "^3.0.9", - "@cypress/xvfb": "^1.2.4", - "@types/sinonjs__fake-timers": "8.1.1", - "@types/sizzle": "^2.3.2", - "arch": "^2.2.0", - "blob-util": "^2.0.2", - "bluebird": "^3.7.2", - "buffer": "^5.7.1", - "cachedir": "^2.3.0", - "chalk": "^4.1.0", - "check-more-types": "^2.24.0", - "ci-info": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-table3": "0.6.1", - "commander": "^6.2.1", - "common-tags": "^1.8.0", - "dayjs": "^1.10.4", - "debug": "^4.3.4", - "enquirer": "^2.3.6", - "eventemitter2": "6.4.7", - "execa": "4.1.0", - "executable": "^4.1.1", - "extract-zip": "2.0.1", - "figures": "^3.2.0", - "fs-extra": "^9.1.0", - "getos": "^3.2.1", - "hasha": "5.2.2", - "is-installed-globally": "~0.4.0", - "lazy-ass": "^1.6.0", - "listr2": "^3.8.3", - "lodash": "^4.17.21", - "log-symbols": "^4.0.0", - "minimist": "^1.2.8", - "ospath": "^1.2.2", - "pretty-bytes": "^5.6.0", - "process": "^0.11.10", - "proxy-from-env": "1.0.0", - "request-progress": "^3.0.0", - "semver": "^7.7.1", - "supports-color": "^8.1.1", - "tmp": "~0.2.3", - "tree-kill": "1.2.2", - "untildify": "^4.0.0", - "yauzl": "^2.10.0" - }, - "bin": { - "cypress": "bin/cypress" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - } - }, - "node_modules/cypress/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/dayjs": { - "version": "1.11.13", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", - "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", - "dev": true, - "license": "MIT" - }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", - "dev": true, - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "dev": true, - "license": "MIT" - }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/default-browser": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", - "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", - "dev": true, - "license": "MIT", - "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", - "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -3940,131 +742,10 @@ "node": ">= 0.4" } }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true, - "license": "MIT" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/editorconfig": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", - "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@one-ini/wasm": "0.1.1", - "commander": "^10.0.0", - "minimatch": "9.0.1", - "semver": "^7.5.3" - }, - "bin": { - "editorconfig": "bin/editorconfig" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/editorconfig/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/editorconfig/node_modules/minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/editorconfig/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.194", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.194.tgz", - "integrity": "sha512-SdnWJwSUot04UR51I2oPD8kuP2VI37/CADR1OHsFOUzZIvfWJBO6q11k5P/uKNyTT3cdOsnyjkrZ+DDShqYqJA==", - "dev": true, - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -4073,21 +754,10 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/error-stack-parser-es": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", - "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4097,24 +767,15 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "dev": true, - "license": "MIT" - }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -4127,7 +788,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -4139,677 +799,34 @@ "node": ">= 0.4" } }, - "node_modules/esbuild": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", - "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.8", - "@esbuild/android-arm": "0.25.8", - "@esbuild/android-arm64": "0.25.8", - "@esbuild/android-x64": "0.25.8", - "@esbuild/darwin-arm64": "0.25.8", - "@esbuild/darwin-x64": "0.25.8", - "@esbuild/freebsd-arm64": "0.25.8", - "@esbuild/freebsd-x64": "0.25.8", - "@esbuild/linux-arm": "0.25.8", - "@esbuild/linux-arm64": "0.25.8", - "@esbuild/linux-ia32": "0.25.8", - "@esbuild/linux-loong64": "0.25.8", - "@esbuild/linux-mips64el": "0.25.8", - "@esbuild/linux-ppc64": "0.25.8", - "@esbuild/linux-riscv64": "0.25.8", - "@esbuild/linux-s390x": "0.25.8", - "@esbuild/linux-x64": "0.25.8", - "@esbuild/netbsd-arm64": "0.25.8", - "@esbuild/netbsd-x64": "0.25.8", - "@esbuild/openbsd-arm64": "0.25.8", - "@esbuild/openbsd-x64": "0.25.8", - "@esbuild/openharmony-arm64": "0.25.8", - "@esbuild/sunos-x64": "0.25.8", - "@esbuild/win32-arm64": "0.25.8", - "@esbuild/win32-ia32": "0.25.8", - "@esbuild/win32-x64": "0.25.8" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz", - "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.0", - "@eslint/core": "^0.15.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.32.0", - "@eslint/plugin-kit": "^0.3.4", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-config-prettier": { - "version": "10.1.8", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", - "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "funding": { - "url": "https://opencollective.com/eslint-config-prettier" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-cypress": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-5.1.0.tgz", - "integrity": "sha512-tdLXm4aq9vX2hTtKJTUFD3gdNseMKqsf8+P6hI4TtOPdz1LU4xvTpQBd1++qPAsPZP2lyYh71B5mvzu2lBr4Ow==", - "dev": true, - "license": "MIT", - "dependencies": { - "globals": "^16.2.0" - }, - "peerDependencies": { - "eslint": ">=9" - } - }, - "node_modules/eslint-plugin-cypress/node_modules/globals": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz", - "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.3.tgz", - "integrity": "sha512-NAdMYww51ehKfDyDhv59/eIItUVzU0Io9H2E8nHNGKEeeqlnci+1gCvrHib6EmZdf6GxF+LCV5K7UC65Ezvw7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.11.7" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-vue": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.3.0.tgz", - "integrity": "sha512-A0u9snqjCfYaPnqqOaH6MBLVWDUIN4trXn8J3x67uDcXvR7X6Ut8p16N+nYhMCQ9Y7edg2BIRGzfyZsY0IdqoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "natural-compare": "^1.4.0", - "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.15", - "semver": "^7.6.3", - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0 || ^8.0.0", - "eslint": "^8.57.0 || ^9.0.0", - "vue-eslint-parser": "^10.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/parser": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-vue/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "license": "MIT" }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", - "dependencies": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, - "node_modules/eventemitter2": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", - "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", - "dev": true, - "license": "MIT" - }, - "node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/executable": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/expect-type": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", - "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", - "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=12.0.0" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" }, - "bin": { - "extract-zip": "cli.js" + "peerDependencies": { + "picomatch": "^3 || ^4" }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "license": "ISC" - }, "node_modules/follow-redirects": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "dev": true, "funding": [ { "type": "individual", @@ -4826,51 +843,10 @@ } } }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", - "dev": true, + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -4883,29 +859,6 @@ "node": ">= 6" } }, - "node_modules/from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", - "dev": true, - "license": "MIT" - }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -4925,27 +878,15 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -4970,7 +911,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -4980,110 +920,10 @@ "node": ">= 0.4" } }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/getos": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", - "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "async": "^3.2.0" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -5092,35 +932,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -5133,7 +948,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -5145,28 +959,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -5175,908 +971,313 @@ "node": ">= 0.4" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, "node_modules/hookable": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", "license": "MIT" }, - "node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", - "dev": true, + "node_modules/is-what": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz", + "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==", "license": "MIT", - "dependencies": { - "whatwg-encoding": "^3.1.1" - }, "engines": { "node": ">=18" - } - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/http-signature": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", - "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^2.0.2", - "sshpk": "^1.18.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-what": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", - "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", - "license": "MIT", - "engines": { - "node": ">=12.13" }, "funding": { "url": "https://github.com/sponsors/mesqueeb" } }, - "node_modules/is-wsl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "node_modules/jquery": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-4.0.0.tgz", + "integrity": "sha512-TXCHVR3Lb6TZdtw1l3RTLf8RBWVGexdxL6AC8/e0xZKEpBflBsjh9/8LXw+dkNFuOyW9B7iB3O1sP7hS0Kiacg==", + "license": "MIT" + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "is-inside-container": "^1.0.0" + "detect-libc": "^2.0.3" }, "engines": { - "node": ">=16" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "type": "opencollective", + "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" } }, - "node_modules/jiti": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", - "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/joi": { - "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "node_modules/js-beautify": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz", - "integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==", - "dev": true, - "license": "MIT", - "dependencies": { - "config-chain": "^1.1.13", - "editorconfig": "^1.0.4", - "glob": "^10.4.2", - "js-cookie": "^3.0.5", - "nopt": "^7.2.1" - }, - "bin": { - "css-beautify": "js/bin/css-beautify.js", - "html-beautify": "js/bin/html-beautify.js", - "js-beautify": "js/bin/js-beautify.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/js-cookie": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", - "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsdom": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", - "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssstyle": "^4.2.1", - "data-urls": "^5.0.0", - "decimal.js": "^10.5.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.6", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.16", - "parse5": "^7.2.1", - "rrweb-cssom": "^0.8.0", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^5.1.1", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.1.1", - "ws": "^8.18.0", - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "canvas": "^3.0.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/node_modules/xml-name-validator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", - "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "license": "(AFL-2.1 OR BSD-3-Clause)" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsprim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", - "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", - "dev": true, - "engines": [ - "node >=0.6.0" + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" ], - "license": "MIT", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kolorist": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", - "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/lazy-ass": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", - "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", - "dev": true, - "license": "MIT", + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "> 0.8" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/listr2": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", - "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.1", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "node_modules/listr2/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=10" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "dev": true, - "license": "MIT" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=10" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=10" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/log-update/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/loupe": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.0.tgz", - "integrity": "sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==", + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", - "dev": true - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -6086,7 +1287,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -6095,82 +1295,12 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/mitt": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "license": "MIT" }, - "node_modules/mrmime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/muggle-string": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", - "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", - "dev": true, - "license": "MIT" - }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -6189,456 +1319,12 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "dev": true, - "license": "MIT" - }, - "node_modules/nopt": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", - "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", - "dev": true, - "license": "ISC", - "dependencies": { - "abbrev": "^2.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-normalize-package-bin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", - "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm-run-all2": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/npm-run-all2/-/npm-run-all2-8.0.4.tgz", - "integrity": "sha512-wdbB5My48XKp2ZfJUlhnLVihzeuA1hgBnqB2J9ahV77wLS+/YAJAlN8I+X3DIFIPZ3m5L7nplmlbhNiFDmXRDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "cross-spawn": "^7.0.6", - "memorystream": "^0.3.1", - "picomatch": "^4.0.2", - "pidtree": "^0.6.0", - "read-package-json-fast": "^4.0.0", - "shell-quote": "^1.7.3", - "which": "^5.0.0" - }, - "bin": { - "npm-run-all": "bin/npm-run-all/index.js", - "npm-run-all2": "bin/npm-run-all/index.js", - "run-p": "bin/run-p/index.js", - "run-s": "bin/run-s/index.js" - }, - "engines": { - "node": "^20.5.0 || >=22.0.0", - "npm": ">= 10" - } - }, - "node_modules/npm-run-all2/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm-run-all2/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/npm-run-all2/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/npm-run-all2/node_modules/which": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", - "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/nwsapi": { - "version": "2.2.21", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.21.tgz", - "integrity": "sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ohash": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", - "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", - "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "default-browser": "^5.2.1", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "wsl-utils": "^0.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ospath": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", - "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", - "dev": true, - "license": "MIT" - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-ms": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", - "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, - "license": "MIT" - }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, - "node_modules/pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "dev": true, - "license": [ - "MIT", - "Apache2" - ], - "dependencies": { - "through": "~2.3" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true, - "license": "MIT" - }, "node_modules/perfect-debounce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", "license": "MIT" }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true, - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -6646,66 +1332,33 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pidtree": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", - "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", - "dev": true, + "node_modules/popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", + "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1", "license": "MIT", - "bin": { - "pidtree": "bin/pidtree.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinia": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.3.tgz", - "integrity": "sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==", - "license": "MIT", - "dependencies": { - "@vue/devtools-api": "^7.7.2" - }, "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "typescript": ">=4.4.4", - "vue": "^2.7.0 || ^3.5.11" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "type": "opencollective", + "url": "https://opencollective.com/popperjs" } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "funding": [ { "type": "opencollective", @@ -6730,243 +1383,19 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-ms": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", - "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", - "dev": true, - "license": "MIT", - "dependencies": { - "parse-ms": "^4.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true, - "license": "ISC" + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "license": "MIT" }, "node_modules/proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", - "dev": true, - "license": "MIT" - }, - "node_modules/ps-tree": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", - "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "event-stream": "=3.3.4" - }, - "bin": { - "ps-tree": "bin/ps-tree.js" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/pump": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "license": "MIT", "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/read-package-json-fast": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz", - "integrity": "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==", - "dev": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^4.0.0", - "npm-normalize-package-bin": "^4.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/request-progress": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", - "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "throttleit": "^1.0.0" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" + "node": ">=10" } }, "node_modules/rfdc": { @@ -6975,307 +1404,47 @@ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "license": "MIT" }, - "node_modules/rollup": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", - "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", + "node_modules/rolldown": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.12.tgz", + "integrity": "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.8" + "@oxc-project/types": "=0.122.0", + "@rolldown/pluginutils": "1.0.0-rc.12" }, "bin": { - "rollup": "dist/bin/rollup" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.46.2", - "@rollup/rollup-android-arm64": "4.46.2", - "@rollup/rollup-darwin-arm64": "4.46.2", - "@rollup/rollup-darwin-x64": "4.46.2", - "@rollup/rollup-freebsd-arm64": "4.46.2", - "@rollup/rollup-freebsd-x64": "4.46.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", - "@rollup/rollup-linux-arm-musleabihf": "4.46.2", - "@rollup/rollup-linux-arm64-gnu": "4.46.2", - "@rollup/rollup-linux-arm64-musl": "4.46.2", - "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", - "@rollup/rollup-linux-ppc64-gnu": "4.46.2", - "@rollup/rollup-linux-riscv64-gnu": "4.46.2", - "@rollup/rollup-linux-riscv64-musl": "4.46.2", - "@rollup/rollup-linux-s390x-gnu": "4.46.2", - "@rollup/rollup-linux-x64-gnu": "4.46.2", - "@rollup/rollup-linux-x64-musl": "4.46.2", - "@rollup/rollup-win32-arm64-msvc": "4.46.2", - "@rollup/rollup-win32-ia32-msvc": "4.46.2", - "@rollup/rollup-win32-x64-msvc": "4.46.2", - "fsevents": "~2.3.2" + "@rolldown/binding-android-arm64": "1.0.0-rc.12", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.12", + "@rolldown/binding-darwin-x64": "1.0.0-rc.12", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.12", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12" } }, - "node_modules/rrweb-cssom": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", - "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.12.tgz", + "integrity": "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==", "dev": true, "license": "MIT" }, - "node_modules/run-applescript": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", - "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rxjs": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, - "license": "ISC", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=v12.22.7" - } - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/sirv": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.1.tgz", - "integrity": "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -7294,333 +1463,33 @@ "node": ">=0.10.0" } }, - "node_modules/split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", - "dev": true, - "license": "MIT", - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT" - }, - "node_modules/start-server-and-test": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-2.0.12.tgz", - "integrity": "sha512-U6QiS5qsz+DN5RfJJrkAXdooxMDnLZ+n5nR8kaX//ZH19SilF6b58Z3zM9zTfrNIkJepzauHo4RceSgvgUSX9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "arg": "^5.0.2", - "bluebird": "3.7.2", - "check-more-types": "2.24.0", - "debug": "4.4.1", - "execa": "5.1.1", - "lazy-ass": "1.6.0", - "ps-tree": "1.2.0", - "wait-on": "8.0.3" - }, - "bin": { - "server-test": "src/bin/start.js", - "start-server-and-test": "src/bin/start.js", - "start-test": "src/bin/start.js" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/start-server-and-test/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/start-server-and-test/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/start-server-and-test/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/std-env": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", - "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", - "dev": true, - "license": "MIT" - }, - "node_modules/stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "duplexer": "~0.1.1" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-literal": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", - "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true, - "license": "MIT" - }, "node_modules/superjson": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", - "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==", + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz", + "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", "license": "MIT", "dependencies": { - "copy-anything": "^3.0.2" + "copy-anything": "^4" }, "engines": { "node": ">=16" } }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "license": "MIT" - }, - "node_modules/synckit": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", - "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.2.9" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/synckit" - } - }, - "node_modules/throttleit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", - "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { "node": ">=12.0.0" @@ -7629,410 +1498,66 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", - "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", - "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tldts": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", - "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tldts-core": "^6.1.86" - }, - "bin": { - "tldts": "bin/cli.js" - } - }, - "node_modules/tldts-core": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", - "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", - "dev": true, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", "license": "MIT" }, - "node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.14" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", - "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tldts": "^6.1.32" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/tr46": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", - "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "license": "MIT", - "bin": { - "tree-kill": "cli.js" - } - }, - "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "license": "0BSD" - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true, - "license": "Unlicense" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } + "license": "0BSD", + "optional": true }, "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=8" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "devOptional": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.38.0.tgz", - "integrity": "sha512-FsZlrYK6bPDGoLeZRuvx2v6qrM03I0U0SnfCLPs/XCCPCFD80xU9Pg09H/K+XFa68uJuZo7l/Xhs+eDRg2l3hg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.38.0", - "@typescript-eslint/parser": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0", - "@typescript-eslint/utils": "8.38.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unplugin-utils": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.2.4.tgz", - "integrity": "sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==", - "dev": true, + "node_modules/vee-validate": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.15.1.tgz", + "integrity": "sha512-DkFsiTwEKau8VIxyZBGdO6tOudD+QoUBPuHj3e6QFqmbfCRj1ArmYWue9lEp6jLSWBIw4XPlDLjFIZNLdRAMSg==", "license": "MIT", "dependencies": { - "pathe": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=18.12.0" - }, - "funding": { - "url": "https://github.com/sponsors/sxzz" - } - }, - "node_modules/unplugin-utils/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" + "@vue/devtools-api": "^7.5.2", + "type-fest": "^4.8.3" }, "peerDependencies": { - "browserslist": ">= 4.21.0" + "vue": "^3.4.26" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], + "node_modules/vee-validate/node_modules/@vue/devtools-api": { + "version": "7.7.9", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.9.tgz", + "integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==", "license": "MIT", "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "@vue/devtools-kit": "^7.7.9" } }, "node_modules/vite": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.6.tgz", - "integrity": "sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.3.tgz", + "integrity": "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.6", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.40.0", - "tinyglobby": "^0.2.14" + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.8", + "rolldown": "1.0.0-rc.12", + "tinyglobby": "^0.2.15" }, "bin": { "vite": "bin/vite.js" @@ -8048,9 +1573,10 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.0", + "esbuild": "^0.27.0", "jiti": ">=1.21.0", "less": "^4.0.0", - "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", @@ -8063,15 +1589,18 @@ "@types/node": { "optional": true }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, "jiti": { "optional": true }, "less": { "optional": true }, - "lightningcss": { - "optional": true - }, "sass": { "optional": true }, @@ -8095,444 +1624,17 @@ } } }, - "node_modules/vite-dev-rpc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vite-dev-rpc/-/vite-dev-rpc-1.1.0.tgz", - "integrity": "sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==", - "dev": true, - "license": "MIT", - "dependencies": { - "birpc": "^2.4.0", - "vite-hot-client": "^2.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0" - } - }, - "node_modules/vite-hot-client": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vite-hot-client/-/vite-hot-client-2.1.0.tgz", - "integrity": "sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" - } - }, - "node_modules/vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vite-plugin-inspect": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-11.3.2.tgz", - "integrity": "sha512-nzwvyFQg58XSMAmKVLr2uekAxNYvAbz1lyPmCAFVIBncCgN9S/HPM+2UM9Q9cvc4JEbC5ZBgwLAdaE2onmQuKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansis": "^4.1.0", - "debug": "^4.4.1", - "error-stack-parser-es": "^1.0.5", - "ohash": "^2.0.11", - "open": "^10.2.0", - "perfect-debounce": "^1.0.0", - "sirv": "^3.0.1", - "unplugin-utils": "^0.2.4", - "vite-dev-rpc": "^1.1.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "vite": "^6.0.0 || ^7.0.0-0" - }, - "peerDependenciesMeta": { - "@nuxt/kit": { - "optional": true - } - } - }, - "node_modules/vite-plugin-vue-devtools": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-8.0.0.tgz", - "integrity": "sha512-9bWQig8UMu3nPbxX86NJv56aelpFYoBHxB5+pxuQz3pa3Tajc1ezRidj/0dnADA4/UHuVIfwIVYHOvMXYcPshg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/devtools-core": "^8.0.0", - "@vue/devtools-kit": "^8.0.0", - "@vue/devtools-shared": "^8.0.0", - "execa": "^9.6.0", - "sirv": "^3.0.1", - "vite-plugin-inspect": "^11.3.0", - "vite-plugin-vue-inspector": "^5.3.2" - }, - "engines": { - "node": ">=v14.21.3" - }, - "peerDependencies": { - "vite": "^6.0.0 || ^7.0.0-0" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/@vue/devtools-kit": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.0.0.tgz", - "integrity": "sha512-b11OeQODkE0bctdT0RhL684pEV2DPXJ80bjpywVCbFn1PxuL3bmMPDoJKjbMnnoWbrnUYXYzFfmMWBZAMhORkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/devtools-shared": "^8.0.0", - "birpc": "^2.5.0", - "hookable": "^5.5.3", - "mitt": "^3.0.1", - "perfect-debounce": "^1.0.0", - "speakingurl": "^14.0.1", - "superjson": "^2.2.2" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/@vue/devtools-shared": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.0.0.tgz", - "integrity": "sha512-jrKnbjshQCiOAJanoeJjTU7WaCg0Dz2BUal6SaR6VM/P3hiFdX5Q6Pxl73ZMnrhCxNK9nAg5hvvRGqs+6dtU1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "rfdc": "^1.4.1" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/execa": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.0.tgz", - "integrity": "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sindresorhus/merge-streams": "^4.0.0", - "cross-spawn": "^7.0.6", - "figures": "^6.1.0", - "get-stream": "^9.0.0", - "human-signals": "^8.0.1", - "is-plain-obj": "^4.1.0", - "is-stream": "^4.0.1", - "npm-run-path": "^6.0.0", - "pretty-ms": "^9.2.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^4.0.0", - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": "^18.19.0 || >=20.5.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/figures": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", - "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-unicode-supported": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/human-signals": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", - "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/npm-run-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", - "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0", - "unicorn-magic": "^0.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/strip-final-newline": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", - "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vite-plugin-vue-inspector": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-5.3.2.tgz", - "integrity": "sha512-YvEKooQcSiBTAs0DoYLfefNja9bLgkFM7NI2b07bE2SruuvX0MEa9cMaxjKVMkeCp5Nz9FRIdcN1rOdFVBeL6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.23.0", - "@babel/plugin-proposal-decorators": "^7.23.0", - "@babel/plugin-syntax-import-attributes": "^7.22.5", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-transform-typescript": "^7.22.15", - "@vue/babel-plugin-jsx": "^1.1.5", - "@vue/compiler-dom": "^3.3.4", - "kolorist": "^1.8.0", - "magic-string": "^0.30.4" - }, - "peerDependencies": { - "vite": "^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" - } - }, - "node_modules/vite/node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/vitest": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", - "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.4", - "@vitest/mocker": "3.2.4", - "@vitest/pretty-format": "^3.2.4", - "@vitest/runner": "3.2.4", - "@vitest/snapshot": "3.2.4", - "@vitest/spy": "3.2.4", - "@vitest/utils": "3.2.4", - "chai": "^5.2.0", - "debug": "^4.4.1", - "expect-type": "^1.2.1", - "magic-string": "^0.30.17", - "pathe": "^2.0.3", - "picomatch": "^4.0.2", - "std-env": "^3.9.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.14", - "tinypool": "^1.1.1", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.4", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.4", - "@vitest/ui": "3.2.4", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/debug": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "node_modules/vitest/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/vscode-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", - "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", - "dev": true, - "license": "MIT" - }, "node_modules/vue": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.18.tgz", - "integrity": "sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.32.tgz", + "integrity": "sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.18", - "@vue/compiler-sfc": "3.5.18", - "@vue/runtime-dom": "3.5.18", - "@vue/server-renderer": "3.5.18", - "@vue/shared": "3.5.18" + "@vue/compiler-dom": "3.5.32", + "@vue/compiler-sfc": "3.5.32", + "@vue/runtime-dom": "3.5.32", + "@vue/server-renderer": "3.5.32", + "@vue/shared": "3.5.32" }, "peerDependencies": { "typescript": "*" @@ -8543,67 +1645,10 @@ } } }, - "node_modules/vue-component-type-helpers": { - "version": "2.2.12", - "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.2.12.tgz", - "integrity": "sha512-YbGqHZ5/eW4SnkPNR44mKVc6ZKQoRs/Rux1sxC6rdwXb4qpbOSYfDr9DsTHolOTGmIKgM9j141mZbBeg05R1pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/vue-eslint-parser": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.2.0.tgz", - "integrity": "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "eslint-scope": "^8.2.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "esquery": "^1.6.0", - "semver": "^7.6.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - } - }, - "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/vue-eslint-parser/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/vue-router": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz", - "integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==", + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz", + "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==", "license": "MIT", "dependencies": { "@vue/devtools-api": "^6.6.4" @@ -8611,371 +1656,41 @@ "funding": { "url": "https://github.com/sponsors/posva" }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/vuex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz", + "integrity": "sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.0.0-beta.11" + }, "peerDependencies": { "vue": "^3.2.0" } }, - "node_modules/vue-router/node_modules/@vue/devtools-api": { - "version": "6.6.4", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", - "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", - "license": "MIT" - }, - "node_modules/vue-tsc": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.0.5.tgz", - "integrity": "sha512-PsTFN9lo1HJCrZw9NoqjYcAbYDXY0cOKyuW2E7naX5jcaVyWpqEsZOHN9Dws5890E8e5SDAD4L4Zam3dxG3/Cw==", - "dev": true, + "node_modules/yup": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz", + "integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==", "license": "MIT", "dependencies": { - "@volar/typescript": "2.4.22", - "@vue/language-core": "3.0.5" - }, - "bin": { - "vue-tsc": "bin/vue-tsc.js" - }, - "peerDependencies": { - "typescript": ">=5.0.0" + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" } }, - "node_modules/w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "xml-name-validator": "^5.0.0" - }, + "node_modules/yup/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=18" - } - }, - "node_modules/w3c-xmlserializer/node_modules/xml-name-validator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/wait-on": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.3.tgz", - "integrity": "sha512-nQFqAFzZDeRxsu7S3C7LbuxslHhk+gnJZHyethuGKAn2IVleIbTB9I3vJSQiSR+DifUqmdzfPMoMPJfLqMF2vw==", - "dev": true, - "license": "MIT", - "dependencies": { - "axios": "^1.8.2", - "joi": "^17.13.3", - "lodash": "^4.17.21", - "minimist": "^1.2.8", - "rxjs": "^7.8.2" - }, - "bin": { - "wait-on": "bin/wait-on" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-url": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", - "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "^5.1.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/wsl-utils": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", - "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-wsl": "^3.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true, - "license": "MIT" - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yoctocolors": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", - "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" diff --git a/kontor-vue/package.json b/kontor-vue/package.json index b5e68aa..a0d7f56 100644 --- a/kontor-vue/package.json +++ b/kontor-vue/package.json @@ -1,53 +1,29 @@ { "name": "kontor-vue", - "version": "0.0.0", "private": true, + "version": "0.0.0", "type": "module", - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, "scripts": { "dev": "vite", - "build": "run-p type-check \"build-only {@}\" --", - "preview": "vite preview", - "test:unit": "vitest", - "prepare": "cypress install", - "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'", - "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'", - "build-only": "vite build", - "type-check": "vue-tsc --build", - "lint": "eslint . --fix", - "format": "prettier --write src/" + "build": "vite build", + "preview": "vite preview" }, "dependencies": { - "pinia": "^3.0.3", - "vue": "^3.5.18", - "vue-router": "^4.5.1" + "@fortawesome/fontawesome-svg-core": "^7.2.0", + "@fortawesome/free-solid-svg-icons": "^7.2.0", + "@fortawesome/vue-fontawesome": "^3.1.3", + "axios": "^1.14.0", + "bootstrap": "^5.3.8", + "jquery": "^4.0.0", + "popper.js": "^1.16.1", + "vee-validate": "^4.15.1", + "vue": "^3.5.30", + "vue-router": "^4.6.4", + "vuex": "^4.1.0", + "yup": "^1.7.1" }, "devDependencies": { - "@tsconfig/node22": "^22.0.2", - "@types/jsdom": "^21.1.7", - "@types/node": "^22.16.5", - "@vitejs/plugin-vue": "^6.0.1", - "@vitejs/plugin-vue-jsx": "^5.0.1", - "@vitest/eslint-plugin": "^1.3.4", - "@vue/eslint-config-prettier": "^10.2.0", - "@vue/eslint-config-typescript": "^14.6.0", - "@vue/test-utils": "^2.4.6", - "@vue/tsconfig": "^0.7.0", - "cypress": "^14.5.3", - "eslint": "^9.31.0", - "eslint-plugin-cypress": "^5.1.0", - "eslint-plugin-vue": "~10.3.0", - "jiti": "^2.4.2", - "jsdom": "^26.1.0", - "npm-run-all2": "^8.0.4", - "prettier": "3.6.2", - "start-server-and-test": "^2.0.12", - "typescript": "~5.8.0", - "vite": "^7.0.6", - "vite-plugin-vue-devtools": "^8.0.0", - "vitest": "^3.2.4", - "vue-tsc": "^3.0.4" + "@vitejs/plugin-vue": "^6.0.5", + "vite": "^8.0.1" } } diff --git a/kontor-vue/public/favicon.ico b/kontor-vue/public/favicon.ico deleted file mode 100644 index df36fcf..0000000 Binary files a/kontor-vue/public/favicon.ico and /dev/null differ diff --git a/kontor-vue/public/favicon.svg b/kontor-vue/public/favicon.svg new file mode 100644 index 0000000..6893eb1 --- /dev/null +++ b/kontor-vue/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/kontor-vue/public/icons.svg b/kontor-vue/public/icons.svg new file mode 100644 index 0000000..e952219 --- /dev/null +++ b/kontor-vue/public/icons.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kontor-vue/public/index.html b/kontor-vue/public/index.html deleted file mode 100644 index 3e5a139..0000000 --- a/kontor-vue/public/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - <%= htmlWebpackPlugin.options.title %> - - - -
    - - - diff --git a/kontor-vue/src/App.vue b/kontor-vue/src/App.vue index d4d805e..8ef54e6 100644 --- a/kontor-vue/src/App.vue +++ b/kontor-vue/src/App.vue @@ -1,43 +1,84 @@ - - - +}; + diff --git a/kontor-vue/src/assets/base.css b/kontor-vue/src/assets/base.css deleted file mode 100644 index 003ea41..0000000 --- a/kontor-vue/src/assets/base.css +++ /dev/null @@ -1,51 +0,0 @@ -/* color palette from */ -/* :root { - --vt-c-white: #ffffff; - --vt-c-white-soft: #f8f8f8; - --vt-c-white-mute: #f2f2f2; - - --vt-c-black: #181818; - --vt-c-black-soft: #222222; - --vt-c-black-mute: #282828; - - --vt-c-indigo: #2c3e50; - - --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); - --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); - --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); - --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); - - --vt-c-text-light-1: var(--vt-c-indigo); - --vt-c-text-light-2: rgba(60, 60, 60, 0.66); - --vt-c-text-dark-1: var(--vt-c-white); - --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); -} */ - -/* semantic color variables for this project */ -:root { - --color-background: var(--vt-c-white); - --color-background-soft: var(--vt-c-white-soft); - --color-background-mute: var(--vt-c-white-mute); - - --color-border: var(--vt-c-divider-light-2); - --color-border-hover: var(--vt-c-divider-light-1); - - --color-heading: var(--vt-c-text-light-1); - --color-text: var(--vt-c-text-light-1); - - --section-gap: 160px; -} - -/* @media (prefers-color-scheme: dark) { - :root { - --color-background: var(--vt-c-black); - --color-background-soft: var(--vt-c-black-soft); - --color-background-mute: var(--vt-c-black-mute); - - --color-border: var(--vt-c-divider-dark-2); - --color-border-hover: var(--vt-c-divider-dark-1); - - --color-heading: var(--vt-c-text-dark-1); - --color-text: var(--vt-c-text-dark-2); - } -} */ diff --git a/kontor-vue/src/assets/hero.png b/kontor-vue/src/assets/hero.png new file mode 100644 index 0000000..cc51a3d Binary files /dev/null and b/kontor-vue/src/assets/hero.png differ diff --git a/kontor-vue/src/assets/logo.png b/kontor-vue/src/assets/logo.png deleted file mode 100644 index f3d2503..0000000 Binary files a/kontor-vue/src/assets/logo.png and /dev/null differ diff --git a/kontor-vue/src/assets/logo.svg b/kontor-vue/src/assets/logo.svg deleted file mode 100644 index 7565660..0000000 --- a/kontor-vue/src/assets/logo.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/kontor-vue/src/assets/main.css b/kontor-vue/src/assets/main.css deleted file mode 100644 index 57b2821..0000000 --- a/kontor-vue/src/assets/main.css +++ /dev/null @@ -1,209 +0,0 @@ -@import './base.css'; - -* { - box-sizing: border-box; -} - -body { - font-family: Arial; - padding: 10px; - background: lightgrey; -} - -/* Header/Blog Title */ -.header { - padding: 30px; - text-align: center; - background-color: lightblue; -} - -.header h1 { - font-size: 50px; -} - -/* Style the top navigation bar */ -.topnav { - overflow: hidden; - background-color: darkgrey; -} - -/* Style the topnav links */ -.topnav a { - float: left; - display: block; - color: #f2f2f2; - text-align: center; - padding: 14px 16px; - text-decoration: none; -} - -/* Change color on hover */ -.topnav a:hover { - background-color: #ddd; - color: black; -} - -.subnav { - overflow: hidden; - background-color: grey; -} - -.subnav a { - float: left; - display: block; - color: #f2f2f2; - text-align: center; - padding: 14px 16px; - text-decoration: none; -} - -.form-inline { - display: flex; - flex-flow: row wrap; - align-items: center; - padding-top: 10px; - padding-left: 20px; -} - -.form-inline label { - margin: 5px 10px 5px 0; -} - -.form-inline input { - padding-right: 50px; - margin-right: 10px; -} - -.form-inline button { - padding: 10px 20px; - background-color: dodgerblue; - border: 1px solid #ddd; - color: white; - border-radius: 10px; -} - -.form-inline button:hover { - background-color: royalblue; -} - -.pill-nav a { - display: inline-block; - color: white; - background-color: dodgerblue; - text-align: center; - padding: 10px; - text-decoration: none; - border-radius: 10px; - margin-left: 20px; -} - -/* Change the color of links on mouse-over */ -.pill-nav a:hover { - background-color: royalblue; - color: white; -} - -/* Add a color to the active/current link */ -.pill-nav a.active { - background-color: royalblue; - color: white; -} - -.maincolumn { - float:left; - width: 100%; -} -/* Create two unequal columns that floats next to each other */ -/* Left column */ -.leftcolumn { - float: left; - width: 75%; -} - -/* Right column */ -.rightcolumn { - float: left; - width: 25%; - background-color: #f1f1f1; - padding-left: 20px; -} - -/* Fake image */ -.fakeimg { - background-color: #aaa; - width: 100%; - padding: 20px; -} - -/* Add a card effect for articles */ -.card { - background-color: white; - padding: 20px; - margin-top: 20px; -} - -/* Clear floats after the columns */ -.row::after { - content: ""; - display: table; - clear: both; -} - -/* Footer */ -.footer { - padding: 20px; - text-align: center; - background: #ddd; - margin-top: 20px; -} - -/* Responsive layout - when the screen is less than 800px wide, make the two columns stack on top of each other instead of next to each other */ -@media screen and (max-width: 800px) { - .leftcolumn, .rightcolumn { - width: 100%; - padding: 0; - } -} - -/* Responsive layout - when the screen is less than 400px wide, make the navigation links stack on top of each other instead of next to each other */ -@media screen and (max-width: 400px) { - .topnav a { - float: none; - width: 100%; - } -} - -/* #app { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - font-weight: normal; -} */ - -/* a, -.green { - text-decoration: none; - color: hsla(160, 100%, 37%, 1); - transition: 0.4s; - padding: 3px; -} */ - -/* @media (hover: hover) { - a:hover { - background-color: hsla(160, 100%, 37%, 0.2); - } -} */ - -/* @media (min-width: 1024px) { - body { - display: flex; - place-items: center; - } - - #app { - display: grid; - grid-template-columns: 1fr 1fr; - padding: 0 2rem; - } - -} */ diff --git a/kontor-vue/src/assets/vite.svg b/kontor-vue/src/assets/vite.svg new file mode 100644 index 0000000..5101b67 --- /dev/null +++ b/kontor-vue/src/assets/vite.svg @@ -0,0 +1 @@ +Vite diff --git a/kontor-vue/src/assets/vue.svg b/kontor-vue/src/assets/vue.svg new file mode 100644 index 0000000..770e9d3 --- /dev/null +++ b/kontor-vue/src/assets/vue.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/kontor-vue/src/components/BoardAdmin.vue b/kontor-vue/src/components/BoardAdmin.vue new file mode 100644 index 0000000..9e5efc0 --- /dev/null +++ b/kontor-vue/src/components/BoardAdmin.vue @@ -0,0 +1,36 @@ + + + + diff --git a/kontor-vue/src/components/BoardModerator.vue b/kontor-vue/src/components/BoardModerator.vue new file mode 100644 index 0000000..b1d0f4d --- /dev/null +++ b/kontor-vue/src/components/BoardModerator.vue @@ -0,0 +1,36 @@ + + + + diff --git a/kontor-vue/src/components/BoardUser.vue b/kontor-vue/src/components/BoardUser.vue new file mode 100644 index 0000000..b5ecbb1 --- /dev/null +++ b/kontor-vue/src/components/BoardUser.vue @@ -0,0 +1,35 @@ + + + diff --git a/kontor-vue/src/components/HelloWorld.vue b/kontor-vue/src/components/HelloWorld.vue new file mode 100644 index 0000000..010cb89 --- /dev/null +++ b/kontor-vue/src/components/HelloWorld.vue @@ -0,0 +1,85 @@ + + + diff --git a/kontor-vue/src/components/Home.vue b/kontor-vue/src/components/Home.vue new file mode 100644 index 0000000..3b636e6 --- /dev/null +++ b/kontor-vue/src/components/Home.vue @@ -0,0 +1,35 @@ + + + diff --git a/kontor-vue/src/components/Login.vue b/kontor-vue/src/components/Login.vue new file mode 100644 index 0000000..9e5f59e --- /dev/null +++ b/kontor-vue/src/components/Login.vue @@ -0,0 +1,96 @@ + + + + diff --git a/kontor-vue/src/components/MainHeader.vue b/kontor-vue/src/components/MainHeader.vue deleted file mode 100644 index 4c3b80e..0000000 --- a/kontor-vue/src/components/MainHeader.vue +++ /dev/null @@ -1,12 +0,0 @@ - - - \ No newline at end of file diff --git a/kontor-vue/src/components/MainNavbar.vue b/kontor-vue/src/components/MainNavbar.vue deleted file mode 100644 index cf05076..0000000 --- a/kontor-vue/src/components/MainNavbar.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/kontor-vue/src/components/Profile.vue b/kontor-vue/src/components/Profile.vue new file mode 100644 index 0000000..6e0c803 --- /dev/null +++ b/kontor-vue/src/components/Profile.vue @@ -0,0 +1,41 @@ + + + diff --git a/kontor-vue/src/components/Register.vue b/kontor-vue/src/components/Register.vue new file mode 100644 index 0000000..f6d7356 --- /dev/null +++ b/kontor-vue/src/components/Register.vue @@ -0,0 +1,123 @@ + + + diff --git a/kontor-vue/src/components/__tests__/MainHeader.spec.ts b/kontor-vue/src/components/__tests__/MainHeader.spec.ts deleted file mode 100644 index 99f4c32..0000000 --- a/kontor-vue/src/components/__tests__/MainHeader.spec.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { describe, it, expect } from 'vitest' - -import { mount } from '@vue/test-utils' -import MainHeader from '../MainHeader.vue' - -describe('MainHeader', () => { - it('renders properly', () => { - const wrapper = mount(MainHeader, { props: { headerTitle: 'Kontor' } }) - expect(wrapper.text()).toContain('Kontor') - }) -}) diff --git a/kontor-vue/src/main.js b/kontor-vue/src/main.js index 01433bc..378131c 100644 --- a/kontor-vue/src/main.js +++ b/kontor-vue/src/main.js @@ -1,4 +1,14 @@ -import { createApp } from 'vue' -import App from './App.vue' +import { createApp } from "vue"; +import "./style.css"; +import App from "./App.vue"; +import router from "./router"; +import store from "./store"; +import "bootstrap"; +import "bootstrap/dist/css/bootstrap.min.css"; +import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; -createApp(App).mount('#app') +createApp(App) + .use(router) + .use(store) + .component("font-awesome-icon", FontAwesomeIcon) + .mount("#app"); diff --git a/kontor-vue/src/main.ts b/kontor-vue/src/main.ts deleted file mode 100644 index 5dcad83..0000000 --- a/kontor-vue/src/main.ts +++ /dev/null @@ -1,14 +0,0 @@ -import './assets/main.css' - -import { createApp } from 'vue' -import { createPinia } from 'pinia' - -import App from './App.vue' -import router from './router' - -const app = createApp(App) - -app.use(createPinia()) -app.use(router) - -app.mount('#app') diff --git a/kontor-vue/src/router.js b/kontor-vue/src/router.js new file mode 100644 index 0000000..5e6e619 --- /dev/null +++ b/kontor-vue/src/router.js @@ -0,0 +1,60 @@ +import { createWebHistory, createRouter } from "vue-router"; +import Home from "./components/Home.vue"; +import Login from "./components/Login.vue"; +import Register from "./components/Register.vue"; +// lazy-loaded +const Profile = () => import("./components/Profile.vue"); +const BoardAdmin = () => import("./components/BoardAdmin.vue"); +const BoardModerator = () => import("./components/BoardModerator.vue"); +const BoardUser = () => import("./components/BoardUser.vue"); + +const routes = [ + { + path: "/", + name: "home", + component: Home, + }, + { + path: "/home", + component: Home, + }, + { + path: "/login", + component: Login, + }, + { + path: "/register", + component: Register, + }, + { + path: "/profile", + name: "profile", + // lazy-loaded + component: Profile, + }, + { + path: "/admin", + name: "admin", + // lazy-loaded + component: BoardAdmin, + }, + { + path: "/mod", + name: "moderator", + // lazy-loaded + component: BoardModerator, + }, + { + path: "/user", + name: "user", + // lazy-loaded + component: BoardUser, + }, +]; + +const router = createRouter({ + history: createWebHistory(), + routes, +}); + +export default router; diff --git a/kontor-vue/src/router/index.ts b/kontor-vue/src/router/index.ts deleted file mode 100644 index add7e10..0000000 --- a/kontor-vue/src/router/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { createRouter, createWebHistory } from 'vue-router' -import HomeView from '../views/HomeView.vue' -import ComicsView from '@/views/ComicsView.vue' - -const router = createRouter({ - history: createWebHistory(import.meta.env.BASE_URL), - routes: [ - { - path: '/', - name: 'home', - component: HomeView, - }, - { - path: '/comics', - name: 'comics', - component: ComicsView, - }, - { - path: '/comic/artists', - name: 'artists', - component: () => import('@/views/ComicsView.vue') - }, - ], -}) - -export default router diff --git a/kontor-vue/src/services/auth-header.js b/kontor-vue/src/services/auth-header.js new file mode 100644 index 0000000..c0ebbbe --- /dev/null +++ b/kontor-vue/src/services/auth-header.js @@ -0,0 +1,9 @@ +export default function authHeader() { + let user = JSON.parse(localStorage.getItem("user")); + + if (user && user.accessToken) { + return { Authorization: "Bearer " + user.accessToken }; + } else { + return {}; + } +} diff --git a/kontor-vue/src/services/auth.service.js b/kontor-vue/src/services/auth.service.js new file mode 100644 index 0000000..971f05f --- /dev/null +++ b/kontor-vue/src/services/auth.service.js @@ -0,0 +1,33 @@ +import axios from "axios"; + +const API_URL = "http://localhost:8200/"; + +class AuthService { + login(user) { + return axios + .post(API_URL + "api/login/token", { + username: user.username, + password: user.password, + }) + .then((response) => { + if (response.data.access_token) { + localStorage.setItem("user", JSON.stringify(response.data)); + } + return response.data; + }); + } + + logout() { + localStorage.removeItem("user"); + } + + register(user) { + return axios.post(API_URL + "signup", { + username: user.username, + email: user.email, + password: user.password, + }); + } +} + +export default new AuthService(); diff --git a/kontor-vue/src/services/user.service.js b/kontor-vue/src/services/user.service.js new file mode 100644 index 0000000..6c83836 --- /dev/null +++ b/kontor-vue/src/services/user.service.js @@ -0,0 +1,24 @@ +import axios from "axios"; +import authHeader from "./auth-header"; + +const API_URL = "http://localhost:8200/api/user/"; + +class UserService { + getPublicContent() { + return axios.get(API_URL + "profiles"); + } + + getUserBoard() { + return axios.get(API_URL + "user", { headers: authHeader() }); + } + + getModeratorBoard() { + return axios.get(API_URL + "mod", { headers: authHeader() }); + } + + getAdminBoard() { + return axios.get(API_URL + "admin", { headers: authHeader() }); + } +} + +export default new UserService(); diff --git a/kontor-vue/src/store/auth.module.js b/kontor-vue/src/store/auth.module.js new file mode 100644 index 0000000..77ee12e --- /dev/null +++ b/kontor-vue/src/store/auth.module.js @@ -0,0 +1,61 @@ +import AuthService from "../services/auth.service"; + +const user = JSON.parse(localStorage.getItem("user")); +const initialState = user + ? { status: { loggedIn: true }, user } + : { status: { loggedIn: false }, user: null }; + +export const auth = { + namespaced: true, + state: initialState, + actions: { + login({ commit }, user) { + return AuthService.login(user).then( + (user) => { + commit("loginSuccess", user); + return Promise.resolve(user); + }, + (error) => { + commit("loginFailure"); + return Promise.reject(error); + } + ); + }, + logout({ commit }) { + AuthService.logout(); + commit("logout"); + }, + register({ commit }, user) { + return AuthService.register(user).then( + (response) => { + commit("registerSuccess"); + return Promise.resolve(response.data); + }, + (error) => { + commit("registerFailure"); + return Promise.reject(error); + } + ); + }, + }, + mutations: { + loginSuccess(state, user) { + state.status.loggedIn = true; + state.user = user; + }, + loginFailure(state) { + state.status.loggedIn = false; + state.user = null; + }, + logout(state) { + state.status.loggedIn = false; + state.user = null; + }, + registerSuccess(state) { + state.status.loggedIn = false; + }, + registerFailure(state) { + state.status.loggedIn = false; + }, + }, +}; diff --git a/kontor-vue/src/store/index.js b/kontor-vue/src/store/index.js new file mode 100644 index 0000000..4c6b034 --- /dev/null +++ b/kontor-vue/src/store/index.js @@ -0,0 +1,10 @@ +import { createStore } from "vuex"; +import { auth } from "./auth.module"; + +const store = createStore({ + modules: { + auth, + }, +}); + +export default store; diff --git a/kontor-vue/src/stores/counter.ts b/kontor-vue/src/stores/counter.ts deleted file mode 100644 index b6757ba..0000000 --- a/kontor-vue/src/stores/counter.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ref, computed } from 'vue' -import { defineStore } from 'pinia' - -export const useCounterStore = defineStore('counter', () => { - const count = ref(0) - const doubleCount = computed(() => count.value * 2) - function increment() { - count.value++ - } - - return { count, doubleCount, increment } -}) diff --git a/kontor-vue/src/style.css b/kontor-vue/src/style.css new file mode 100644 index 0000000..527d4fb --- /dev/null +++ b/kontor-vue/src/style.css @@ -0,0 +1,296 @@ +:root { + --text: #6b6375; + --text-h: #08060d; + --bg: #fff; + --border: #e5e4e7; + --code-bg: #f4f3ec; + --accent: #aa3bff; + --accent-bg: rgba(170, 59, 255, 0.1); + --accent-border: rgba(170, 59, 255, 0.5); + --social-bg: rgba(244, 243, 236, 0.5); + --shadow: + rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px; + + --sans: system-ui, 'Segoe UI', Roboto, sans-serif; + --heading: system-ui, 'Segoe UI', Roboto, sans-serif; + --mono: ui-monospace, Consolas, monospace; + + font: 18px/145% var(--sans); + letter-spacing: 0.18px; + color-scheme: light dark; + color: var(--text); + background: var(--bg); + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + @media (max-width: 1024px) { + font-size: 16px; + } +} + +@media (prefers-color-scheme: dark) { + :root { + --text: #9ca3af; + --text-h: #f3f4f6; + --bg: #16171d; + --border: #2e303a; + --code-bg: #1f2028; + --accent: #c084fc; + --accent-bg: rgba(192, 132, 252, 0.15); + --accent-border: rgba(192, 132, 252, 0.5); + --social-bg: rgba(47, 48, 58, 0.5); + --shadow: + rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px; + } + + #social .button-icon { + filter: invert(1) brightness(2); + } +} + +body { + margin: 0; +} + +h1, +h2 { + font-family: var(--heading); + font-weight: 500; + color: var(--text-h); +} + +h1 { + font-size: 56px; + letter-spacing: -1.68px; + margin: 32px 0; + @media (max-width: 1024px) { + font-size: 36px; + margin: 20px 0; + } +} +h2 { + font-size: 24px; + line-height: 118%; + letter-spacing: -0.24px; + margin: 0 0 8px; + @media (max-width: 1024px) { + font-size: 20px; + } +} +p { + margin: 0; +} + +code, +.counter { + font-family: var(--mono); + display: inline-flex; + border-radius: 4px; + color: var(--text-h); +} + +code { + font-size: 15px; + line-height: 135%; + padding: 4px 8px; + background: var(--code-bg); +} + +.counter { + font-size: 16px; + padding: 5px 10px; + border-radius: 5px; + color: var(--accent); + background: var(--accent-bg); + border: 2px solid transparent; + transition: border-color 0.3s; + margin-bottom: 24px; + + &:hover { + border-color: var(--accent-border); + } + &:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + } +} + +.hero { + position: relative; + + .base, + .framework, + .vite { + inset-inline: 0; + margin: 0 auto; + } + + .base { + width: 170px; + position: relative; + z-index: 0; + } + + .framework, + .vite { + position: absolute; + } + + .framework { + z-index: 1; + top: 34px; + height: 28px; + transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg) + scale(1.4); + } + + .vite { + z-index: 0; + top: 107px; + height: 26px; + width: auto; + transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg) + scale(0.8); + } +} + +#app { + width: 1126px; + max-width: 100%; + margin: 0 auto; + text-align: center; + border-inline: 1px solid var(--border); + min-height: 100svh; + display: flex; + flex-direction: column; + box-sizing: border-box; +} + +#center { + display: flex; + flex-direction: column; + gap: 25px; + place-content: center; + place-items: center; + flex-grow: 1; + + @media (max-width: 1024px) { + padding: 32px 20px 24px; + gap: 18px; + } +} + +#next-steps { + display: flex; + border-top: 1px solid var(--border); + text-align: left; + + & > div { + flex: 1 1 0; + padding: 32px; + @media (max-width: 1024px) { + padding: 24px 20px; + } + } + + .icon { + margin-bottom: 16px; + width: 22px; + height: 22px; + } + + @media (max-width: 1024px) { + flex-direction: column; + text-align: center; + } +} + +#docs { + border-right: 1px solid var(--border); + + @media (max-width: 1024px) { + border-right: none; + border-bottom: 1px solid var(--border); + } +} + +#next-steps ul { + list-style: none; + padding: 0; + display: flex; + gap: 8px; + margin: 32px 0 0; + + .logo { + height: 18px; + } + + a { + color: var(--text-h); + font-size: 16px; + border-radius: 6px; + background: var(--social-bg); + display: flex; + padding: 6px 12px; + align-items: center; + gap: 8px; + text-decoration: none; + transition: box-shadow 0.3s; + + &:hover { + box-shadow: var(--shadow); + } + .button-icon { + height: 18px; + width: 18px; + } + } + + @media (max-width: 1024px) { + margin-top: 20px; + flex-wrap: wrap; + justify-content: center; + + li { + flex: 1 1 calc(50% - 8px); + } + + a { + width: 100%; + justify-content: center; + box-sizing: border-box; + } + } +} + +#spacer { + height: 88px; + border-top: 1px solid var(--border); + @media (max-width: 1024px) { + height: 48px; + } +} + +.ticks { + position: relative; + width: 100%; + + &::before, + &::after { + content: ''; + position: absolute; + top: -4.5px; + border: 5px solid transparent; + } + + &::before { + left: 0; + border-left-color: var(--border); + } + &::after { + right: 0; + border-right-color: var(--border); + } +} diff --git a/kontor-vue/src/views/ComicsView.vue b/kontor-vue/src/views/ComicsView.vue deleted file mode 100644 index 9461521..0000000 --- a/kontor-vue/src/views/ComicsView.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - \ No newline at end of file diff --git a/kontor-vue/src/views/HomeView.vue b/kontor-vue/src/views/HomeView.vue deleted file mode 100644 index 8542194..0000000 --- a/kontor-vue/src/views/HomeView.vue +++ /dev/null @@ -1,8 +0,0 @@ - - - diff --git a/kontor-vue/tsconfig.app.json b/kontor-vue/tsconfig.app.json deleted file mode 100644 index 913b8f2..0000000 --- a/kontor-vue/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "@vue/tsconfig/tsconfig.dom.json", - "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], - "exclude": ["src/**/__tests__/*"], - "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", - - "paths": { - "@/*": ["./src/*"] - } - } -} diff --git a/kontor-vue/tsconfig.json b/kontor-vue/tsconfig.json deleted file mode 100644 index 5304731..0000000 --- a/kontor-vue/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "files": [], - "references": [ - { - "path": "./tsconfig.node.json" - }, - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.vitest.json" - } - ], - "compilerOptions": { - "module": "NodeNext" - } -} diff --git a/kontor-vue/tsconfig.node.json b/kontor-vue/tsconfig.node.json deleted file mode 100644 index a83dfc9..0000000 --- a/kontor-vue/tsconfig.node.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": "@tsconfig/node22/tsconfig.json", - "include": [ - "vite.config.*", - "vitest.config.*", - "cypress.config.*", - "nightwatch.conf.*", - "playwright.config.*", - "eslint.config.*" - ], - "compilerOptions": { - "noEmit": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - - "module": "ESNext", - "moduleResolution": "Bundler", - "types": ["node"] - } -} diff --git a/kontor-vue/tsconfig.vitest.json b/kontor-vue/tsconfig.vitest.json deleted file mode 100644 index 7d1d8ce..0000000 --- a/kontor-vue/tsconfig.vitest.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "./tsconfig.app.json", - "include": ["src/**/__tests__/*", "env.d.ts"], - "exclude": [], - "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo", - - "lib": [], - "types": ["node", "jsdom"] - } -} diff --git a/kontor-vue/vite.config.js b/kontor-vue/vite.config.js new file mode 100644 index 0000000..bbcf80c --- /dev/null +++ b/kontor-vue/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [vue()], +}) diff --git a/kontor-vue/vite.config.ts b/kontor-vue/vite.config.ts deleted file mode 100644 index d49d708..0000000 --- a/kontor-vue/vite.config.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { fileURLToPath, URL } from 'node:url' - -import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' -import vueJsx from '@vitejs/plugin-vue-jsx' -import vueDevTools from 'vite-plugin-vue-devtools' - -// https://vite.dev/config/ -export default defineConfig({ - plugins: [ - vue(), - vueJsx(), - vueDevTools(), - ], - resolve: { - alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)) - }, - }, -}) diff --git a/kontor-vue/vitest.config.ts b/kontor-vue/vitest.config.ts deleted file mode 100644 index c328717..0000000 --- a/kontor-vue/vitest.config.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { fileURLToPath } from 'node:url' -import { mergeConfig, defineConfig, configDefaults } from 'vitest/config' -import viteConfig from './vite.config' - -export default mergeConfig( - viteConfig, - defineConfig({ - test: { - environment: 'jsdom', - exclude: [...configDefaults.exclude, 'e2e/**'], - root: fileURLToPath(new URL('./', import.meta.url)), - }, - }), -) diff --git a/kontor-vue/vue.config.js b/kontor-vue/vue.config.js deleted file mode 100644 index 910e297..0000000 --- a/kontor-vue/vue.config.js +++ /dev/null @@ -1,4 +0,0 @@ -const { defineConfig } = require('@vue/cli-service') -module.exports = defineConfig({ - transpileDependencies: true -}) diff --git a/kontor.tjp b/kontor.tjp deleted file mode 100644 index a5d46c6..0000000 --- a/kontor.tjp +++ /dev/null @@ -1,30 +0,0 @@ -project kontor "Kontor" "0.1.0" 2024-12-05 +5m { - timezone "Europe/Berlin" - timeformat "%d.%m.%Y" - numberformat "-" "" "" "," 1 - currencyformat "-" "" "" "," 0 - currency "EUR" - - scenario plan "Plan" { - scenario real "Realität" - } -} - -resource gcpce "Google Cloud Compute Engine" { - efficiency 0.0 - rate 0.25 -} - -task flask "Kontor-Flask" { - task import "Import repository kontor-flask into directory flask" -} -task springboot "Springboot Vaadin" { - task import "Import repository kontor-spring into directory springboot" -} - -taskreport "Arbeitsliste" { - formats html - hidetask ~isleaf() - sorttasks plan.end.up -} - diff --git a/kotlin-quarkus/.dockerignore b/kotlin-quarkus/.dockerignore deleted file mode 100644 index 4361d2f..0000000 --- a/kotlin-quarkus/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -* -!build/*-runner -!build/*-runner.jar -!build/lib/* -!build/quarkus-app/* \ No newline at end of file diff --git a/kotlin-quarkus/.gitignore b/kotlin-quarkus/.gitignore deleted file mode 100644 index 285b6ba..0000000 --- a/kotlin-quarkus/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# Gradle -.gradle/ -build/ - -# Eclipse -.project -.classpath -.settings/ -bin/ - -# IntelliJ -.idea -*.ipr -*.iml -*.iws - -# NetBeans -nb-configuration.xml - -# Visual Studio Code -.vscode -.factorypath - -# OSX -.DS_Store - -# Vim -*.swp -*.swo - -# patch -*.orig -*.rej - -# Local environment -.env diff --git a/kotlin-quarkus/README.md b/kotlin-quarkus/README.md deleted file mode 100644 index 08f2a76..0000000 --- a/kotlin-quarkus/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# kontor Project - -This project uses Quarkus, the Supersonic Subatomic Java Framework. - -If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ . - -## Running the application in dev mode - -You can run your application in dev mode that enables live coding using: -```shell script -./gradlew quarkusDev -``` - -> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/. - -## Packaging and running the application - -The application can be packaged using: -```shell script -./gradlew build -``` -It produces the `quarkus-run.jar` file in the `build/quarkus-app/` directory. -Be aware that it’s not an _über-jar_ as the dependencies are copied into the `build/quarkus-app/lib/` directory. - -The application is now runnable using `java -jar build/quarkus-app/quarkus-run.jar`. - -If you want to build an _über-jar_, execute the following command: -```shell script -./gradlew build -Dquarkus.package.type=uber-jar -``` - -The application, packaged as an _über-jar_, is now runnable using `java -jar build/*-runner.jar`. - -## Creating a native executable - -You can create a native executable using: -```shell script -./gradlew build -Dquarkus.package.type=native -``` - -Or, if you don't have GraalVM installed, you can run the native executable build in a container using: -```shell script -./gradlew build -Dquarkus.package.type=native -Dquarkus.native.container-build=true -``` - -You can then execute your native executable with: `./build/kontor-1.0.0-SNAPSHOT-runner` - -If you want to learn more about building native executables, please consult https://quarkus.io/guides/gradle-tooling. - -## Related Guides - -- JDBC Driver - H2 ([guide](https://quarkus.io/guides/datasource)): Connect to the H2 database via JDBC -- Hibernate ORM with Panache and Kotlin ([guide](https://quarkus.io/guides/hibernate-orm-panache-kotlin)): Define your persistent model in Hibernate ORM with Panache -- SmallRye OpenAPI ([guide](https://quarkus.io/guides/openapi-swaggerui)): Document your REST APIs with OpenAPI - comes with Swagger UI -- YAML Configuration ([guide](https://quarkus.io/guides/config#yaml)): Use YAML to configure your Quarkus application -- SmallRye Health ([guide](https://quarkus.io/guides/microprofile-health)): Monitor service health - -## Provided Code - -### YAML Config - -Configure your application with YAML - -[Related guide section...](https://quarkus.io/guides/config-reference#configuration-examples) - -The Quarkus application configuration is located in `src/main/resources/application.yml`. - -### RESTEasy Reactive - -Easily start your Reactive RESTful Web Services - -[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources) - -### SmallRye Health - -Monitor your application's health using SmallRye Health - -[Related guide section...](https://quarkus.io/guides/smallrye-health) diff --git a/kotlin-quarkus/build.gradle.kts b/kotlin-quarkus/build.gradle.kts deleted file mode 100644 index 0a6ac3a..0000000 --- a/kotlin-quarkus/build.gradle.kts +++ /dev/null @@ -1,45 +0,0 @@ -plugins { - java - id("io.quarkus") -} - -repositories { - mavenCentral() - mavenLocal() -} - -val quarkusPlatformGroupId: String by project -val quarkusPlatformArtifactId: String by project -val quarkusPlatformVersion: String by project - -dependencies { - implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")) - implementation("io.quarkus:quarkus-resteasy-reactive-jackson") - implementation("io.quarkus:quarkus-jdbc-h2") - implementation("io.quarkus:quarkus-hibernate-orm-panache-kotlin") - implementation("io.quarkus:quarkus-smallrye-openapi") - implementation("io.quarkus:quarkus-config-yaml") - implementation("io.quarkus:quarkus-hibernate-reactive-panache-kotlin") - implementation("io.quarkus:quarkus-smallrye-health") - implementation("io.quarkus:quarkus-arc") - implementation("io.quarkus:quarkus-resteasy-reactive") - testImplementation("io.quarkus:quarkus-junit5") - testImplementation("io.rest-assured:rest-assured") -} - -group = "de.thpeetz.kontor" -version = "1.0.0-SNAPSHOT" - -java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 -} - -tasks.withType { - systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager") -} - -tasks.withType { - options.encoding = "UTF-8" - options.compilerArgs.add("-parameters") -} diff --git a/kotlin-quarkus/gradle.properties b/kotlin-quarkus/gradle.properties deleted file mode 100644 index 1057e5c..0000000 --- a/kotlin-quarkus/gradle.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Gradle properties -quarkusPluginId=io.quarkus -quarkusPluginVersion=2.15.2.Final -quarkusPlatformGroupId=io.quarkus.platform -quarkusPlatformArtifactId=quarkus-bom -quarkusPlatformVersion=2.15.2.Final \ No newline at end of file diff --git a/kotlin-quarkus/gradle/wrapper/gradle-wrapper.jar b/kotlin-quarkus/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 62d4c05..0000000 Binary files a/kotlin-quarkus/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/kotlin-quarkus/gradle/wrapper/gradle-wrapper.properties b/kotlin-quarkus/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index ae04661..0000000 --- a/kotlin-quarkus/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/kotlin-quarkus/gradlew b/kotlin-quarkus/gradlew deleted file mode 100755 index fbd7c51..0000000 --- a/kotlin-quarkus/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed 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. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -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 - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/kotlin-quarkus/gradlew.bat b/kotlin-quarkus/gradlew.bat deleted file mode 100644 index a9f778a..0000000 --- a/kotlin-quarkus/gradlew.bat +++ /dev/null @@ -1,104 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem 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, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/kotlin-quarkus/settings.gradle.kts b/kotlin-quarkus/settings.gradle.kts deleted file mode 100644 index 043f9fc..0000000 --- a/kotlin-quarkus/settings.gradle.kts +++ /dev/null @@ -1,13 +0,0 @@ -pluginManagement { - val quarkusPluginVersion: String by settings - val quarkusPluginId: String by settings - repositories { - mavenCentral() - gradlePluginPortal() - mavenLocal() - } - plugins { - id(quarkusPluginId) version quarkusPluginVersion - } -} -rootProject.name="kontor" diff --git a/kotlin-quarkus/src/main/docker/Dockerfile.jvm b/kotlin-quarkus/src/main/docker/Dockerfile.jvm deleted file mode 100644 index 669d901..0000000 --- a/kotlin-quarkus/src/main/docker/Dockerfile.jvm +++ /dev/null @@ -1,94 +0,0 @@ -#### -# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode -# -# Before building the container image run: -# -# ./gradlew build -# -# Then, build the image with: -# -# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/kontor-jvm . -# -# Then run the container using: -# -# docker run -i --rm -p 8080:8080 quarkus/kontor-jvm -# -# If you want to include the debug port into your docker image -# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005 -# -# Then run the container using : -# -# docker run -i --rm -p 8080:8080 quarkus/kontor-jvm -# -# This image uses the `run-java.sh` script to run the application. -# This scripts computes the command line to execute your Java application, and -# includes memory/GC tuning. -# You can configure the behavior using the following environment properties: -# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") -# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options -# in JAVA_OPTS (example: "-Dsome.property=foo") -# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is -# used to calculate a default maximal heap memory based on a containers restriction. -# If used in a container without any memory constraints for the container then this -# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio -# of the container available memory as set here. The default is `50` which means 50% -# of the available memory is used as an upper boundary. You can skip this mechanism by -# setting this value to `0` in which case no `-Xmx` option is added. -# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This -# is used to calculate a default initial heap memory based on the maximum heap memory. -# If used in a container without any memory constraints for the container then this -# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio -# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` -# is used as the initial heap size. You can skip this mechanism by setting this value -# to `0` in which case no `-Xms` option is added (example: "25") -# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. -# This is used to calculate the maximum value of the initial heap memory. If used in -# a container without any memory constraints for the container then this option has -# no effect. If there is a memory constraint then `-Xms` is limited to the value set -# here. The default is 4096MB which means the calculated value of `-Xms` never will -# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") -# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output -# when things are happening. This option, if set to true, will set -# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). -# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: -# true"). -# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). -# - CONTAINER_CORE_LIMIT: A calculated core limit as described in -# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") -# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). -# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. -# (example: "20") -# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. -# (example: "40") -# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. -# (example: "4") -# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus -# previous GC times. (example: "90") -# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") -# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") -# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should -# contain the necessary JRE command-line options to specify the required GC, which -# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). -# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") -# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") -# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be -# accessed directly. (example: "foo.example.com,bar.example.com") -# -### -FROM registry.access.redhat.com/ubi8/openjdk-11:1.14 - -ENV LANGUAGE='en_US:en' - - -# We make four distinct layers so if there are application changes the library layers can be re-used -COPY --chown=185 build/quarkus-app/lib/ /deployments/lib/ -COPY --chown=185 build/quarkus-app/*.jar /deployments/ -COPY --chown=185 build/quarkus-app/app/ /deployments/app/ -COPY --chown=185 build/quarkus-app/quarkus/ /deployments/quarkus/ - -EXPOSE 8080 -USER 185 -ENV AB_JOLOKIA_OFF="" -ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" -ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" - diff --git a/kotlin-quarkus/src/main/docker/Dockerfile.legacy-jar b/kotlin-quarkus/src/main/docker/Dockerfile.legacy-jar deleted file mode 100644 index ab8ff1f..0000000 --- a/kotlin-quarkus/src/main/docker/Dockerfile.legacy-jar +++ /dev/null @@ -1,90 +0,0 @@ -#### -# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode -# -# Before building the container image run: -# -# ./gradlew build -Dquarkus.package.type=legacy-jar -# -# Then, build the image with: -# -# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/kontor-legacy-jar . -# -# Then run the container using: -# -# docker run -i --rm -p 8080:8080 quarkus/kontor-legacy-jar -# -# If you want to include the debug port into your docker image -# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005 -# -# Then run the container using : -# -# docker run -i --rm -p 8080:8080 quarkus/kontor-legacy-jar -# -# This image uses the `run-java.sh` script to run the application. -# This scripts computes the command line to execute your Java application, and -# includes memory/GC tuning. -# You can configure the behavior using the following environment properties: -# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") -# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options -# in JAVA_OPTS (example: "-Dsome.property=foo") -# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is -# used to calculate a default maximal heap memory based on a containers restriction. -# If used in a container without any memory constraints for the container then this -# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio -# of the container available memory as set here. The default is `50` which means 50% -# of the available memory is used as an upper boundary. You can skip this mechanism by -# setting this value to `0` in which case no `-Xmx` option is added. -# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This -# is used to calculate a default initial heap memory based on the maximum heap memory. -# If used in a container without any memory constraints for the container then this -# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio -# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` -# is used as the initial heap size. You can skip this mechanism by setting this value -# to `0` in which case no `-Xms` option is added (example: "25") -# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. -# This is used to calculate the maximum value of the initial heap memory. If used in -# a container without any memory constraints for the container then this option has -# no effect. If there is a memory constraint then `-Xms` is limited to the value set -# here. The default is 4096MB which means the calculated value of `-Xms` never will -# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") -# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output -# when things are happening. This option, if set to true, will set -# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). -# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: -# true"). -# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). -# - CONTAINER_CORE_LIMIT: A calculated core limit as described in -# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") -# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). -# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. -# (example: "20") -# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. -# (example: "40") -# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. -# (example: "4") -# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus -# previous GC times. (example: "90") -# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") -# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") -# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should -# contain the necessary JRE command-line options to specify the required GC, which -# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). -# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") -# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") -# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be -# accessed directly. (example: "foo.example.com,bar.example.com") -# -### -FROM registry.access.redhat.com/ubi8/openjdk-11:1.14 - -ENV LANGUAGE='en_US:en' - - -COPY build/lib/* /deployments/lib/ -COPY build/*-runner.jar /deployments/quarkus-run.jar - -EXPOSE 8080 -USER 185 -ENV AB_JOLOKIA_OFF="" -ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" -ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" diff --git a/kotlin-quarkus/src/main/docker/Dockerfile.native b/kotlin-quarkus/src/main/docker/Dockerfile.native deleted file mode 100644 index 38e4141..0000000 --- a/kotlin-quarkus/src/main/docker/Dockerfile.native +++ /dev/null @@ -1,27 +0,0 @@ -#### -# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. -# -# Before building the container image run: -# -# ./gradlew build -Dquarkus.package.type=native -# -# Then, build the image with: -# -# docker build -f src/main/docker/Dockerfile.native -t quarkus/kontor . -# -# Then run the container using: -# -# docker run -i --rm -p 8080:8080 quarkus/kontor -# -### -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6 -WORKDIR /work/ -RUN chown 1001 /work \ - && chmod "g+rwX" /work \ - && chown 1001:root /work -COPY --chown=1001:root build/*-runner /work/application - -EXPOSE 8080 -USER 1001 - -CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/kotlin-quarkus/src/main/docker/Dockerfile.native-micro b/kotlin-quarkus/src/main/docker/Dockerfile.native-micro deleted file mode 100644 index cce62e8..0000000 --- a/kotlin-quarkus/src/main/docker/Dockerfile.native-micro +++ /dev/null @@ -1,30 +0,0 @@ -#### -# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. -# It uses a micro base image, tuned for Quarkus native executables. -# It reduces the size of the resulting container image. -# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. -# -# Before building the container image run: -# -# ./gradlew build -Dquarkus.package.type=native -# -# Then, build the image with: -# -# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/kontor . -# -# Then run the container using: -# -# docker run -i --rm -p 8080:8080 quarkus/kontor -# -### -FROM quay.io/quarkus/quarkus-micro-image:1.0 -WORKDIR /work/ -RUN chown 1001 /work \ - && chmod "g+rwX" /work \ - && chown 1001:root /work -COPY --chown=1001:root build/*-runner /work/application - -EXPOSE 8080 -USER 1001 - -CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/kotlin-quarkus/src/main/resources/META-INF/resources/index.html b/kotlin-quarkus/src/main/resources/META-INF/resources/index.html deleted file mode 100644 index f64aa10..0000000 --- a/kotlin-quarkus/src/main/resources/META-INF/resources/index.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - kontor - 1.0.0-SNAPSHOT - - - -
    -
    -
    - - - - - quarkus_logo_horizontal_rgb_1280px_reverse - - - - - - - - - - - - - - - - - - -
    -
    -
    - -
    -
    -
    -

    You just made a Quarkus application.

    -

    This page is served by Quarkus.

    - Visit the Dev UI -

    This page: src/main/resources/META-INF/resources/index.html

    -

    App configuration: src/main/resources/application.yml

    -

    Static assets: src/main/resources/META-INF/resources/

    -

    Code: src/main/java

    -

    Generated starter code:

    -
      -
    • - RESTEasy Reactive Easily start your Reactive RESTful Web Services -
      @Path: /hello -
      Related guide -
    • - -
    -
    -
    -

    Selected extensions

    -
      -
    • RESTEasy Reactive Jackson
    • -
    • JDBC Driver - H2 (guide)
    • -
    • Hibernate ORM with Panache and Kotlin (guide)
    • -
    • SmallRye OpenAPI (guide)
    • -
    • YAML Configuration (guide)
    • -
    • Hibernate Reactive Panache Kotlin
    • -
    • SmallRye Health (guide)
    • -
    -
    Documentation
    -

    Practical step-by-step guides to help you achieve a specific goal. Use them to help get your work - done.

    -
    Set up your IDE
    -

    Everyone has a favorite IDE they like to use to code. Learn how to configure yours to maximize your - Quarkus productivity.

    -
    -
    -
    - - diff --git a/kotlin-quarkus/src/main/resources/application.yml b/kotlin-quarkus/src/main/resources/application.yml deleted file mode 100644 index 527a35f..0000000 --- a/kotlin-quarkus/src/main/resources/application.yml +++ /dev/null @@ -1,2 +0,0 @@ -greeting: - message: "hello" diff --git a/kotlin-quarkus/src/native-test/java/de/thpeetz/kontor/GreetingResourceIT.java b/kotlin-quarkus/src/native-test/java/de/thpeetz/kontor/GreetingResourceIT.java deleted file mode 100644 index ef71448..0000000 --- a/kotlin-quarkus/src/native-test/java/de/thpeetz/kontor/GreetingResourceIT.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.thpeetz.kontor; - -import io.quarkus.test.junit.QuarkusIntegrationTest; - -@QuarkusIntegrationTest -public class GreetingResourceIT extends GreetingResourceTest { - // Execute the same tests but in packaged mode. -} diff --git a/kotlin-spring/.gitignore b/kotlin-spring/.gitignore deleted file mode 100644 index c2065bc..0000000 --- a/kotlin-spring/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -HELP.md -.gradle -build/ -!gradle/wrapper/gradle-wrapper.jar -!**/src/main/**/build/ -!**/src/test/**/build/ - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ diff --git a/kotlin-spring/README.md b/kotlin-spring/README.md deleted file mode 100644 index 0473319..0000000 --- a/kotlin-spring/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# Kontor Kotlin - - - -## Getting started - -To make it easy for you to get started with GitLab, here's a list of recommended next steps. - -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin https://gitlab.thpeetz.de/kontor/kontor-kotlin.git -git branch -M main -git push -uf origin main -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](https://gitlab.thpeetz.de/kontor/kontor-kotlin/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. diff --git a/kotlin-spring/build.gradle b/kotlin-spring/build.gradle deleted file mode 100644 index c6df720..0000000 --- a/kotlin-spring/build.gradle +++ /dev/null @@ -1,58 +0,0 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - -plugins { - id 'org.springframework.boot' version '2.7.7' - id 'io.spring.dependency-management' version '1.0.15.RELEASE' - id 'org.jetbrains.kotlin.jvm' version '1.7.21' - id 'org.jetbrains.kotlin.plugin.spring' version '1.7.21' - id 'org.jetbrains.kotlin.plugin.jpa' version '1.7.21' - id 'org.jetbrains.kotlin.plugin.allopen' version '1.7.21' - id 'org.jetbrains.kotlin.kapt' version '1.7.21' -} - -group = 'de.thpeetz.kontor' -version = '0.0.1-SNAPSHOT' -sourceCompatibility = '11' - -repositories { - mavenCentral() -} - -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-mustache' - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'com.fasterxml.jackson.module:jackson-module-kotlin' - implementation 'org.jetbrains.kotlin:kotlin-reflect' - implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' - developmentOnly 'org.springframework.boot:spring-boot-devtools' - kapt 'org.springframework.boot:spring-boot-configuration-processor' - runtimeOnly 'com.h2database:h2' - runtimeOnly 'org.springframework.boot:spring-boot-devtools' - testImplementation("org.springframework.boot:spring-boot-starter-test") { - exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' - exclude module: 'mockito-core' - } - testImplementation 'org.junit.jupiter:junit-jupiter-api' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' - testImplementation 'com.ninja-squad:springmockk:3.1.1' - - -} - -tasks.withType(KotlinCompile) { - kotlinOptions { - freeCompilerArgs = ['-Xjsr305=strict'] - jvmTarget = '11' - } -} - -tasks.named('test') { - useJUnitPlatform() -} - -allOpen { - annotation("javax.persistence.Entity") - annotation("javax.persistence.Embeddable") - annotation("javax.persistence.MappedSuperclass") -} diff --git a/kotlin-spring/gradle/wrapper/gradle-wrapper.jar b/kotlin-spring/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e583..0000000 Binary files a/kotlin-spring/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/kotlin-spring/gradle/wrapper/gradle-wrapper.properties b/kotlin-spring/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 070cb70..0000000 --- a/kotlin-spring/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/kotlin-spring/gradlew b/kotlin-spring/gradlew deleted file mode 100644 index a69d9cb..0000000 --- a/kotlin-spring/gradlew +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed 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. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -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 - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/kotlin-spring/gradlew.bat b/kotlin-spring/gradlew.bat deleted file mode 100644 index 53a6b23..0000000 --- a/kotlin-spring/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem 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, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/kotlin-spring/settings.gradle b/kotlin-spring/settings.gradle deleted file mode 100644 index 185aa4e..0000000 --- a/kotlin-spring/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'kontor' diff --git a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/KontorApplication.kt b/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/KontorApplication.kt deleted file mode 100644 index 279b7db..0000000 --- a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/KontorApplication.kt +++ /dev/null @@ -1,16 +0,0 @@ -package de.thpeetz.kontor - -import org.springframework.boot.Banner -import org.springframework.boot.autoconfigure.SpringBootApplication -import org.springframework.boot.context.properties.EnableConfigurationProperties -import org.springframework.boot.runApplication - -@SpringBootApplication -@EnableConfigurationProperties(KontorProperties::class) -class KontorApplication - -fun main(args: Array) { - runApplication(*args) { - setBannerMode(Banner.Mode.OFF) - } -} diff --git a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/KontorConfiguration.kt b/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/KontorConfiguration.kt deleted file mode 100644 index e54f2f9..0000000 --- a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/KontorConfiguration.kt +++ /dev/null @@ -1,79 +0,0 @@ -package de.thpeetz.kontor - -import de.thpeetz.kontor.comics.* -import org.springframework.boot.ApplicationRunner -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration - -@Configuration -class KontorConfiguration { - @Bean - fun databaseInitializer(artistRepository: ArtistRepository, - publisherRepository: PublisherRepository, - comicRepository: ComicRepository, - issueRepository: IssueRepository - ) = ApplicationRunner { - - artistRepository.save(Artist("Turner, Michael")) - artistRepository.save(Artist("Bendis, Brian Michael")) - artistRepository.save(Artist("Land, Greg")) - artistRepository.save(Artist("Whedon, Joss")) - val marvel = publisherRepository.save(Publisher("Marvel")) - val aspen = publisherRepository.save(Publisher("Aspen")) - publisherRepository.save(Publisher("DC")) - val de = publisherRepository.save(Publisher("Dynamite Entertainment")) - val wildstorm = publisherRepository.save(Publisher("WildStorm")) - val bongo = publisherRepository.save(Publisher("Bongo")) - val image = publisherRepository.save(Publisher("Image")) - val darkHorse = publisherRepository.save(Publisher("Dark Horse Comics")) - val cliffhanger = publisherRepository.save(Publisher("Cliffhanger")) - comicRepository.save(Comic(title = "X-Men", publisher = marvel, currentOrder = false, completed = false)) - val redSonja = comicRepository.save(Comic(title = "Red Sonja", publisher = de, currentOrder = false, completed = false)) - val x23 = comicRepository.save(Comic(title = "X-23", publisher = marvel, currentOrder = false, completed = false)) - comicRepository.save(Comic(title = "Simpsons Comics", publisher = bongo, currentOrder = false, completed = false)) - comicRepository.save(Comic(title = "Futurama Comics", publisher = bongo, currentOrder = false, completed = false)) - comicRepository.save(Comic(title = "Bomb Queen III: The Good, The Bad and The Lovely", publisher = image, currentOrder = false, completed = false)) - comicRepository.save(Comic(title = "Bomb Queen IV: Suicide Bomber", publisher = image, currentOrder = false, completed = false)) - comicRepository.save(Comic(title = "Gen13", publisher = wildstorm, currentOrder = false, completed = false)) - val bombqueen = comicRepository.save(Comic(title = "Bomb Queen II: Queen of Hearts", publisher = image, currentOrder = false, completed = false)) - comicRepository.save(Comic(title = "Iron & The Maiden",publisher = aspen,currentOrder = false,completed = false)) - comicRepository.save(Comic(title = "Fathom",publisher = aspen,currentOrder = false,completed = false)) - comicRepository.save(Comic(title = "Soulfire",publisher = aspen,currentOrder = false,completed = false)) - comicRepository.save(Comic(title = "Star Wars: Rebellion",publisher = darkHorse,currentOrder = false,completed = false)) - comicRepository.save(Comic(title = "Star Wars: Rebellion",publisher = darkHorse,currentOrder = false,completed = false)) - comicRepository.save(Comic(title = "Star Wars: Knights of the Old Republic",publisher = darkHorse,currentOrder = false,completed = false)) - comicRepository.save(Comic(title = "Star Wars: Legacy",publisher = darkHorse,currentOrder = false,completed = false)) - comicRepository.save(Comic(title = "Star Wars: Dark Times", publisher = darkHorse, currentOrder = false, completed = false)) - comicRepository.save(Comic(title = "Samurai: Heaven and Earth", publisher = darkHorse, currentOrder = false, completed = false)) - val battlpope = comicRepository.save(Comic(title = "Battle Pope", publisher = image,currentOrder = false, completed = false)) - comicRepository.save(Comic(title = "Danger Girl", publisher = cliffhanger, currentOrder = false, completed = false)) - val marville = comicRepository.save(Comic(title = "Marville", publisher = marvel, currentOrder = false, completed = false)) - issueRepository.save(Issue(number = "0", comic = redSonja, gelesen = true)) - issueRepository.save(Issue(number = "1", comic = redSonja, gelesen = true)) - issueRepository.save(Issue(number = "2", comic = redSonja, gelesen = true)) - issueRepository.save(Issue(number = "1", comic = x23, gelesen = false)) - issueRepository.save(Issue(number = "1", comic = bombqueen, gelesen = false)) - issueRepository.save(Issue(number = "2", comic = bombqueen, gelesen = false)) - issueRepository.save(Issue(number = "3", comic = bombqueen, gelesen = false)) - issueRepository.save(Issue(number = "4", comic = bombqueen, gelesen = false)) - issueRepository.save(Issue(number = "1", comic = battlpope, gelesen = false)) - issueRepository.save(Issue(number = "2", comic = battlpope, gelesen = false)) - issueRepository.save(Issue(number = "3", comic = battlpope, gelesen = false)) - issueRepository.save(Issue(number = "4", comic = battlpope, gelesen = false)) - issueRepository.save(Issue(number = "5", comic = battlpope, gelesen = false)) - issueRepository.save(Issue(number = "6", comic = battlpope, gelesen = false)) - issueRepository.save(Issue(number = "7", comic = battlpope, gelesen = false)) - issueRepository.save(Issue(number = "8", comic = battlpope, gelesen = false)) - issueRepository.save(Issue(number = "9", comic = battlpope, gelesen = false)) - issueRepository.save(Issue(number = "10", comic = battlpope, gelesen = false)) - issueRepository.save(Issue(number = "11", comic = battlpope, gelesen = false)) - issueRepository.save(Issue(number = "12", comic = battlpope, gelesen = false)) - issueRepository.save(Issue(number = "1", comic = marville, gelesen = false)) - issueRepository.save(Issue(number = "2", comic = marville, gelesen = false)) - issueRepository.save(Issue(number = "3", comic = marville, gelesen = false)) - issueRepository.save(Issue(number = "4", comic = marville, gelesen = false)) - issueRepository.save(Issue(number = "5", comic = marville, gelesen = false)) - issueRepository.save(Issue(number = "6", comic = marville, gelesen = false)) - issueRepository.save(Issue(number = "7", comic = marville, gelesen = false)) - } -} diff --git a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/KontorController.kt b/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/KontorController.kt deleted file mode 100644 index 3d639dd..0000000 --- a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/KontorController.kt +++ /dev/null @@ -1,24 +0,0 @@ -package de.thpeetz.kontor - -import de.thpeetz.kontor.KontorProperties -import de.thpeetz.kontor.Navigation -import org.springframework.stereotype.Controller -import org.springframework.ui.Model -import org.springframework.ui.set -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.RequestMapping - -@Controller -@RequestMapping("/") -class KontorController(val properties: KontorProperties, val navigation: Navigation) { - @GetMapping("/") - fun blog(model: Model): String { - model["title"] = properties.title - model["title"] = "Kontor" - model["banner"] = properties.banner - model["version"] = properties.version - model["navigation"] = navigation.links() - model["login"] = navigation.login() - return "kontor" - } -} \ No newline at end of file diff --git a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/KontorProperties.kt b/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/KontorProperties.kt deleted file mode 100644 index 92c77c7..0000000 --- a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/KontorProperties.kt +++ /dev/null @@ -1,10 +0,0 @@ -package de.thpeetz.kontor - -import org.springframework.boot.context.properties.ConfigurationProperties -import org.springframework.boot.context.properties.ConstructorBinding - -@ConstructorBinding -@ConfigurationProperties("kontor") -data class KontorProperties(var title: String, var version: String = "unknown", val banner: Banner) { - data class Banner(val title: String? = null, val content: String) -} \ No newline at end of file diff --git a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/Navigation.kt b/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/Navigation.kt deleted file mode 100644 index fb730af..0000000 --- a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/Navigation.kt +++ /dev/null @@ -1,24 +0,0 @@ -package de.thpeetz.kontor - -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration - -@Configuration -class Navigation { - - @Bean - fun links(): Iterable = listOf( - Link("/comics", "Comics"), - Link("/library","Library"), - Link("/office", "HomeOffice"), - Link("/tradingcards", "Trading Cards"), - Link("/tysc","TradeYourSportsCards"), - Link("/user/login", ""), - Link("/admin/","Admin") - ) - - @Bean - fun login(): Iterable = listOf(Link("/user/login", "Login")) -} - -data class Link(val link: String, val title: String) diff --git a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/RequestLoggingFilter.kt b/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/RequestLoggingFilter.kt deleted file mode 100644 index decb70f..0000000 --- a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/RequestLoggingFilter.kt +++ /dev/null @@ -1,25 +0,0 @@ -package de.thpeetz.kontor - -import org.slf4j.LoggerFactory -import javax.servlet.Filter -import org.springframework.stereotype.Component -import javax.servlet.FilterChain -import javax.servlet.ServletRequest -import javax.servlet.ServletResponse - -@Component -class RequestLoggingFilter: Filter { - val loggerFactory = LoggerFactory.getLogger("Kontor Logger") - - override fun doFilter( - request: ServletRequest, - response: ServletResponse, - filterChain: FilterChain - ) { - val requestString = request.servletContext.contextPath.toString() - //val attributeNames = request.attributeNames - //attributeNames.toList().forEach { loggerFactory.info("Attribute: ${it.toString()}") } - loggerFactory.info("Logging request: $requestString") - filterChain.doFilter(request, response) - } -} \ No newline at end of file diff --git a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/comics/ComicsApiController.kt b/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/comics/ComicsApiController.kt deleted file mode 100644 index d2e3b4e..0000000 --- a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/comics/ComicsApiController.kt +++ /dev/null @@ -1,25 +0,0 @@ -package de.thpeetz.kontor.comics - -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController - -@RestController -@RequestMapping("api/") -class ComicsApiController(val artistRepository: ArtistRepository, - val publisherRepository: PublisherRepository, - val comicRepository: ComicRepository, - val issueRepository: IssueRepository) { - - @GetMapping("/artist") - fun artistList() = artistRepository.findAll() - - @GetMapping("/publisher") - fun publisherList() = publisherRepository.findAll() - - @GetMapping("/comics") - fun comicsList() = comicRepository.findAll() - - @GetMapping("/issues") - fun issuesList() = issueRepository.findAll() -} diff --git a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/comics/ComicsController.kt b/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/comics/ComicsController.kt deleted file mode 100644 index f339b04..0000000 --- a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/comics/ComicsController.kt +++ /dev/null @@ -1,29 +0,0 @@ -package de.thpeetz.kontor.comics - -import de.thpeetz.kontor.KontorProperties -import de.thpeetz.kontor.Navigation -import org.springframework.stereotype.Controller -import org.springframework.ui.Model -import org.springframework.ui.set -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.RequestMapping - -@Controller -@RequestMapping("/comics") -class ComicsController(private val properties: KontorProperties, - val navigation: Navigation, - val comicRepository: ComicRepository -) { - - @GetMapping("/") - fun blog(model: Model): String { - model["title"] = properties.title - model["title"] = "Comics" - model["banner"] = properties.banner - model["navigation"] = navigation.links() - model["comics"] = comicRepository.findAll().map { it } - return "comics" - } - - -} diff --git a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/comics/Entities.kt b/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/comics/Entities.kt deleted file mode 100644 index 3be00f5..0000000 --- a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/comics/Entities.kt +++ /dev/null @@ -1,36 +0,0 @@ -package de.thpeetz.kontor.comics - -import javax.persistence.Entity -import javax.persistence.GeneratedValue -import javax.persistence.Id -import javax.persistence.ManyToOne - - -@Entity -class Artist( - val name: String, - @Id @GeneratedValue val id: Long? = null -) - -@Entity -class Publisher( - val name: String, - @Id @GeneratedValue val id: Long? = null -) - -@Entity -class Comic( - val title: String, - @ManyToOne val publisher: Publisher, - val currentOrder: Boolean, - val completed: Boolean, - @Id @GeneratedValue val id: Long? = null -) - -@Entity -class Issue( - val number: String, - @ManyToOne val comic: Comic, - val gelesen: Boolean, - @Id @GeneratedValue val id: Long? = null -) \ No newline at end of file diff --git a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/comics/Repositories.kt b/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/comics/Repositories.kt deleted file mode 100644 index fe44b2e..0000000 --- a/kotlin-spring/src/main/kotlin/de/thpeetz/kontor/comics/Repositories.kt +++ /dev/null @@ -1,22 +0,0 @@ -package de.thpeetz.kontor.comics - -import org.springframework.data.repository.CrudRepository - -interface ArtistRepository: CrudRepository { - - override fun findAll(): Iterable -} - -interface PublisherRepository: CrudRepository { - override fun findAll(): Iterable -} - -interface ComicRepository: CrudRepository { - - override fun findAll(): Iterable -} - -interface IssueRepository: CrudRepository { - - override fun findAll(): Iterable -} \ No newline at end of file diff --git a/kotlin-spring/src/main/resources/application.properties b/kotlin-spring/src/main/resources/application.properties deleted file mode 100644 index 6d27d3a..0000000 --- a/kotlin-spring/src/main/resources/application.properties +++ /dev/null @@ -1,6 +0,0 @@ -spring.jpa.properties.hibernate.globally_quoted_identifiers=true -spring.jpa.properties.hibernate.globally_quoted_identifiers_skip_column_definitions = true -kontor.title=Kontor -kontor.version=1.0.0-SNAPSHOT -kontor.banner.title=Warning -kontor.banner.content=The blog will be down tomorrow. diff --git a/kotlin-spring/src/main/resources/templates/comics.mustache b/kotlin-spring/src/main/resources/templates/comics.mustache deleted file mode 100644 index 336d9f0..0000000 --- a/kotlin-spring/src/main/resources/templates/comics.mustache +++ /dev/null @@ -1,23 +0,0 @@ -{{> header}} - -{{> menu}} - - -
    - - - - {{#comics}} - - {{/comics}} -
    List of Comics
    Name
    {{title}}
    -
    - Add entry -
    -
    - -{{> footer}} diff --git a/kotlin-spring/src/main/resources/templates/footer.mustache b/kotlin-spring/src/main/resources/templates/footer.mustache deleted file mode 100644 index dde9847..0000000 --- a/kotlin-spring/src/main/resources/templates/footer.mustache +++ /dev/null @@ -1,22 +0,0 @@ - - - - diff --git a/kotlin-spring/src/main/resources/templates/header.mustache b/kotlin-spring/src/main/resources/templates/header.mustache deleted file mode 100644 index d794c9e..0000000 --- a/kotlin-spring/src/main/resources/templates/header.mustache +++ /dev/null @@ -1,15 +0,0 @@ - - - - - {{title}} - - - - - - - - - - diff --git a/kotlin-spring/src/main/resources/templates/kontor.mustache b/kotlin-spring/src/main/resources/templates/kontor.mustache deleted file mode 100644 index 177306f..0000000 --- a/kotlin-spring/src/main/resources/templates/kontor.mustache +++ /dev/null @@ -1,18 +0,0 @@ -{{> header}} - -{{> menu}} - -
    - {{#banner.title}} -
    - - -
    - {{/banner.title}} -
    - -{{> footer}} diff --git a/kotlin-spring/src/main/resources/templates/menu.mustache b/kotlin-spring/src/main/resources/templates/menu.mustache deleted file mode 100644 index c4d9ba0..0000000 --- a/kotlin-spring/src/main/resources/templates/menu.mustache +++ /dev/null @@ -1,23 +0,0 @@ - diff --git a/kotlin-spring/src/test/resources/junit-platform.properties b/kotlin-spring/src/test/resources/junit-platform.properties deleted file mode 100644 index ab79697..0000000 --- a/kotlin-spring/src/test/resources/junit-platform.properties +++ /dev/null @@ -1 +0,0 @@ -junit.jupiter.testinstance.lifecycle.default = per_class diff --git a/script/bootstrap b/script/bootstrap new file mode 100755 index 0000000..64b9737 --- /dev/null +++ b/script/bootstrap @@ -0,0 +1,16 @@ +#!/bin/sh + +# script/bootstrap: Resolve all dependencies that the application requires to run + +set -e + +cd "$(dirname "$0")/.." + +if command -v podman &> /dev/null; then + echo "podman is installed" +else + echo "update repositories and install podman" + sudo apt-get update &> /dev/null + sudo apt-get install podman +fi + diff --git a/script/cibuild b/script/cibuild new file mode 100755 index 0000000..af8bc23 --- /dev/null +++ b/script/cibuild @@ -0,0 +1,25 @@ +#!/bin/sh + +# script/cibuild: + +set -e + +cd "$(dirname "$0")/.." + +echo " => Baue Image localhost/kontor-spring:0.3.0" +buildah build -t kontor-spring:0.3.0 kontor-spring +echo " => Baue Image localhost/kontor-api:0.3.0" +buildah build --volume /home/tpeetz/projects/kontor/kontor-model:/container/kontor-model -t kontor-api:0.3.0 kontor-api +echo " => Baue Image localhost/kontor-quarkus:0.3.0" +buildah build -t kontor-quarkus:0.3.0 kontor-quarkus +echo " => Baue Image localhost/kontor-echo:0.3.0" +buildah build -t kontor-echo:0.3.0 kontor-echo +echo " => Baue Image localhost/kontor-fiber:0.3.0" +buildah build -t kontor-fiber:0.3.0 kontor-fiber +echo " => Baue Image localhost/kontor-javalin:0.3.0" +buildah build -t kontor-javalin:0.3.0 kontor-javalin +echo " => Baue Image localhost/kontor-vue:0.3.0" +buildah build -t kontor-vue:0.3.0 kontor-vue +echo " => Baue Image localhost/kontor-angular:0.3.0" +buildah build -t kontor-angular:0.3.0 kontor-angular + diff --git a/script/service b/script/service new file mode 100755 index 0000000..b1a8c54 --- /dev/null +++ b/script/service @@ -0,0 +1,11 @@ +#!/bin/sh + +# script/service: Setup user systemd scripts + +set -e + +cd "$(dirname "$0")/.." + +echo "==> Setting up systemd user services" +cp service/container/*.service $HOME/.config/systemd/user/ + diff --git a/script/setup b/script/setup new file mode 100755 index 0000000..3f10bbb --- /dev/null +++ b/script/setup @@ -0,0 +1,256 @@ +#!/bin/sh + +# script/setup: Set up container for the first time after cloning + +set -e + +cd "$(dirname "$0")/.." + +script/bootstrap + +#script/cibuild + + +echo "==> Setting up pod kontor" +if podman pod exists kontor; then + echo " => pod kontor exists" + if podman pod ps --filter "name=kontor" --filter "status=running"; then + echo " => pod kontor is running" + else + podman pod start kontor + fi +else + podman pod create --name kontor \ + --infra \ + -p 5432:5432 \ + -p 8100:8100 \ + -p 8200:8200 \ + -p 8300:8300 \ + -p 8400:8400 \ + -p 8500:8500 \ + -p 8600:8600 \ + -p 8700:8700 \ + -p 8800:8800 \ + -p 8900:8080 \ + -p 61616:61616 \ + -p 8161:8161 \ + -p 5672:5672 \ + --network bridge +fi + +echo "==> Setting up volume kontor-db" +if podman volume exists kontor-db; then + echo " => volume kontor-db exists" +else + podman volume create kontor-db +fi + +echo "==> Setting up volume activemq-data" +if podman volume exists activemq-data; then + echo " => volume kontor-db exists" +else + podman volume create activemq-data +fi + +echo "==> Setting up container postgres" +if podman container exists postgres; then + if podman ps -q --filter "name=postgres"; then + echo " => postgres is running" + fi +else + podman run -d --replace --pod kontor --name postgres \ + -e POSTGRES_PASSWORD=kontor \ + -e POSTGRES_DB=kontor \ + -e POSTGRES_USER=kontor \ + -v kontor-db:/var/lib/postgresql/data \ + --health-cmd='pg_isready -U kontor || exit 1' \ + --health-interval=1s \ + --health-timeout=5s \ + --health-retries=10 \ + docker.io/library/postgres:17 +fi + +echo "==> Setting up container adminer" +if podman container exists adminer; then + if podman ps -q --filter "name=adminer"; then + echo " => adminer is running" + fi +else + podman run -d --replace --pod kontor --name adminer docker.io/library/adminer +fi + +echo "==> Setting up container activemq" +if podman container exists activemq; then + if podman ps -q --filter "name=activemq"; then + echo " => adminer is running" + fi +else + podman run -d --replace --pod kontor --name activemq \ + -v activemq-data:/var/lib/artemis-instance \ + docker.io/apache/activemq-artemis:latest-alpine +fi + +echo "==> Setting up container kontor-spring" +if podman image exists localhost/kontor-spring:0.3.0; then + echo " => Image localhost/kontor-spring:0.3.0 available" +fi +if podman container exists kontor-spring; then + if podman ps -q --filter "name=kontor-spring"; then + echo " => kontor-spring is running" + fi +else + podman run -d \ + --replace \ + --pod kontor \ + --name kontor-spring \ + --label "io.containers.autoupdate=local" \ + --label "PODMAN_SYSTEMD_UNIT=container-kontor-spring.service" \ + localhost/kontor-spring:0.3.0 +fi + +echo "==> Setting up container kontor-api" +if podman image exists localhost/kontor-api:0.3.0; then + echo " => Image localhost/kontor-api:0.3.0 available" +fi +if podman container exists kontor-api; then + if podman ps -q --filter "name=kontor-api"; then + echo " => kontor-api is running" + fi +else + podman run -d \ + --replace \ + --pod kontor \ + --name kontor-api \ + --label "io.containers.autoupdate=local" \ + --label "PODMAN_SYSTEMD_UNIT=container-kontor-api.service" \ + --health-cmd='curl -f http://kontor-api:8200/health || exit 1' \ + --health-interval=1s \ + --health-timeout=5s \ + --health-retries=10 \ + localhost/kontor-api:0.3.0 +fi + +echo "==> Setting up container kontor-quarkus" +if podman image exists localhost/kontor-quarkus:0.3.0; then + echo " => Image localhost/kontor-quarkus:0.3.0 available" +fi +if podman container exists kontor-quarkus; then + if podman ps -q --filter "name=kontor-quarkus"; then + echo " => kontor-quarkus is running" + fi +else + podman run -d \ + --replace \ + --pod kontor \ + --name kontor-quarkus \ + --label "io.containers.autoupdate=local" \ + --label "PODMAN_SYSTEMD_UNIT=container-kontor-quarkus.service" \ + --health-cmd='curl -f http://kontor-quarkus:8300/q/health || exit 1' \ + --health-interval=1s \ + --health-timeout=5s \ + --health-retries=10 \ + localhost/kontor-quarkus:0.3.0 +fi + +echo "==> Setting up container kontor-echo" +if podman image exists localhost/kontor-echo:0.3.0; then + echo " => Image localhost/kontor-echo:0.3.0 available" +fi +if podman container exists kontor-echo; then + if podman ps -q --filter "name=kontor-echo"; then + echo " => kontor-echo is running" + fi +else + podman run -d \ + --replace \ + --pod kontor \ + --name kontor-echo \ + --label "io.containers.autoupdate=local" \ + --label "PODMAN_SYSTEMD_UNIT=container-kontor-echo.service" \ + --health-cmd='curl -f http://kontor-echo:8400/health || exit 1' \ + --health-interval=1s \ + --health-timeout=5s \ + --health-retries=10 \ + localhost/kontor-echo:0.3.0 +fi + +echo "==> Setting up container kontor-fiber" +if podman image exists localhost/kontor-fiber:0.3.0; then + echo " => Image localhost/kontor-fiber:0.3.0 available" +fi +if podman container exists kontor-fiber; then + if podman ps -q --filter "name=kontor-fiber"; then + echo " => kontor-fiber is running" + fi +else + podman run -d \ + --replace \ + --pod kontor \ + --name kontor-fiber \ + --label "io.containers.autoupdate=local" \ + --label "PODMAN_SYSTEMD_UNIT=container-kontor-fiber.service" \ + --health-cmd='curl -f http://kontor-echo:8500/health || exit 1' \ + --health-interval=1s \ + --health-timeout=5s \ + --health-retries=10 \ + localhost/kontor-fiber:0.3.0 +fi + +echo "==> Setting up container kontor-javalin" +if podman image exists localhost/kontor-javalin:0.3.0; then + echo " => Image localhost/kontor-javalin:0.3.0 available" +fi +if podman container exists kontor-javalin; then + if podman ps -q --filter "name=kontor-javalin"; then + echo " => kontor-javalin is running" + fi +else + podman run -d \ + --replace \ + --pod kontor \ + --name kontor-javalin \ + --label "io.containers.autoupdate=local" \ + --label "PODMAN_SYSTEMD_UNIT=container-kontor-javalin.service" \ + --health-cmd='curl -f http://kontor-echo:8600/health || exit 1' \ + --health-interval=1s \ + --health-timeout=5s \ + --health-retries=10 \ + localhost/kontor-javalin:0.3.0 +fi + +echo "==> Setting up container kontor-vue" +if podman image exists localhost/kontor-vue:0.3.0; then + echo " => Image localhost/kontor-vue:0.3.0 available" +fi +if podman container exists kontor-vue; then + if podman ps -q --filter "name=kontor-vue"; then + echo " => kontor-vue is running" + fi +else + podman run -d \ + --replace \ + --pod kontor \ + --name kontor-vue \ + --label "io.containers.autoupdate=local" \ + --label "PODMAN_SYSTEMD_UNIT=container-kontor-vue.service" \ + localhost/kontor-vue:0.3.0 +fi + +echo "==> Setting up container kontor-angular" +if podman image exists localhost/kontor-angular:0.3.0; then + echo " => Image localhost/kontor-angular:0.3.0 available" +fi +if podman container exists kontor-angular; then + if podman ps -q --filter "name=kontor-angular"; then + echo " => kontor-angular is running" + fi +else + podman run -d \ + --replace \ + --pod kontor \ + --name kontor-angular \ + --label "io.containers.autoupdate=local" \ + --label "PODMAN_SYSTEMD_UNIT=container-kontor-angular.service" \ + localhost/kontor-angular:0.3.0 +fi + diff --git a/script/test b/script/test new file mode 100755 index 0000000..c58f6ee --- /dev/null +++ b/script/test @@ -0,0 +1,8 @@ +#!/bin/sh + +# script/test: + +set -e + +cd "$(dirname "$0")/.." + diff --git a/script/update b/script/update new file mode 100755 index 0000000..fe8622b --- /dev/null +++ b/script/update @@ -0,0 +1,17 @@ +#!/bin/sh + +# script/update: + +set -e + +cd "$(dirname "$0")/.." + +echo "==> Stopping and removing pod kontor" +if podman pod exists kontor; then + podman pod stop kontor +fi + +#script/cibuild + +script/setup + diff --git a/service/container/kontor-activemq.service b/service/container/kontor-activemq.service new file mode 100644 index 0000000..4399dbd --- /dev/null +++ b/service/container/kontor-activemq.service @@ -0,0 +1,38 @@ +# kontor-activemq.service +# autogenerated by Podman 4.9.3 +# Sun Apr 19 16:28:14 CEST 2026 + +[Unit] +Description=Podman kontor-activemq.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-kontor.service +After=pod-kontor.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-kontor.pod-id \ + --sdnotify=conmon \ + -d \ + --replace \ + --name activemq \ + -v activemq-data:/var/lib/artemis-instance docker.io/apache/activemq-artemis:latest-alpine +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/service/container/kontor-adminer.service b/service/container/kontor-adminer.service new file mode 100644 index 0000000..e40587b --- /dev/null +++ b/service/container/kontor-adminer.service @@ -0,0 +1,38 @@ +# kontor-adminer.service +# autogenerated by Podman 4.9.3 +# Sun Apr 19 16:28:14 CEST 2026 + +[Unit] +Description=Podman kontor-adminer.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-kontor.service +After=pod-kontor.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-kontor.pod-id \ + --sdnotify=conmon \ + -d \ + --replace \ + --name kontor-adminer \ + docker.io/library/adminer +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/service/container/kontor-angular.service b/service/container/kontor-angular.service new file mode 100644 index 0000000..e2ff76d --- /dev/null +++ b/service/container/kontor-angular.service @@ -0,0 +1,41 @@ +# kontor-angular.service +# autogenerated by Podman 4.9.3 +# Sun Apr 19 16:28:14 CEST 2026 + +[Unit] +Description=Podman kontor-angular.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-kontor.service +After=pod-kontor.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-kontor.pod-id \ + --sdnotify=conmon \ + -d \ + --replace \ + --name kontor-angular \ + --label io.containers.autoupdate=local \ + --label PODMAN_SYSTEMD_UNIT=kontor-angular.service \ + localhost/kontor-angular:0.3.0 +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/service/container/kontor-api.service b/service/container/kontor-api.service new file mode 100644 index 0000000..ade0143 --- /dev/null +++ b/service/container/kontor-api.service @@ -0,0 +1,44 @@ +# kontor-api.service +# autogenerated by Podman 4.9.3 +# Sun Apr 19 16:28:14 CEST 2026 + +[Unit] +Description=Podmanco kontor-api.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-kontor.service +After=pod-kontor.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-kontor.pod-id \ + --sdnotify=conmon \ + -d \ + --replace \ + --name kontor-api \ + --label io.containers.autoupdate=local \ + --label PODMAN_SYSTEMD_UNIT=kontor-api.service \ + --health-cmd="curl -f http://kontor-api:8200/health || exit 1" \ + --health-interval=1s \ + --health-timeout=5s \ + --health-retries=10 \ + localhost/kontor-api:0.3.0 +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/service/container/kontor-echo.service b/service/container/kontor-echo.service new file mode 100644 index 0000000..f072d00 --- /dev/null +++ b/service/container/kontor-echo.service @@ -0,0 +1,45 @@ +# kontor-echo.service +# autogenerated by Podman 4.9.3 +# Sun Apr 19 16:28:14 CEST 2026 + +[Unit] +Description=Podman kontor-echo.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-kontor.service +After=pod-kontor.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-kontor.pod-id \ + --sdnotify=conmon \ + -d \ + --replace \ + --name kontor-echo \ + --label io.containers.autoupdate=local \ + --label PODMAN_SYSTEMD_UNIT=kontor-echo.service \ + --health-cmd="curl -f http://kontor-echo:8400/health || exit 1" \ + --health-interval=1s \ + --health-timeout=5s \ + --health-retries=10 \ + localhost/kontor-echo:0.3.0 +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/service/container/kontor-fiber.service b/service/container/kontor-fiber.service new file mode 100644 index 0000000..e77e7b5 --- /dev/null +++ b/service/container/kontor-fiber.service @@ -0,0 +1,45 @@ +# kontor-fiber.service +# autogenerated by Podman 4.9.3 +# Sun Apr 19 16:28:14 CEST 2026 + +[Unit] +Description=Podman kontor-fiber.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-kontor.service +After=pod-kontor.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-kontor.pod-id \ + --sdnotify=conmon \ + -d \ + --replace \ + --name kontor-fiber \ + --label io.containers.autoupdate=local \ + --label PODMAN_SYSTEMD_UNIT=kontor-fiber.service \ + --health-cmd="curl -f http://kontor-echo:8500/health || exit 1" \ + --health-interval=1s \ + --health-timeout=5s \ + --health-retries=10 \ + localhost/kontor-fiber:0.3.0 +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/service/container/kontor-javalin.service b/service/container/kontor-javalin.service new file mode 100644 index 0000000..ee70885 --- /dev/null +++ b/service/container/kontor-javalin.service @@ -0,0 +1,45 @@ +# kontor-javalin.service +# autogenerated by Podman 4.9.3 +# Sun Apr 19 16:28:14 CEST 2026 + +[Unit] +Description=Podman kontor-javalin.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-kontor.service +After=pod-kontor.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-kontor.pod-id \ + --sdnotify=conmon \ + -d \ + --replace \ + --name kontor-javalin \ + --label io.containers.autoupdate=local \ + --label PODMAN_SYSTEMD_UNIT=kontor-javalin.service \ + --health-cmd="curl -f http://kontor-echo:8600/health || exit 1" \ + --health-interval=1s \ + --health-timeout=5s \ + --health-retries=10 \ + localhost/kontor-javalin:0.3.0 +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/service/container/kontor-postgres.service b/service/container/kontor-postgres.service new file mode 100644 index 0000000..d5179b2 --- /dev/null +++ b/service/container/kontor-postgres.service @@ -0,0 +1,47 @@ +# kontor-postgres.service +# autogenerated by Podman 4.9.3 +# Sun Apr 19 16:28:14 CEST 2026 + +[Unit] +Description=Podman kontor-postgres.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-kontor.service +After=pod-kontor.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-kontor.pod-id \ + --sdnotify=conmon \ + -d \ + --replace \ + --name postgres \ + -e POSTGRES_PASSWORD=kontor \ + -e POSTGRES_DB=kontor \ + -e POSTGRES_USER=kontor \ + -v kontor-db:/var/lib/postgresql/data \ + --health-cmd="pg_isready -U kontor || exit 1" \ + --health-interval=1s \ + --health-timeout=5s \ + --health-retries=10 \ + docker.io/library/postgres:17 +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/service/container/kontor-quarkus.service b/service/container/kontor-quarkus.service new file mode 100644 index 0000000..05187f1 --- /dev/null +++ b/service/container/kontor-quarkus.service @@ -0,0 +1,45 @@ +# kontor-quarkus.service +# autogenerated by Podman 4.9.3 +# Sun Apr 19 16:28:14 CEST 2026 + +[Unit] +Description=Podman kontor-quarkus.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-kontor.service +After=pod-kontor.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-kontor.pod-id \ + --sdnotify=conmon \ + -d \ + --replace \ + --name kontor-quarkus \ + --label io.containers.autoupdate=local \ + --label PODMAN_SYSTEMD_UNIT=kontor-quarkus.service \ + --health-cmd="curl -f http://kontor-quarkus:8300/q/health || exit 1" \ + --health-interval=1s \ + --health-timeout=5s \ + --health-retries=10 \ + localhost/kontor-quarkus:0.3.0 +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/service/container/kontor-spring.service b/service/container/kontor-spring.service new file mode 100644 index 0000000..b3690d5 --- /dev/null +++ b/service/container/kontor-spring.service @@ -0,0 +1,41 @@ +# kontor-spring.service +# autogenerated by Podman 4.9.3 +# Sun Apr 19 16:28:14 CEST 2026 + +[Unit] +Description=Podman kontor-spring.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-kontor.service +After=pod-kontor.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-kontor.pod-id \ + --sdnotify=conmon \ + -d \ + --replace \ + --name kontor-spring \ + --label io.containers.autoupdate=local \ + --label PODMAN_SYSTEMD_UNIT=kontor-spring.service \ + localhost/kontor-spring:0.3.0 +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/service/container/kontor-vue.service b/service/container/kontor-vue.service new file mode 100644 index 0000000..b440696 --- /dev/null +++ b/service/container/kontor-vue.service @@ -0,0 +1,41 @@ +# kontor-vue.service +# autogenerated by Podman 4.9.3 +# Sun Apr 19 16:28:14 CEST 2026 + +[Unit] +Description=Podman kontor-vue.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=%t/containers +BindsTo=pod-kontor.service +After=pod-kontor.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStart=/usr/bin/podman run \ + --cidfile=%t/%n.ctr-id \ + --cgroups=no-conmon \ + --rm \ + --pod-id-file %t/pod-kontor.pod-id \ + --sdnotify=conmon \ + -d \ + --replace \ + --name kontor-vue \ + --label io.containers.autoupdate=local \ + --label PODMAN_SYSTEMD_UNIT=kontor-vue.service \ + localhost/kontor-vue:0.3.0 +ExecStop=/usr/bin/podman stop \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore -t 10 \ + --cidfile=%t/%n.ctr-id +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/service/container/pod-kontor.service b/service/container/pod-kontor.service new file mode 100644 index 0000000..e5f208d --- /dev/null +++ b/service/container/pod-kontor.service @@ -0,0 +1,53 @@ +# pod-kontor.service +# autogenerated by Podman 4.9.3 +# Sun Apr 19 16:28:14 CEST 2026 + +[Unit] +Description=Podman pod-kontor.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=/run/user/1000/containers +Wants=kontor-activemq.service kontor-adminer.service kontor-angular.service kontor-api.service kontor-echo.service kontor-fiber.service kontor-javalin.service kontor-quarkus.service kontor-spring.service kontor-vue.service kontor-postgres.service +Before=kontor-activemq.service kontor-adminer.service kontor-angular.service kontor-api.service kontor-echo.service kontor-fiber.service kontor-javalin.service kontor-quarkus.service kontor-spring.service kontor-vue.service kontor-postgres.service + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=on-failure +TimeoutStopSec=70 +ExecStartPre=/usr/bin/podman pod create \ + --infra-conmon-pidfile %t/pod-kontor.pid \ + --pod-id-file %t/pod-kontor.pod-id \ + --exit-policy=stop \ + --name kontor \ + --infra \ + -p 5432:5432 \ + -p 8100:8100 \ + -p 8200:8200 \ + -p 8300:8300 \ + -p 8400:8400 \ + -p 8500:8500 \ + -p 8600:8600 \ + -p 8700:8700 \ + -p 8800:8800 \ + -p 8900:8080 \ + -p 61616:61616 \ + -p 8161:8161 \ + -p 5672:5672 \ + --network bridge \ + --replace +ExecStart=/usr/bin/podman pod start \ + --pod-id-file %t/pod-kontor.pod-id +ExecStop=/usr/bin/podman pod stop \ + --ignore \ + --pod-id-file %t/pod-kontor.pod-id \ + -t 10 +ExecStopPost=/usr/bin/podman pod rm \ + --ignore \ + -f \ + --pod-id-file %t/pod-kontor.pod-id +PIDFile=%t/pod-kontor.pid +Type=forking + +[Install] +WantedBy=default.target diff --git a/service/standalone/kontor-api.service b/service/standalone/kontor-api.service new file mode 100644 index 0000000..42c53d4 --- /dev/null +++ b/service/standalone/kontor-api.service @@ -0,0 +1,16 @@ +[Unit] +Description=kontor-api via UV +After=network.target + +[Service] +Type=simple +User=tpeetz +Group=tpeetz +Environment="DB_SERVER=localhost" +WorkingDirectory=/home/tpeetz/projects/kontor/kontor-api +ExecStart=/home/tpeetz/projects/kontor/kontor-api/.venv/bin/uvicorn src.main:kontor --log-level info --host 127.0.0.1 --port 8200 +Restart=on-failure + +[Install] +WantedBy=multi-user.target + diff --git a/wicket/.github/workflows/gradle.yml b/wicket/.github/workflows/gradle.yml deleted file mode 100644 index 58e1c59..0000000 --- a/wicket/.github/workflows/gradle.yml +++ /dev/null @@ -1,26 +0,0 @@ -# This workflow will build a Java project with Gradle -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle - -name: Java CI with Gradle - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - name: Build with Gradle - run: ./gradlew build diff --git a/wicket/.gitignore b/wicket/.gitignore deleted file mode 100644 index 2e1f2c3..0000000 --- a/wicket/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -.gradle/ -build/ -bin/ -.classpath -.project -.settings/ -.asciidoctorconfig.adoc diff --git a/wicket/.gitlab-ci.yml b/wicket/.gitlab-ci.yml deleted file mode 100644 index 514cefd..0000000 --- a/wicket/.gitlab-ci.yml +++ /dev/null @@ -1,36 +0,0 @@ -variables: - GRADLE_OPTS: "-Dorg.gradle.daemon=false" - -before_script: - - source "/home/gitlab-runner/.sdkman/bin/sdkman-init.sh" - - sdk u java 11.0.12-open - -stages: - - build - - test - - analysis - - publish - -Build Application: - stage: build - script: ./gradlew build - -Create Documentation: - stage: build - script: ./gradlew asciidoctorPdf - -Test Application: - stage: test - script: ./gradlew check - -sonarqube-check: - stage: analysis - variables: - SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache - GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task - script: ./gradlew sonarqube - allow_failure: true - -Publish Artifacts: - stage: publish - script: ./gradlew publish diff --git a/wicket/README.md b/wicket/README.md deleted file mode 100644 index ab12d07..0000000 --- a/wicket/README.md +++ /dev/null @@ -1,4 +0,0 @@ -![Java CI with Gradle](https://github.com/tpeetz/kontor-wicket/workflows/Java%20CI%20with%20Gradle/badge.svg) - -# kontor-wicket -Kontor Application with Apache Wicket diff --git a/wicket/build.gradle b/wicket/build.gradle deleted file mode 100644 index 0afbe9f..0000000 --- a/wicket/build.gradle +++ /dev/null @@ -1,61 +0,0 @@ -plugins { - id 'war' - id 'jacoco-report-aggregation' - alias(versions.plugins.asciidoctorConvention) - alias(versions.plugins.javaConvention) - alias(versions.plugins.sonarqube) -} - -final BUILD_DATE = new Date().format('dd.MM.yyyy').toString() - -dependencies { - implementation versions.slf4j - implementation versions.commonscli - testImplementation versions.junit - implementation versions.bundles.logback - spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.12.0' - - implementation 'org.apache.wicket:wicket:9.9.1' - implementation 'org.apache.wicket:wicket-extensions:9.9.1' - testImplementation 'org.eclipse.jetty:jetty-webapp:9.4.44.v20210927' - testImplementation 'org.eclipse.jetty:jetty-jmx:9.4.44.v20210927' -} - -publishing { - publications { - application(MavenPublication) { - groupId = group - from components.java - } - } -} - -jacocoTestReport { - reports { - xml.enabled true - } -} - -test.finalizedBy jacocoTestReport - -spotbugs { - ignoreFailures = true -} - -sonarqube { - properties { - property "sonar.projectKey", "kontor_kontor-wicket_AYCAQ47WRCd9N673sSSD" - property "sonar.host.url", "https://sonar.thpeetz.de" - property "sonar.login", "7cf604ab1ebf48f7dc60d942c8196a132b228a6d" - property "sonar.qualitygate.wait", true - property "sonar.sourceEncoding", "UTF-8" - } -} - -tasks.named('sonarqube').configure { - dependsOn test -} - -wrapper { - gradleVersion = "7.5" -} diff --git a/wicket/gradle.properties b/wicket/gradle.properties deleted file mode 100644 index e140eca..0000000 --- a/wicket/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -description='Anwendung Kontor mit Apache Wicket' -group=de.thpeetz -version=1.0.0-SNAPSHOT diff --git a/wicket/gradle/wrapper/gradle-wrapper.jar b/wicket/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e583..0000000 Binary files a/wicket/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/wicket/gradle/wrapper/gradle-wrapper.properties b/wicket/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 8049c68..0000000 --- a/wicket/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/wicket/gradlew b/wicket/gradlew deleted file mode 100755 index a69d9cb..0000000 --- a/wicket/gradlew +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed 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. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -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 - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/wicket/gradlew.bat b/wicket/gradlew.bat deleted file mode 100644 index 53a6b23..0000000 --- a/wicket/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem 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, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/wicket/settings.gradle b/wicket/settings.gradle deleted file mode 100644 index f66ecb4..0000000 --- a/wicket/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = "kontor-wicket" diff --git a/wicket/src/docs/asciidoc/kontor-wicket.adoc b/wicket/src/docs/asciidoc/kontor-wicket.adoc deleted file mode 100644 index e310b6f..0000000 --- a/wicket/src/docs/asciidoc/kontor-wicket.adoc +++ /dev/null @@ -1,179 +0,0 @@ -= Projektbeschreibung kontor-wicket: Entwicklungs- und Projekthandbuch -:author: Thomas Peetz -:email: -:doctype: book -:sectnums: -:sectnumlevels: 4 -:toc: -:toclevels: 4 -:table-caption!: -:counter: table-number: 0 - -[title="Dokumenthistorie", id="Table-{counter:table-number}", options="header"] -|=== -| Version | Datum | Autor | Änderungsgrund / Bemerkungen -| 1.0.0 | 16.05.2022 | Thomas Peetz | Ersterstellung -|=== - -== Allgemeines - -=== Zweck des Dokumentes - -Das Entwicklungshandbuch beschreibt die Werkzeuge und die Vorgehensweise bei der Entwicklung -im Projekt kontor-wicket und der Erstellung der Dokumentation. - -=== Verwendete Tools - -==== Gitlab - -Für die Verwaltung des Sourcecode kommt ((Gitlab))<> zum Einsatz. -Mit Gitlab werden auch die Projektaufgaben verwaltet. - -Das Projekt und das dazugehörige Git Repository sind unter der Adresse - -https://gitlab.ingenieurbuero-peetz.de/kontor/kontor-wicket - -zu finden. - -== Erstellung der Dokumentation - -Die Dokumentation des Projektes wird mit ((Asciidoctor))<> geschrieben. -Die Dokumente erhalten ihre Namen nach dem jeweiligen Hauptdokument. - -=== Quellcode Verwaltung - -Die Asciidoctor-Dateien haben die Endung `.adoc`. - -=== Buildsystem - -Zur Erstellung der PDF-Dateien aus den Asciidoctor-Dateien wird das Buildsystem ((Gradle))<<3>> verwendet. -Die Dateien für die Dokumente liegen im Verzeichnis `src/docs/asciidoc`. - -Der Gradle Build wird über die Datei `build.gradle` definiert. - - -== Einführung - -=== Zweck - -=== Stakeholder des Systems - -=== Systemumfang - -==== Zielsetzung des Systems - -=== Systemübersicht - -==== Systemkontext - -==== Systemarchitektur - -==== Systemschnittstellen - -===== Realisierte Schnittstellen - -===== Verwendete Schnittstellen - -==== Logisches Datenmodell - -==== Einschränkungen - -== Anforderungen der Domäne - -=== Systemfunktionen - -==== Anwendungsfälle - -==== Akteure - -==== Zielgruppen - -=== Anforderungen - -==== Anforderungen an externe Schnittstellen - -==== Funktionale Anforderungen - -==== Qualitätsanforderungen - -==== Randbedingungen - -==== Weitere Anforderungen - -==== Wartungs- und Supportinformationen - -=== Verifikation - -== Projektbeschreibung - -=== Ausgangslage - -//==== Rechtliche Vorgaben und Rahmenbedingungen -//=== Rahmenbedingungen - -//==== Vorhandene Regelungen - -=== Projektziele - -=== Projektabgrenzung - -//=== Voraussichtliche Kosten - -//=== Projektrisiken - -//==== Produktivität - -//==== Finanzielle Risiken - -//==== Akzeptanz - -== Projektorganisation - -=== Projekt-Aufbauorganisation - -=== Rollendefinition - -//==== Projektauftraggeber - -//==== Projektausschuss - -//==== Beratung / Qualitätssicherung - -==== Projekteiter - -==== Projektteam - -==== Liste der Stakeholder - -=== Projektablauforganisation - -==== Projekt-Phasen - -===== Erstellung der Projektdokumentation - - -== Verschiedenes - -=== Erreichbarkeiten - -[bibliography] -== Referenzen - -- [[[asciidoctor]]] http://asciidoctor.org -- [[[gitlab]]] http://www.gitlab.org -- [[[gradle]]] http://www.gradle.org -- [[[jenkins]]] http://jenkins-ci.org - -[glossary] -== Glossar - -[index] -== Index - -== Verzeichnisse - -=== Abbildungsverzeichnis - -=== Tabellenverzeichnis - -<> <> diff --git a/wicket/src/main/java/de/thpeetz/kontor/HomePage.java b/wicket/src/main/java/de/thpeetz/kontor/HomePage.java deleted file mode 100644 index e5a3c82..0000000 --- a/wicket/src/main/java/de/thpeetz/kontor/HomePage.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.thpeetz.kontor; - -import org.apache.wicket.request.mapper.parameter.PageParameters; -import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.WebPage; - -public class HomePage extends WebPage { - private static final long serialVersionUID = 1L; - - public HomePage(final PageParameters parameters) { - super(parameters); - - add(new Label("version", getApplication().getFrameworkSettings().getVersion())); - - // TODO Add your page's components here - - } -} diff --git a/wicket/src/main/java/de/thpeetz/kontor/KontorApplication.java b/wicket/src/main/java/de/thpeetz/kontor/KontorApplication.java deleted file mode 100644 index 9c39858..0000000 --- a/wicket/src/main/java/de/thpeetz/kontor/KontorApplication.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.thpeetz.kontor; - -import org.apache.wicket.csp.CSPDirective; -import org.apache.wicket.csp.CSPDirectiveSrcValue; -import org.apache.wicket.markup.html.WebPage; -import org.apache.wicket.protocol.http.WebApplication; - -/** - * Application object for your web application. - * If you want to run this application without deploying, run the Start class. - * - * @see de.thpeetz.kontor.Start#main(String[]) - */ -public class KontorApplication extends WebApplication -{ - /** - * @see org.apache.wicket.Application#getHomePage() - */ - @Override - public Class getHomePage() - { - return HomePage.class; - } - - /** - * @see org.apache.wicket.Application#init() - */ - @Override - public void init() - { - super.init(); - - // needed for the styling used by the quickstart - getCspSettings().blocking() - .add(CSPDirective.STYLE_SRC, CSPDirectiveSrcValue.SELF) - .add(CSPDirective.STYLE_SRC, "https://fonts.googleapis.com/css") - .add(CSPDirective.FONT_SRC, "https://fonts.gstatic.com"); - - // add your configuration here - } -} diff --git a/wicket/src/main/resources/de/thpeetz/kontor/HomePage.html b/wicket/src/main/resources/de/thpeetz/kontor/HomePage.html deleted file mode 100644 index 4ca32fc..0000000 --- a/wicket/src/main/resources/de/thpeetz/kontor/HomePage.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - Apache Wicket Quickstart - - - - -
    - -
    -
    -

    Congratulations!

    -

    - Your quick start works! This project is especially useful to - start developing your Wicket application or to create a test - case for a bug report. -

    -

    Get started

    -

    - You can even switch to HTTPS! -

    -

    - From here you can start hacking away at your application and - wow your clients: -

    - -

    Get help

    -

    - We are here to help! -

    - -

    Reporting a bug

    -

    - Help us help you: -

    -
      -
    1. reproduce the bug with the least amount of code
    2. -
    3. create a unit test that shows the bug
    4. -
    5. fix the bug and create a patch
    6. -
    7. attach the result of step 1, 2 or 3 to a JIRA issue
    8. -
    9. profit!
    10. -
    -

    - Please mention the correct Wicket version: 1.5-SNAPSHOT. -

    -
    -
    -
    - - diff --git a/wicket/src/main/webapp/WEB-INF/web.xml b/wicket/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index f5b288e..0000000 --- a/wicket/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - kontor-wicket - - - - - wicket.kontor-wicket - org.apache.wicket.protocol.http.WicketFilter - - applicationClassName - de.thpeetz.kontor.KontorApplication - - - - - wicket.kontor-wicket - /* - - diff --git a/wicket/src/main/webapp/logo.png b/wicket/src/main/webapp/logo.png deleted file mode 100644 index 39ec548..0000000 Binary files a/wicket/src/main/webapp/logo.png and /dev/null differ diff --git a/wicket/src/main/webapp/style.css b/wicket/src/main/webapp/style.css deleted file mode 100644 index 87576a7..0000000 --- a/wicket/src/main/webapp/style.css +++ /dev/null @@ -1,68 +0,0 @@ -body, p, li, a { font-family: georgia, times, serif;font-size:13pt;} -h1, h2, h3 { font-family: 'Yanone Kaffeesatz', arial, serif; } -body { margin:0;padding:0;} -#hd { - width : 100%; - height : 87px; - background-color : #092E67; - margin-top : 0; - padding-top : 10px; - border-bottom : 1px solid #888; - z-index : 0; -} -#ft { - position : absolute; - bottom : 0; - width : 100%; - height : 99px; - background-color : #6493D2; - border-top : 1px solid #888; - z-index : 0; -} -#logo,#bd { - width : 650px; - margin: 0 auto; - padding: 25px 50px 0 50px; -} -#logo h1 { - color : white; - font-size:36pt; - display: inline; -} -#logo img { - display:inline; - vertical-align: bottom; - margin-left : 50px; - margin-right : 5px; -} -body { margin-top : 0; padding-top : 0;} -#logo, #logo h1 { margin-top : 0; padding-top : 0;} -#bd { - position : absolute; - top : 75px; - bottom : 75px; - left : 50%; - margin-left : -325px; - z-index : 1; - overflow: auto; - background-color : #fff; - -webkit-border-radius: 10px; - -moz-border-radius: 10px; - border-radius: 10px; - -moz-box-shadow: 0px 0px 10px #888; - -webkit-box-shadow: 0px 0px 10px #888; - box-shadow: 0px 0px 10px #888; -} -a, a:visited, a:hover, a:active { - color : #6493D2; -} -h2 { - padding : 0; margin:0; - font-size:36pt; - color:#FF5500; -} -h3 { - padding : 0; margin:0; - font-size:24pt; - color:#092E67; -} diff --git a/wicket/src/test/java/de/thpeetz/kontor/Start.java b/wicket/src/test/java/de/thpeetz/kontor/Start.java deleted file mode 100644 index 49c740a..0000000 --- a/wicket/src/test/java/de/thpeetz/kontor/Start.java +++ /dev/null @@ -1,106 +0,0 @@ -package de.thpeetz.kontor; - -import java.lang.management.ManagementFactory; - -import javax.management.MBeanServer; - -import org.eclipse.jetty.jmx.MBeanContainer; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.SecureRequestCustomizer; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.SslConnectionFactory; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.eclipse.jetty.webapp.WebAppContext; - -/** - * Separate startup class for people that want to run the examples directly. Use parameter - * -Dcom.sun.management.jmxremote to startup JMX (and e.g. connect with jconsole). - */ -public class Start -{ - /** - * Main function, starts the jetty server. - * - * @param args - */ - public static void main(String[] args) - { - System.setProperty("wicket.configuration", "development"); - - Server server = new Server(); - - HttpConfiguration http_config = new HttpConfiguration(); - http_config.setSecureScheme("https"); - http_config.setSecurePort(8443); - http_config.setOutputBufferSize(32768); - - ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(http_config)); - http.setPort(8080); - http.setIdleTimeout(1000 * 60 * 60); - - server.addConnector(http); - - Resource keystore = Resource.newClassPathResource("/keystore.p12"); - if (keystore != null && keystore.exists()) - { - // if a keystore for a SSL certificate is available, start a SSL - // connector on port 8443. - // By default, the quickstart comes with a Apache Wicket Quickstart - // Certificate that expires about half way september 2031. Do not - // use this certificate anywhere important as the passwords are - // available in the source. - - SslContextFactory sslContextFactory = new SslContextFactory(); - sslContextFactory.setKeyStoreResource(keystore); - sslContextFactory.setKeyStorePassword("wicket"); - sslContextFactory.setKeyManagerPassword("wicket"); - - HttpConfiguration https_config = new HttpConfiguration(http_config); - https_config.addCustomizer(new SecureRequestCustomizer()); - - ServerConnector https = new ServerConnector(server, new SslConnectionFactory( - sslContextFactory, "http/1.1"), new HttpConnectionFactory(https_config)); - https.setPort(8443); - https.setIdleTimeout(500000); - - server.addConnector(https); - System.out.println("SSL access to the examples has been enabled on port 8443"); - System.out - .println("You can access the application using SSL on https://localhost:8443"); - System.out.println(); - } - - WebAppContext bb = new WebAppContext(); - bb.setServer(server); - bb.setContextPath("/"); - bb.setWar("src/main/webapp"); - - // uncomment the next two lines if you want to start Jetty with WebSocket (JSR-356) support - // you need org.apache.wicket:wicket-native-websocket-javax in the classpath! - // ServerContainer serverContainer = WebSocketServerContainerInitializer.configureContext(bb); - // serverContainer.addEndpoint(new WicketServerEndpointConfig()); - - // uncomment next line if you want to test with JSESSIONID encoded in the urls - // ((AbstractSessionManager) - // bb.getSessionHandler().getSessionManager()).setUsingCookies(false); - - server.setHandler(bb); - - MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); - MBeanContainer mBeanContainer = new MBeanContainer(mBeanServer); - server.addEventListener(mBeanContainer); - server.addBean(mBeanContainer); - - try - { - server.start(); - server.join(); - } catch (Exception e) { - e.printStackTrace(); - System.exit(100); - } - } -} diff --git a/wicket/src/test/java/de/thpeetz/kontor/TestHomePage.java b/wicket/src/test/java/de/thpeetz/kontor/TestHomePage.java deleted file mode 100644 index fe9c409..0000000 --- a/wicket/src/test/java/de/thpeetz/kontor/TestHomePage.java +++ /dev/null @@ -1,29 +0,0 @@ -package de.thpeetz.kontor; - -import org.apache.wicket.util.tester.WicketTester; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -/** - * Simple test using the WicketTester - */ -public class TestHomePage -{ - private WicketTester tester; - - @BeforeEach - public void setUp() - { - tester = new WicketTester(new KontorApplication()); - } - - @Test - public void homepageRendersSuccessfully() - { - //start and render the test page - tester.startPage(HomePage.class); - - //assert rendered page class - tester.assertRenderedPage(HomePage.class); - } -} diff --git a/wicket/src/test/resources/jetty/jetty-http.xml b/wicket/src/test/resources/jetty/jetty-http.xml deleted file mode 100644 index 7b39acb..0000000 --- a/wicket/src/test/resources/jetty/jetty-http.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/wicket/src/test/resources/jetty/jetty-https.xml b/wicket/src/test/resources/jetty/jetty-https.xml deleted file mode 100644 index 35100e7..0000000 --- a/wicket/src/test/resources/jetty/jetty-https.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - http/1.1 - - - - - - - - - - - - - 30000 - - - - diff --git a/wicket/src/test/resources/jetty/jetty-ssl.xml b/wicket/src/test/resources/jetty/jetty-ssl.xml deleted file mode 100644 index f23231b..0000000 --- a/wicket/src/test/resources/jetty/jetty-ssl.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - / - - - - - - SSL_RSA_WITH_DES_CBC_SHA - SSL_DHE_RSA_WITH_DES_CBC_SHA - SSL_DHE_DSS_WITH_DES_CBC_SHA - SSL_RSA_EXPORT_WITH_RC4_40_MD5 - SSL_RSA_EXPORT_WITH_DES40_CBC_SHA - SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA - SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA - TLS_RSA_WITH_AES_256_GCM_SHA384 - TLS_RSA_WITH_AES_128_GCM_SHA256 - TLS_RSA_WITH_AES_256_CBC_SHA256 - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - TLS_RSA_WITH_AES_256_CBC_SHA - TLS_RSA_WITH_AES_256_CBC_SHA - TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - TLS_DHE_RSA_WITH_AES_256_CBC_SHA - TLS_DHE_DSS_WITH_AES_256_CBC_SHA - TLS_RSA_WITH_AES_128_CBC_SHA256 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - TLS_RSA_WITH_AES_128_CBC_SHA - TLS_RSA_WITH_AES_128_CBC_SHA - TLS_RSA_WITH_AES_128_CBC_SHA - TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - TLS_DHE_RSA_WITH_AES_128_CBC_SHA - TLS_DHE_DSS_WITH_AES_128_CBC_SHA - - - - - - - - - - - - - - - diff --git a/wicket/src/test/resources/jetty/jetty.xml b/wicket/src/test/resources/jetty/jetty.xml deleted file mode 100644 index 5590715..0000000 --- a/wicket/src/test/resources/jetty/jetty.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - https - - - - 32768 - 8192 - 8192 - true - false - 512 - - - - - - diff --git a/wicket/src/test/resources/keystore b/wicket/src/test/resources/keystore deleted file mode 100644 index 1473db3..0000000 Binary files a/wicket/src/test/resources/keystore and /dev/null differ