Compare commits
99
Commits
9b8171db5b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1be7152a7 | ||
|
|
aa14131757 | ||
|
|
21a76418fe | ||
|
|
4223ec2e72 | ||
|
|
8981fe6fda | ||
|
|
f434e39c32 | ||
|
|
1417057160 | ||
|
|
742b4bfc32 | ||
|
|
bc0775eafe | ||
|
|
c778d3422c | ||
|
|
14f9040456 | ||
|
|
8dfa89c6b6 | ||
|
|
a32111fbf4 | ||
|
|
6772c5e408 | ||
|
|
156012ad64 | ||
|
|
d3429cefb4 | ||
|
|
397a1844b5 | ||
|
|
412e9f03bb | ||
|
|
76342d3d55 | ||
|
|
eced2dc1e9 | ||
|
|
e692a50efc | ||
|
|
f097fd8c43 | ||
|
|
e211b7f680 | ||
|
|
72ade7f92c | ||
|
|
72f8196acf | ||
|
|
b087d9822e | ||
|
|
785f6ac8b9 | ||
|
|
20d80d76f0 | ||
|
|
6a75825a88 | ||
|
|
5599476730 | ||
|
|
d13738069e | ||
|
|
5aec5ae176 | ||
|
|
186cf4411e | ||
|
|
435e0260e5 | ||
|
|
eaf6b09349 | ||
|
|
405639329c | ||
|
|
719b9d7000 | ||
|
|
e3270d64bf | ||
|
|
f97d8e53b1 | ||
|
|
1d8b138b62 | ||
|
|
75cc0b46f9 | ||
|
|
3cddbe4922 | ||
|
|
58645f87ea | ||
|
|
b58b56249a | ||
|
|
5ec51451ee | ||
|
|
8d4bcfdf0c | ||
|
|
8f474a1081 | ||
|
|
be28592dfa | ||
|
|
11087ead17 | ||
|
|
2bfc56ea81 | ||
|
|
dcc02ab60d | ||
|
|
4017708282 | ||
|
|
4df2a1dede | ||
|
|
b6cfe62724 | ||
|
|
96dd142899 | ||
|
|
7ae97c27a0 | ||
|
|
bbe550b8a9 | ||
|
|
de15af4302 | ||
|
|
1da5748734 | ||
|
|
b771f979ba | ||
|
|
2fec54f212 | ||
|
|
4b4db65f4d | ||
|
|
b1013ea1c1 | ||
|
|
7f8d7cbc86 | ||
|
|
bdf0466d79 | ||
|
|
ab26234c20 | ||
|
|
87651e70d4 | ||
|
|
5007a434ca | ||
|
|
57ae528057 | ||
|
|
364641c8fa | ||
|
|
d1052831ad | ||
|
|
d8785c37a0 | ||
|
|
15d431bcdd | ||
|
|
994155bc9e | ||
|
|
75b4c97545 | ||
|
|
9d9acf5483 | ||
|
|
a9bdbde640 | ||
|
|
82857bfbe2 | ||
|
|
1a605975f9 | ||
|
|
564dd8547f | ||
|
|
a309736249 | ||
|
|
38ec95a7b9 | ||
|
|
4709da935b | ||
|
|
a1ec1822cd | ||
|
|
910d8082fc | ||
|
|
f17547da9b | ||
|
|
c0ee89df6a | ||
|
|
784f187d80 | ||
|
|
c342a52465 | ||
|
|
9b28a60f8b | ||
|
|
a6b8347f16 | ||
|
|
cb69587afb | ||
|
|
5c1e6501f9 | ||
|
|
f63b3da312 | ||
|
|
d72345b2f8 | ||
|
|
bdae82dda6 | ||
|
|
98c6e9aac0 | ||
|
|
e756d3fd49 | ||
|
|
17ee42c8ea |
Generated
+3
@@ -11,6 +11,9 @@
|
|||||||
<orderEntry type="jdk" jdkName="Python 3.12 (announcementService) (2)" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.12 (announcementService) (2)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="PackageRequirementsSettings">
|
||||||
|
<option name="versionSpecifier" value="Strong equality (==x.y.z)" />
|
||||||
|
</component>
|
||||||
<component name="TemplatesService">
|
<component name="TemplatesService">
|
||||||
<option name="TEMPLATE_CONFIGURATION" value="Jinja2" />
|
<option name="TEMPLATE_CONFIGURATION" value="Jinja2" />
|
||||||
<option name="TEMPLATE_FOLDERS">
|
<option name="TEMPLATE_FOLDERS">
|
||||||
|
|||||||
Generated
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||||
<data-source source="LOCAL" name="@localhost" uuid="5bd2f97d-04d9-4780-924c-77d00c802fc5">
|
<data-source source="LOCAL" name="@localhost" uuid="5bd2f97d-04d9-4780-924c-77d00c802fc5">
|
||||||
<driver-ref>mongo</driver-ref>
|
<driver-ref>mongo.4</driver-ref>
|
||||||
<synchronize>true</synchronize>
|
<synchronize>true</synchronize>
|
||||||
<jdbc-driver>com.dbschema.MongoJdbcDriver</jdbc-driver>
|
<jdbc-driver>com.dbschema.MongoJdbcDriver</jdbc-driver>
|
||||||
<jdbc-url>mongodb://localhost:27017</jdbc-url>
|
<jdbc-url>mongodb://localhost:27017</jdbc-url>
|
||||||
|
|||||||
+127
-99
@@ -3,144 +3,172 @@ info:
|
|||||||
title: announcementService
|
title: announcementService
|
||||||
description: Announcing patchnotes for KanzleiApp
|
description: Announcing patchnotes for KanzleiApp
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- name: Patchnotes
|
||||||
|
description: Create, update and read patchnotes
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
/patchnotes:
|
/patchnotes:
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- Patchnotes
|
|
||||||
description: creates new Patch notes
|
|
||||||
requestBody:
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/patch_notes'
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: game created
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/patch_notes'
|
|
||||||
"400":
|
|
||||||
description: bad payload
|
|
||||||
get:
|
get:
|
||||||
description: returns list of all Patch notes
|
tags: [Patchnotes]
|
||||||
|
summary: Returns list of patch notes newer than the caller’s last login
|
||||||
|
operationId: listPatchnotes
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/SinceParam'
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
|
description: list of patch notes
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/patch_notes'
|
$ref: '#/components/schemas/patch_notes'
|
||||||
description: returns list of all unseen Patch notes from the user
|
|
||||||
"404":
|
"404":
|
||||||
description: no Patch notes found
|
description: no Patch notes found
|
||||||
tags:
|
|
||||||
- Patchnotes
|
post:
|
||||||
x-openapi-router-controller: openapi_server.controllers.patchnotes_controller
|
tags: [Patchnotes]
|
||||||
/patchnotes/{patchID}:
|
summary: Creates new patch notes
|
||||||
put:
|
operationId: createPatchnote
|
||||||
tags:
|
|
||||||
- Patchnotes
|
|
||||||
description: Updates one Patch
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: patchID
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
format: uuid
|
|
||||||
type: string
|
|
||||||
requestBody:
|
requestBody:
|
||||||
|
required: true
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/patch_notes'
|
$ref: '#/components/schemas/patch_notes_input'
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
description: patch note created
|
||||||
|
headers:
|
||||||
|
Location:
|
||||||
|
description: URL of the newly created patch note
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/patch_notes'
|
||||||
|
"400":
|
||||||
|
description: bad payload
|
||||||
|
/patchnotes/{patchID}:
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: patchID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
description: ID of the patch note
|
||||||
|
|
||||||
|
get:
|
||||||
|
tags: [Patchnotes]
|
||||||
|
summary: Returns one patch note
|
||||||
|
operationId: getPatchnote
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: single patch note
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/patch_notes'
|
||||||
|
"404":
|
||||||
|
description: no patch note found
|
||||||
|
|
||||||
|
put:
|
||||||
|
tags: [Patchnotes]
|
||||||
|
summary: Updates one patch note (full replace)
|
||||||
|
operationId: updatePatchnote
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/patch_notes_input'
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: patch updated
|
description: patch updated
|
||||||
"404":
|
|
||||||
description: no patch found
|
|
||||||
delete:
|
|
||||||
tags:
|
|
||||||
- Patchnotes
|
|
||||||
description: deletes one Patch note
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: patchID
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
format: uuid
|
|
||||||
type: string
|
|
||||||
style: simple
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: patch successfully deleted
|
|
||||||
"404":
|
|
||||||
description: patch not found
|
|
||||||
/patchnotes/{date}:
|
|
||||||
get:
|
|
||||||
description: returns list of all unseen Patch notes from the user
|
|
||||||
parameters:
|
|
||||||
- explode: false
|
|
||||||
in: path
|
|
||||||
name: date
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
format: date
|
|
||||||
type: string
|
|
||||||
style: simple
|
|
||||||
example: 2025-01-02
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: array
|
$ref: '#/components/schemas/patch_notes'
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/patch_notes'
|
|
||||||
description: returns list of all unseen Patch notes from the user
|
|
||||||
"404":
|
"404":
|
||||||
description: no Patch notes found
|
description: no patch note found
|
||||||
tags:
|
|
||||||
- Patchnotes
|
delete:
|
||||||
x-openapi-router-controller: openapi_server.controllers.patchnotes_controller
|
tags: [Patchnotes]
|
||||||
|
summary: Deletes one patch note
|
||||||
|
operationId: deletePatchnote
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: patch successfully deleted
|
||||||
|
"404":
|
||||||
|
description: patch not found
|
||||||
|
|
||||||
components:
|
components:
|
||||||
|
parameters:
|
||||||
|
SinceParam:
|
||||||
|
name: since
|
||||||
|
in: query
|
||||||
|
description: Only patchnotes newer than this date (YYYY-MM-DD)
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
|
||||||
schemas:
|
schemas:
|
||||||
patch_notes:
|
patch_notes:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
patchID:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
changes:
|
||||||
|
type: string
|
||||||
|
version:
|
||||||
|
type: string
|
||||||
|
patch_date:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
project:
|
||||||
|
type: string
|
||||||
|
required: [patchID, title, changes, version, patch_date, project]
|
||||||
example:
|
example:
|
||||||
patchID: 29e80bcc-5981-4a52-99e1-373442dea9b9
|
patchID: 29e80bcc-5981-4a52-99e1-373442dea9b9
|
||||||
title: Patch note 1
|
title: Patch note 1
|
||||||
changes: changes
|
changes: Fixed export bug
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
date: 2025-01-02
|
patch_date: '2025-01-02' # ← als String in Quotes!
|
||||||
|
project: 'Test-Projekt'
|
||||||
|
|
||||||
|
patch_notes_input:
|
||||||
|
description: Schema for POST/PUT (server generates patchID if omitted)
|
||||||
|
type: object
|
||||||
properties:
|
properties:
|
||||||
patchID:
|
|
||||||
format: uuid
|
|
||||||
title: patchID
|
|
||||||
type: string
|
|
||||||
title:
|
title:
|
||||||
type: string
|
type: string
|
||||||
title: title
|
|
||||||
changes:
|
changes:
|
||||||
type: string
|
type: string
|
||||||
title: changes
|
|
||||||
version:
|
version:
|
||||||
type: string
|
type: string
|
||||||
title: version
|
|
||||||
patch_date:
|
patch_date:
|
||||||
title: patch_date
|
|
||||||
type: string
|
type: string
|
||||||
required:
|
|
||||||
- "title"
|
|
||||||
- "changes"
|
|
||||||
- "patch_date"
|
|
||||||
- "version"
|
|
||||||
user:
|
|
||||||
example:
|
|
||||||
lastSeenDate: 2025-01-02
|
|
||||||
properties:
|
|
||||||
lastSeenDate:
|
|
||||||
format: date
|
format: date
|
||||||
title: lastNoteChecked
|
project:
|
||||||
type: string
|
type: string
|
||||||
|
required: [title, changes, version, patch_date, project]
|
||||||
|
example:
|
||||||
|
title: Patch note 1
|
||||||
|
changes: Fixed export bug
|
||||||
|
version: 1.0.0
|
||||||
|
patch_date: '2025-01-02' # ← ebenfalls in Quotes
|
||||||
|
project: 'Test-Projekt'
|
||||||
|
|
||||||
|
responses:
|
||||||
|
Error400:
|
||||||
|
description: Invalid request payload
|
||||||
|
Error404:
|
||||||
|
description: Resource not found
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
from flask import Flask, jsonify, request
|
from flask import Flask, jsonify, request
|
||||||
|
from flask_cors import cross_origin
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
#docs/*.md
|
#docs/*.md
|
||||||
# Then explicitly reverse the ignore rule for a single file:
|
# Then explicitly reverse the ignore rule for a single file:
|
||||||
#!docs/README.md
|
#!docs/README.md
|
||||||
|
openapi_server/encoder.py
|
||||||
openapi_server/controllers/patchnotes_controller.py
|
openapi_server/controllers/patchnotes_controller.py
|
||||||
openapi_server/__main__.py
|
openapi_server/__main__.py
|
||||||
openapi_server/encoder.py
|
|
||||||
openapi_server/models/base_model.py
|
openapi_server/models/base_model.py
|
||||||
|
requirements.txt
|
||||||
|
|||||||
@@ -6,16 +6,14 @@ README.md
|
|||||||
git_push.sh
|
git_push.sh
|
||||||
openapi_server/__init__.py
|
openapi_server/__init__.py
|
||||||
openapi_server/controllers/__init__.py
|
openapi_server/controllers/__init__.py
|
||||||
openapi_server/controllers/patchnotes_controller.py
|
|
||||||
openapi_server/controllers/security_controller.py
|
openapi_server/controllers/security_controller.py
|
||||||
openapi_server/models/__init__.py
|
openapi_server/models/__init__.py
|
||||||
openapi_server/models/patch_notes.py
|
openapi_server/models/patch_notes.py
|
||||||
openapi_server/models/user.py
|
openapi_server/models/patch_notes_input.py
|
||||||
openapi_server/openapi/openapi.yaml
|
openapi_server/openapi/openapi.yaml
|
||||||
openapi_server/test/__init__.py
|
openapi_server/test/__init__.py
|
||||||
openapi_server/typing_utils.py
|
openapi_server/typing_utils.py
|
||||||
openapi_server/util.py
|
openapi_server/util.py
|
||||||
requirements.txt
|
|
||||||
setup.py
|
setup.py
|
||||||
test-requirements.txt
|
test-requirements.txt
|
||||||
tox.ini
|
tox.ini
|
||||||
|
|||||||
@@ -2,17 +2,34 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
import connexion
|
import connexion
|
||||||
|
from connexion.middleware import MiddlewarePosition
|
||||||
|
from flask import Flask
|
||||||
|
|
||||||
from openapi_server import encoder
|
from openapi_server import encoder
|
||||||
from pymongo import MongoClient
|
from pymongo import MongoClient, ASCENDING
|
||||||
|
from starlette.middleware.cors import CORSMiddleware
|
||||||
|
import re
|
||||||
|
|
||||||
client = MongoClient(host='mongodb://host.docker.internal:27017/')
|
client = MongoClient(host='mongodb://admin:admin@announcement-service-database-svc:27017/?authSource=admin')
|
||||||
db = client["MainDB"]
|
db = client["MainDB"]
|
||||||
collection = db['patch_notes']
|
collection = db['patch_notes']
|
||||||
|
last_login_collection = db["user_last_login"]
|
||||||
|
|
||||||
|
last_login_collection.create_index(
|
||||||
|
[("user_id", ASCENDING)], unique=True, name="user_id_unique"
|
||||||
|
)
|
||||||
|
|
||||||
|
app = connexion.FlaskApp(__name__, specification_dir='./openapi/')
|
||||||
|
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
position=MiddlewarePosition.BEFORE_EXCEPTION,
|
||||||
|
allow_origin_regex=r"^https?://(.*\.kanzleiapp\.io|.*\.masasana\.ai|localhost:4200)$",
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
app = connexion.App(__name__, specification_dir='./openapi/')
|
|
||||||
app.app.logger.setLevel(logging.DEBUG)
|
|
||||||
app.app.json_encoder = encoder.JSONEncoder
|
|
||||||
app.add_api('openapi.yaml',
|
app.add_api('openapi.yaml',
|
||||||
base_path='/api',
|
base_path='/api',
|
||||||
arguments={'title': 'announcementService'},
|
arguments={'title': 'announcementService'},
|
||||||
|
|||||||
@@ -1,63 +1,88 @@
|
|||||||
|
import connexion
|
||||||
|
from typing import Dict
|
||||||
|
from typing import Tuple
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
from openapi_server.models.patch_notes import PatchNotes # noqa: E501
|
||||||
|
from openapi_server.models.patch_notes_input import PatchNotesInput # noqa: E501
|
||||||
|
from openapi_server import util
|
||||||
import logging
|
import logging
|
||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime
|
from datetime import datetime, date
|
||||||
|
|
||||||
from bson import json_util
|
from bson import json_util
|
||||||
from connexion import ProblemException
|
from connexion import ProblemException
|
||||||
from flask import Response
|
from flask import Response
|
||||||
from __main__ import collection
|
from __main__ import collection
|
||||||
|
|
||||||
from openapi_server.__main__ import collection
|
from openapi_server.__main__ import collection, last_login_collection
|
||||||
from openapi_server.models.patch_notes import PatchNotes # noqa: E501
|
from openapi_server.models.patch_notes import PatchNotes
|
||||||
|
from openapi_server.utils.auth import current_user_id
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
def patchnotes_date_get(date): # noqa: E501
|
def create_patchnote(body): # noqa: E501
|
||||||
"""patchnotes_date_get
|
"""Creates new patch notes
|
||||||
|
|
||||||
returns list of all unseen Patch notes from the user # noqa: E501
|
# noqa: E501
|
||||||
|
|
||||||
:param date:
|
:param body:
|
||||||
:type date: str
|
:param patch_notes_input:
|
||||||
|
:type patch_notes_input: dict | bytes
|
||||||
|
|
||||||
:rtype: Union[List[PatchNotes], Tuple[List[PatchNotes], int], Tuple[List[PatchNotes], int, Dict[str, str]]
|
:rtype: Union[PatchNotes, Tuple[PatchNotes, int], Tuple[PatchNotes, int, Dict[str, str]]
|
||||||
"""
|
"""
|
||||||
logging.error(type(date))
|
patch_notes_input = body
|
||||||
try:
|
if not body:
|
||||||
datetime.strptime(date, '%Y-%m-%d') # 2025-01-0
|
return Response("No patch notes provided", status=400)
|
||||||
except ValueError as e:
|
|
||||||
raise ProblemException(
|
pn = PatchNotes.from_dict(body)
|
||||||
title="Bad Request",
|
|
||||||
detail="The date is invalid. Needs to be in this Format YYYY-MM-DD",
|
# --- Datum wahlweise als str oder Date annehmen ---
|
||||||
status=400,
|
if isinstance(pn.patch_date, date):
|
||||||
)
|
date_str = pn.patch_date.isoformat()
|
||||||
logging.error('date:' + str(date))
|
else:
|
||||||
query = {
|
try:
|
||||||
'patch_date': {'$gte': date}
|
date_str = datetime.strptime(pn.patch_date, "%Y-%m-%d").date().isoformat()
|
||||||
|
except ValueError:
|
||||||
|
raise ProblemException(
|
||||||
|
title="Bad Request",
|
||||||
|
detail="patch_date must be in format YYYY-MM-DD",
|
||||||
|
status=400,
|
||||||
|
)
|
||||||
|
|
||||||
|
patch_doc = {
|
||||||
|
"patchID": str(uuid.uuid4()),
|
||||||
|
"title": pn.title,
|
||||||
|
"changes": pn.changes,
|
||||||
|
"version": pn.version,
|
||||||
|
"patch_date": date_str,
|
||||||
|
"project": pn.project
|
||||||
}
|
}
|
||||||
results = []
|
|
||||||
for entry in collection.find(query):
|
collection.insert_one(patch_doc)
|
||||||
patch_note = PatchNotes.from_dict(entry)
|
patch_doc.pop("_id", None) # Mongo-internes Feld ausblenden
|
||||||
results.append(patch_note.to_dict())
|
|
||||||
return Response(
|
return Response(
|
||||||
json_util.dumps(results),
|
json_util.dumps(patch_doc),
|
||||||
mimetype='application/json',
|
mimetype="application/json",
|
||||||
status=200,
|
status=201, # 201 Created
|
||||||
|
headers={"Location": f"/api/patchnotes/{patch_doc['patchID']}"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def patchnotes_patch_iddelete(patch_id): # noqa: E501
|
def delete_patchnote(patch_id): # noqa: E501
|
||||||
"""patchnotes_patch_iddelete
|
"""Deletes one patch note
|
||||||
|
|
||||||
deletes one Patch note # noqa: E501
|
# noqa: E501
|
||||||
|
|
||||||
:param patch_id:
|
:param patch_id: ID of the patch note
|
||||||
:type patch_id: str
|
:type patch_id: str
|
||||||
:type patch_id: str
|
:type patch_id: str
|
||||||
|
|
||||||
:rtype: Union[None, Tuple[None, int], Tuple[None, int, Dict[str, str]]
|
:rtype: Union[None, Tuple[None, int], Tuple[None, int, Dict[str, str]]
|
||||||
"""
|
"""
|
||||||
deleted_doc = collection.delete_one({'patchID': patch_id})
|
deleted_doc = collection.delete_one({'patchID': patch_id})
|
||||||
logging.error(deleted_doc.deleted_count)
|
|
||||||
if deleted_doc.deleted_count == 0:
|
if deleted_doc.deleted_count == 0:
|
||||||
raise ProblemException(
|
raise ProblemException(
|
||||||
title="Not found",
|
title="Not found",
|
||||||
@@ -65,151 +90,155 @@ def patchnotes_patch_iddelete(patch_id): # noqa: E501
|
|||||||
status=404,
|
status=404,
|
||||||
)
|
)
|
||||||
return Response(
|
return Response(
|
||||||
"Document was deleted",
|
"Document was deleted",
|
||||||
mimetype='application/json',
|
mimetype='application/json',
|
||||||
status=200,
|
status=200,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def patchnotes_patch_idput(patch_id, body): # noqa: E501
|
def get_patchnote(patch_id): # noqa: E501
|
||||||
"""patchnotes_patch_idput
|
"""Returns one patch note
|
||||||
|
|
||||||
Updates one Patch # noqa: E501
|
# noqa: E501
|
||||||
|
|
||||||
:param body:
|
:param patch_id: ID of the patch note
|
||||||
:param patch_id:
|
|
||||||
:type patch_id: str
|
:type patch_id: str
|
||||||
:type patch_id: str
|
:type patch_id: str
|
||||||
|
|
||||||
:rtype: Union[None, Tuple[None, int], Tuple[None, int, Dict[str, str]]
|
:rtype: Union[PatchNotes, Tuple[PatchNotes, int], Tuple[PatchNotes, int, Dict[str, str]]
|
||||||
"""
|
"""
|
||||||
pn = PatchNotes.from_dict(body)
|
pn = collection.find_one({'patchID': patch_id})
|
||||||
try:
|
if pn is None:
|
||||||
date_obj = datetime.strptime(pn.patch_date, '%Y-%m-%d').date()
|
|
||||||
date_str = date_obj.strftime('%Y-%m-%d')
|
|
||||||
except ValueError as e:
|
|
||||||
raise ProblemException(
|
|
||||||
title="Bad Request",
|
|
||||||
detail="The date is invalid. Needs to be in this Format YYYY-MM-DD",
|
|
||||||
status=400,
|
|
||||||
)
|
|
||||||
query_filter = {'patchID': patch_id}
|
|
||||||
updated_post = {'$set':
|
|
||||||
{
|
|
||||||
'title': pn.title,
|
|
||||||
'changes': pn.changes,
|
|
||||||
'version': pn.version,
|
|
||||||
'date': date_str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = collection.update_one(query_filter, updated_post)
|
|
||||||
if result.modified_count == 0:
|
|
||||||
raise ProblemException(
|
raise ProblemException(
|
||||||
title="Not found",
|
title="Not found",
|
||||||
detail="No document has been deleted",
|
detail="No document has been found",
|
||||||
status=404,
|
status=404,
|
||||||
)
|
)
|
||||||
logging.error(result)
|
|
||||||
return Response("Document was updated", status=200, mimetype='application/json')
|
|
||||||
|
|
||||||
|
|
||||||
def patchnotes_post(body):
|
|
||||||
"""patchnotes_post
|
|
||||||
|
|
||||||
creates new Patch notes # noqa: E501
|
|
||||||
|
|
||||||
:param body:
|
|
||||||
:param patch_notes:
|
|
||||||
:type patch_notes: dict | bytes
|
|
||||||
|
|
||||||
:rtype: Union[List[PatchNotes], Tuple[List[PatchNotes], int], Tuple[List[PatchNotes], int, Dict[str, str]]
|
|
||||||
"""
|
|
||||||
if body is None:
|
|
||||||
return Response('error: No patch notes provided', status=400)
|
|
||||||
pn = PatchNotes.from_dict(body)
|
|
||||||
try:
|
|
||||||
date_obj = datetime.strptime(pn.patch_date, '%Y-%m-%d').date()
|
|
||||||
date_str = date_obj.strftime('%Y-%m-%d')
|
|
||||||
except ValueError as e:
|
|
||||||
raise ProblemException(
|
|
||||||
title="Bad Request",
|
|
||||||
detail="The date is invalid. Needs to be in this Format YYYY-MM-DD",
|
|
||||||
status=400,
|
|
||||||
)
|
|
||||||
|
|
||||||
logging.error('patch_notes_type:' + str(type(date_obj)))
|
|
||||||
logging.error('patch notes' + str(pn))
|
|
||||||
|
|
||||||
patch_note = {
|
|
||||||
'patchID': str(uuid.uuid4()),
|
|
||||||
'title': pn.title,
|
|
||||||
'changes': pn.changes,
|
|
||||||
'version': pn.version,
|
|
||||||
'patch_date': date_str
|
|
||||||
}
|
|
||||||
|
|
||||||
logging.error('patch_notes_type:' + str(type(patch_note)))
|
|
||||||
logging.error('patch notes' + str(patch_note))
|
|
||||||
|
|
||||||
collection.insert_one(patch_note)
|
|
||||||
patch_note_obj = PatchNotes.from_dict(patch_note)
|
|
||||||
patch_note = patch_note_obj.to_dict()
|
|
||||||
return Response(json_util.dumps(patch_note), mimetype='application/json',
|
|
||||||
status=200)
|
|
||||||
|
|
||||||
def patchnotes_post(body):
|
|
||||||
"""patchnotes_post
|
|
||||||
|
|
||||||
creates new Patch notes # noqa: E501
|
|
||||||
|
|
||||||
:param body:
|
|
||||||
:param patch_notes:
|
|
||||||
:type patch_notes: dict | bytes
|
|
||||||
|
|
||||||
:rtype: Union[List[PatchNotes], Tuple[List[PatchNotes], int], Tuple[List[PatchNotes], int, Dict[str, str]]
|
|
||||||
"""
|
|
||||||
if body is None:
|
|
||||||
return Response('error: No patch notes provided', status=400)
|
|
||||||
pn = PatchNotes.from_dict(body)
|
|
||||||
try:
|
|
||||||
date_obj = datetime.strptime(pn.patch_date, '%Y-%m-%d').date()
|
|
||||||
date_str = date_obj.strftime('%Y-%m-%d')
|
|
||||||
except ValueError as e:
|
|
||||||
raise ProblemException(
|
|
||||||
title="Bad Request",
|
|
||||||
detail="The date is invalid. Needs to be in this Format YYYY-MM-DD",
|
|
||||||
status=400,
|
|
||||||
)
|
|
||||||
|
|
||||||
patch_note = {
|
|
||||||
'patchID': str(uuid.uuid4()),
|
|
||||||
'title': pn.title,
|
|
||||||
'changes': pn.changes,
|
|
||||||
'version': pn.version,
|
|
||||||
'patch_date': date_str
|
|
||||||
}
|
|
||||||
|
|
||||||
collection.insert_one(patch_note)
|
|
||||||
patch_note_obj = PatchNotes.from_dict(patch_note)
|
|
||||||
patch_note = patch_note_obj.to_dict()
|
|
||||||
return Response(json_util.dumps(patch_note), mimetype='application/json',
|
|
||||||
status=200)
|
|
||||||
|
|
||||||
|
|
||||||
def patchnotes_get(): # noqa: E501
|
|
||||||
"""patchnotes_get
|
|
||||||
|
|
||||||
returns list of all Patch notes # noqa: E501
|
|
||||||
|
|
||||||
|
|
||||||
:rtype: Union[List[PatchNotes], Tuple[List[PatchNotes], int], Tuple[List[PatchNotes], int, Dict[str, str]]
|
|
||||||
"""
|
|
||||||
results = []
|
|
||||||
for entry in collection.find({}):
|
|
||||||
patch_note = PatchNotes.from_dict(entry)
|
|
||||||
results.append(patch_note.to_dict())
|
|
||||||
return Response(
|
return Response(
|
||||||
json_util.dumps(results),
|
json_util.dumps(pn),
|
||||||
mimetype='application/json',
|
mimetype='application/json',
|
||||||
status=200,
|
status=200,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def list_patchnotes(since: str | None = None):
|
||||||
|
"""GET /patchnotes – liefert neue Patchnotes und setzt last_login."""
|
||||||
|
|
||||||
|
user_id = current_user_id() # 1) aktueller Benutzer
|
||||||
|
last_login_doc = last_login_collection.find_one(
|
||||||
|
{"user_id": user_id},
|
||||||
|
{"_id": 0, "last_login": 1}
|
||||||
|
)
|
||||||
|
last_login = last_login_doc.get("last_login") if last_login_doc else None
|
||||||
|
|
||||||
|
query = {}
|
||||||
|
logging.info("since" + str(since))
|
||||||
|
logging.info("last_login" + str(last_login))
|
||||||
|
if since:
|
||||||
|
logging.info("Went into if since")
|
||||||
|
|
||||||
|
try:
|
||||||
|
datetime.strptime(since, "%Y-%m-%d")
|
||||||
|
except ValueError:
|
||||||
|
raise ProblemException(
|
||||||
|
title="Bad Request",
|
||||||
|
detail="since must be YYYY-MM-DD",
|
||||||
|
status=400,
|
||||||
|
)
|
||||||
|
query = {
|
||||||
|
"patch_date": {
|
||||||
|
"$gte": since,
|
||||||
|
"$lte": last_login
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# 3) Datum validieren (nur wenn vorhanden)
|
||||||
|
elif since is None:
|
||||||
|
logging.info("Went into if since is None")
|
||||||
|
try:
|
||||||
|
docs = collection.find({})
|
||||||
|
for d in docs:
|
||||||
|
d.pop("_id", None)
|
||||||
|
if isinstance(d["patch_date"], (datetime, date)):
|
||||||
|
d["patch_date"] = d["patch_date"].isoformat()
|
||||||
|
except ValueError as e:
|
||||||
|
raise ProblemException(
|
||||||
|
title="Internal Server Error",
|
||||||
|
detail=str(e),
|
||||||
|
status=500,
|
||||||
|
)
|
||||||
|
# 4) Patchnotes abholen
|
||||||
|
|
||||||
|
docs = list(collection.find(query).sort("patch_date", 1))
|
||||||
|
for d in docs:
|
||||||
|
d.pop("_id", None)
|
||||||
|
if isinstance(d["patch_date"], (datetime, date)):
|
||||||
|
d["patch_date"] = d["patch_date"].isoformat()
|
||||||
|
|
||||||
|
# 5) Heutiges Datum als neuen last_login speichern
|
||||||
|
today = date.today().isoformat()
|
||||||
|
last_login_collection.update_one(
|
||||||
|
{"user_id": user_id},
|
||||||
|
{"$set": {"last_login": today}},
|
||||||
|
upsert=True,
|
||||||
|
)
|
||||||
|
return Response(json_util.dumps(docs), mimetype="application/json", status=200)
|
||||||
|
|
||||||
|
|
||||||
|
def update_patchnote(patch_id, body): # noqa: E501
|
||||||
|
"""Updates one patch note (full replace)
|
||||||
|
|
||||||
|
# noqa: E501
|
||||||
|
|
||||||
|
:param body:
|
||||||
|
:param patch_id: ID of the patch note
|
||||||
|
:type patch_id: str
|
||||||
|
:type patch_id: str
|
||||||
|
:param patch_notes_input:
|
||||||
|
:type patch_notes_input: dict | bytes
|
||||||
|
|
||||||
|
:rtype: Union[PatchNotes, Tuple[PatchNotes, int], Tuple[PatchNotes, int, Dict[str, str]]
|
||||||
|
"""
|
||||||
|
if not body:
|
||||||
|
return Response("No patch notes provided", status=400)
|
||||||
|
|
||||||
|
pn = PatchNotes.from_dict(body)
|
||||||
|
|
||||||
|
if isinstance(pn.patch_date, date):
|
||||||
|
date_str = pn.patch_date.isoformat()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
date_str = datetime.strptime(pn.patch_date, "%Y-%m-%d").date().isoformat()
|
||||||
|
except ValueError:
|
||||||
|
raise ProblemException(
|
||||||
|
title="Bad Request",
|
||||||
|
detail="patch_date must be in format YYYY-MM-DD",
|
||||||
|
status=400,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = collection.update_one(
|
||||||
|
{"patchID": patch_id},
|
||||||
|
{"$set": {
|
||||||
|
"title": pn.title,
|
||||||
|
"changes": pn.changes,
|
||||||
|
"version": pn.version,
|
||||||
|
"patch_date": date_str, # richtiger Feldname!
|
||||||
|
"project": pn.project,
|
||||||
|
}}
|
||||||
|
)
|
||||||
|
|
||||||
|
if result.matched_count == 0:
|
||||||
|
raise ProblemException(
|
||||||
|
title="Not found",
|
||||||
|
detail="No document has been found",
|
||||||
|
status=404,
|
||||||
|
)
|
||||||
|
|
||||||
|
doc = collection.find_one({"patchID": patch_id})
|
||||||
|
doc.pop("_id", None)
|
||||||
|
|
||||||
|
return Response(
|
||||||
|
json_util.dumps(doc),
|
||||||
|
mimetype="application/json",
|
||||||
|
status=200,
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
# import models into model package
|
# import models into model package
|
||||||
from openapi_server.models.patch_notes import PatchNotes
|
from openapi_server.models.patch_notes import PatchNotes
|
||||||
from openapi_server.models.user import User
|
from openapi_server.models.patch_notes_input import PatchNotesInput
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import pprint
|
import pprint
|
||||||
|
|
||||||
import typing
|
import typing
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from openapi_server import util
|
from openapi_server import util
|
||||||
|
|
||||||
@@ -29,26 +28,23 @@ class Model:
|
|||||||
"""
|
"""
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
for attr, _ in self.openapi_types.items():
|
for attr in self.openapi_types:
|
||||||
value = getattr(self, attr)
|
value = getattr(self, attr)
|
||||||
dict_attr = self.attribute_map[attr]
|
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
result[dict_attr] = list(map(
|
result[attr] = list(map(
|
||||||
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
|
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
|
||||||
value
|
value
|
||||||
))
|
))
|
||||||
elif hasattr(value, "to_dict"):
|
elif hasattr(value, "to_dict"):
|
||||||
result[dict_attr] = value.to_dict()
|
result[attr] = value.to_dict()
|
||||||
elif isinstance(value, dict):
|
elif isinstance(value, dict):
|
||||||
result[dict_attr] = dict(map(
|
result[attr] = dict(map(
|
||||||
lambda item: (item[0], item[1].to_dict())
|
lambda item: (item[0], item[1].to_dict())
|
||||||
if hasattr(item[1], "to_dict") else item,
|
if hasattr(item[1], "to_dict") else item,
|
||||||
value.items()
|
value.items()
|
||||||
))
|
))
|
||||||
elif isinstance(value, datetime):
|
|
||||||
result[dict_attr] = value.isoformat()
|
|
||||||
else:
|
else:
|
||||||
result[dict_attr] = value
|
result[attr] = value
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class PatchNotes(Model):
|
|||||||
Do not edit the class manually.
|
Do not edit the class manually.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, patch_id=None, title=None, changes=None, version=None, patch_date=None): # noqa: E501
|
def __init__(self, patch_id=None, title=None, changes=None, version=None, patch_date=None, project=None): # noqa: E501
|
||||||
"""PatchNotes - a model defined in OpenAPI
|
"""PatchNotes - a model defined in OpenAPI
|
||||||
|
|
||||||
:param patch_id: The patch_id of this PatchNotes. # noqa: E501
|
:param patch_id: The patch_id of this PatchNotes. # noqa: E501
|
||||||
@@ -24,14 +24,17 @@ class PatchNotes(Model):
|
|||||||
:param version: The version of this PatchNotes. # noqa: E501
|
:param version: The version of this PatchNotes. # noqa: E501
|
||||||
:type version: str
|
:type version: str
|
||||||
:param patch_date: The patch_date of this PatchNotes. # noqa: E501
|
:param patch_date: The patch_date of this PatchNotes. # noqa: E501
|
||||||
:type patch_date: str
|
:type patch_date: date
|
||||||
|
:param project: The project of this PatchNotes. # noqa: E501
|
||||||
|
:type project: str
|
||||||
"""
|
"""
|
||||||
self.openapi_types = {
|
self.openapi_types = {
|
||||||
'patch_id': str,
|
'patch_id': str,
|
||||||
'title': str,
|
'title': str,
|
||||||
'changes': str,
|
'changes': str,
|
||||||
'version': str,
|
'version': str,
|
||||||
'patch_date': str
|
'patch_date': str,
|
||||||
|
'project': str
|
||||||
}
|
}
|
||||||
|
|
||||||
self.attribute_map = {
|
self.attribute_map = {
|
||||||
@@ -39,7 +42,8 @@ class PatchNotes(Model):
|
|||||||
'title': 'title',
|
'title': 'title',
|
||||||
'changes': 'changes',
|
'changes': 'changes',
|
||||||
'version': 'version',
|
'version': 'version',
|
||||||
'patch_date': 'patch_date'
|
'patch_date': 'patch_date',
|
||||||
|
'project': 'project'
|
||||||
}
|
}
|
||||||
|
|
||||||
self._patch_id = patch_id
|
self._patch_id = patch_id
|
||||||
@@ -47,6 +51,7 @@ class PatchNotes(Model):
|
|||||||
self._changes = changes
|
self._changes = changes
|
||||||
self._version = version
|
self._version = version
|
||||||
self._patch_date = patch_date
|
self._patch_date = patch_date
|
||||||
|
self._project = project
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, dikt) -> 'PatchNotes':
|
def from_dict(cls, dikt) -> 'PatchNotes':
|
||||||
@@ -77,6 +82,8 @@ class PatchNotes(Model):
|
|||||||
:param patch_id: The patch_id of this PatchNotes.
|
:param patch_id: The patch_id of this PatchNotes.
|
||||||
:type patch_id: str
|
:type patch_id: str
|
||||||
"""
|
"""
|
||||||
|
if patch_id is None:
|
||||||
|
raise ValueError("Invalid value for `patch_id`, must not be `None`") # noqa: E501
|
||||||
|
|
||||||
self._patch_id = patch_id
|
self._patch_id = patch_id
|
||||||
|
|
||||||
@@ -150,24 +157,47 @@ class PatchNotes(Model):
|
|||||||
self._version = version
|
self._version = version
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def patch_date(self) -> str:
|
def patch_date(self) -> date:
|
||||||
"""Gets the patch_date of this PatchNotes.
|
"""Gets the patch_date of this PatchNotes.
|
||||||
|
|
||||||
|
|
||||||
:return: The patch_date of this PatchNotes.
|
:return: The patch_date of this PatchNotes.
|
||||||
:rtype: str
|
:rtype: date
|
||||||
"""
|
"""
|
||||||
return self._patch_date
|
return self._patch_date
|
||||||
|
|
||||||
@patch_date.setter
|
@patch_date.setter
|
||||||
def patch_date(self, patch_date: str):
|
def patch_date(self, patch_date: date):
|
||||||
"""Sets the patch_date of this PatchNotes.
|
"""Sets the patch_date of this PatchNotes.
|
||||||
|
|
||||||
|
|
||||||
:param patch_date: The patch_date of this PatchNotes.
|
:param patch_date: The patch_date of this PatchNotes.
|
||||||
:type patch_date: str
|
:type patch_date: date
|
||||||
"""
|
"""
|
||||||
if patch_date is None:
|
if patch_date is None:
|
||||||
raise ValueError("Invalid value for `patch_date`, must not be `None`") # noqa: E501
|
raise ValueError("Invalid value for `patch_date`, must not be `None`") # noqa: E501
|
||||||
|
|
||||||
self._patch_date = patch_date
|
self._patch_date = patch_date
|
||||||
|
|
||||||
|
@property
|
||||||
|
def project(self) -> str:
|
||||||
|
"""Gets the project of this PatchNotes.
|
||||||
|
|
||||||
|
|
||||||
|
:return: The project of this PatchNotes.
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return self._project
|
||||||
|
|
||||||
|
@project.setter
|
||||||
|
def project(self, project: str):
|
||||||
|
"""Sets the project of this PatchNotes.
|
||||||
|
|
||||||
|
|
||||||
|
:param project: The project of this PatchNotes.
|
||||||
|
:type project: str
|
||||||
|
"""
|
||||||
|
if project is None:
|
||||||
|
raise ValueError("Invalid value for `project`, must not be `None`") # noqa: E501
|
||||||
|
|
||||||
|
self._project = project
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
from datetime import date, datetime # noqa: F401
|
||||||
|
|
||||||
|
from typing import List, Dict # noqa: F401
|
||||||
|
|
||||||
|
from openapi_server.models.base_model import Model
|
||||||
|
from openapi_server import util
|
||||||
|
|
||||||
|
|
||||||
|
class PatchNotesInput(Model):
|
||||||
|
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
|
||||||
|
Do not edit the class manually.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, title=None, changes=None, version=None, patch_date=None, project=None): # noqa: E501
|
||||||
|
"""PatchNotesInput - a model defined in OpenAPI
|
||||||
|
|
||||||
|
:param title: The title of this PatchNotesInput. # noqa: E501
|
||||||
|
:type title: str
|
||||||
|
:param changes: The changes of this PatchNotesInput. # noqa: E501
|
||||||
|
:type changes: str
|
||||||
|
:param version: The version of this PatchNotesInput. # noqa: E501
|
||||||
|
:type version: str
|
||||||
|
:param patch_date: The patch_date of this PatchNotesInput. # noqa: E501
|
||||||
|
:type patch_date: date
|
||||||
|
:param project: The project of this PatchNotesInput. # noqa: E501
|
||||||
|
:type project: str
|
||||||
|
"""
|
||||||
|
self.openapi_types = {
|
||||||
|
'title': str,
|
||||||
|
'changes': str,
|
||||||
|
'version': str,
|
||||||
|
'patch_date': date,
|
||||||
|
'project': str
|
||||||
|
}
|
||||||
|
|
||||||
|
self.attribute_map = {
|
||||||
|
'title': 'title',
|
||||||
|
'changes': 'changes',
|
||||||
|
'version': 'version',
|
||||||
|
'patch_date': 'patch_date',
|
||||||
|
'project': 'project'
|
||||||
|
}
|
||||||
|
|
||||||
|
self._title = title
|
||||||
|
self._changes = changes
|
||||||
|
self._version = version
|
||||||
|
self._patch_date = patch_date
|
||||||
|
self._project = project
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, dikt) -> 'PatchNotesInput':
|
||||||
|
"""Returns the dict as a model
|
||||||
|
|
||||||
|
:param dikt: A dict.
|
||||||
|
:type: dict
|
||||||
|
:return: The patch_notes_input of this PatchNotesInput. # noqa: E501
|
||||||
|
:rtype: PatchNotesInput
|
||||||
|
"""
|
||||||
|
return util.deserialize_model(dikt, cls)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def title(self) -> str:
|
||||||
|
"""Gets the title of this PatchNotesInput.
|
||||||
|
|
||||||
|
|
||||||
|
:return: The title of this PatchNotesInput.
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return self._title
|
||||||
|
|
||||||
|
@title.setter
|
||||||
|
def title(self, title: str):
|
||||||
|
"""Sets the title of this PatchNotesInput.
|
||||||
|
|
||||||
|
|
||||||
|
:param title: The title of this PatchNotesInput.
|
||||||
|
:type title: str
|
||||||
|
"""
|
||||||
|
if title is None:
|
||||||
|
raise ValueError("Invalid value for `title`, must not be `None`") # noqa: E501
|
||||||
|
|
||||||
|
self._title = title
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changes(self) -> str:
|
||||||
|
"""Gets the changes of this PatchNotesInput.
|
||||||
|
|
||||||
|
|
||||||
|
:return: The changes of this PatchNotesInput.
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return self._changes
|
||||||
|
|
||||||
|
@changes.setter
|
||||||
|
def changes(self, changes: str):
|
||||||
|
"""Sets the changes of this PatchNotesInput.
|
||||||
|
|
||||||
|
|
||||||
|
:param changes: The changes of this PatchNotesInput.
|
||||||
|
:type changes: str
|
||||||
|
"""
|
||||||
|
if changes is None:
|
||||||
|
raise ValueError("Invalid value for `changes`, must not be `None`") # noqa: E501
|
||||||
|
|
||||||
|
self._changes = changes
|
||||||
|
|
||||||
|
@property
|
||||||
|
def version(self) -> str:
|
||||||
|
"""Gets the version of this PatchNotesInput.
|
||||||
|
|
||||||
|
|
||||||
|
:return: The version of this PatchNotesInput.
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return self._version
|
||||||
|
|
||||||
|
@version.setter
|
||||||
|
def version(self, version: str):
|
||||||
|
"""Sets the version of this PatchNotesInput.
|
||||||
|
|
||||||
|
|
||||||
|
:param version: The version of this PatchNotesInput.
|
||||||
|
:type version: str
|
||||||
|
"""
|
||||||
|
if version is None:
|
||||||
|
raise ValueError("Invalid value for `version`, must not be `None`") # noqa: E501
|
||||||
|
|
||||||
|
self._version = version
|
||||||
|
|
||||||
|
@property
|
||||||
|
def patch_date(self) -> date:
|
||||||
|
"""Gets the patch_date of this PatchNotesInput.
|
||||||
|
|
||||||
|
|
||||||
|
:return: The patch_date of this PatchNotesInput.
|
||||||
|
:rtype: date
|
||||||
|
"""
|
||||||
|
return self._patch_date
|
||||||
|
|
||||||
|
@patch_date.setter
|
||||||
|
def patch_date(self, patch_date: date):
|
||||||
|
"""Sets the patch_date of this PatchNotesInput.
|
||||||
|
|
||||||
|
|
||||||
|
:param patch_date: The patch_date of this PatchNotesInput.
|
||||||
|
:type patch_date: date
|
||||||
|
"""
|
||||||
|
if patch_date is None:
|
||||||
|
raise ValueError("Invalid value for `patch_date`, must not be `None`") # noqa: E501
|
||||||
|
|
||||||
|
self._patch_date = patch_date
|
||||||
|
|
||||||
|
@property
|
||||||
|
def project(self) -> str:
|
||||||
|
"""Gets the project of this PatchNotesInput.
|
||||||
|
|
||||||
|
|
||||||
|
:return: The project of this PatchNotesInput.
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return self._project
|
||||||
|
|
||||||
|
@project.setter
|
||||||
|
def project(self, project: str):
|
||||||
|
"""Sets the project of this PatchNotesInput.
|
||||||
|
|
||||||
|
|
||||||
|
:param project: The project of this PatchNotesInput.
|
||||||
|
:type project: str
|
||||||
|
"""
|
||||||
|
if project is None:
|
||||||
|
raise ValueError("Invalid value for `project`, must not be `None`") # noqa: E501
|
||||||
|
|
||||||
|
self._project = project
|
||||||
@@ -5,11 +5,23 @@ info:
|
|||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
servers:
|
servers:
|
||||||
- url: /
|
- url: /
|
||||||
|
tags:
|
||||||
|
- description: "Create, update and read patchnotes"
|
||||||
|
name: Patchnotes
|
||||||
paths:
|
paths:
|
||||||
/patchnotes:
|
/patchnotes:
|
||||||
get:
|
get:
|
||||||
description: returns list of all Patch notes
|
operationId: list_patchnotes
|
||||||
operationId: patchnotes_get
|
parameters:
|
||||||
|
- description: Only patchnotes newer than this date (YYYY-MM-DD)
|
||||||
|
explode: true
|
||||||
|
in: query
|
||||||
|
name: since
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
format: date
|
||||||
|
type: string
|
||||||
|
style: form
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
content:
|
content:
|
||||||
@@ -18,86 +30,93 @@ paths:
|
|||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/patch_notes'
|
$ref: '#/components/schemas/patch_notes'
|
||||||
type: array
|
type: array
|
||||||
description: returns list of all unseen Patch notes from the user
|
description: list of patch notes
|
||||||
"404":
|
"404":
|
||||||
description: no Patch notes found
|
description: no Patch notes found
|
||||||
|
summary: Returns list of patch notes newer than the caller’s last login
|
||||||
tags:
|
tags:
|
||||||
- Patchnotes
|
- Patchnotes
|
||||||
x-openapi-router-controller: openapi_server.controllers.patchnotes_controller
|
x-openapi-router-controller: openapi_server.controllers.patchnotes_controller
|
||||||
post:
|
post:
|
||||||
description: creates new Patch notes
|
operationId: create_patchnote
|
||||||
operationId: patchnotes_post
|
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/patch_notes'
|
$ref: '#/components/schemas/patch_notes_input'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"201":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/patch_notes'
|
||||||
|
description: patch note created
|
||||||
|
headers:
|
||||||
|
Location:
|
||||||
|
description: URL of the newly created patch note
|
||||||
|
explode: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
style: simple
|
||||||
|
"400":
|
||||||
|
description: bad payload
|
||||||
|
summary: Creates new patch notes
|
||||||
|
tags:
|
||||||
|
- Patchnotes
|
||||||
|
x-openapi-router-controller: openapi_server.controllers.patchnotes_controller
|
||||||
|
/patchnotes/{patchID}:
|
||||||
|
delete:
|
||||||
|
operationId: delete_patchnote
|
||||||
|
parameters:
|
||||||
|
- description: ID of the patch note
|
||||||
|
explode: false
|
||||||
|
in: path
|
||||||
|
name: patchID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
format: uuid
|
||||||
|
type: string
|
||||||
|
style: simple
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: patch successfully deleted
|
||||||
|
"404":
|
||||||
|
description: patch not found
|
||||||
|
summary: Deletes one patch note
|
||||||
|
tags:
|
||||||
|
- Patchnotes
|
||||||
|
x-openapi-router-controller: openapi_server.controllers.patchnotes_controller
|
||||||
|
get:
|
||||||
|
operationId: get_patchnote
|
||||||
|
parameters:
|
||||||
|
- description: ID of the patch note
|
||||||
|
explode: false
|
||||||
|
in: path
|
||||||
|
name: patchID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
format: uuid
|
||||||
|
type: string
|
||||||
|
style: simple
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/patch_notes'
|
$ref: '#/components/schemas/patch_notes'
|
||||||
description: game created
|
description: single patch note
|
||||||
"400":
|
|
||||||
description: bad payload
|
|
||||||
tags:
|
|
||||||
- Patchnotes
|
|
||||||
x-openapi-router-controller: openapi_server.controllers.patchnotes_controller
|
|
||||||
/patchnotes/{date}:
|
|
||||||
get:
|
|
||||||
description: returns list of all unseen Patch notes from the user
|
|
||||||
operationId: patchnotes_date_get
|
|
||||||
parameters:
|
|
||||||
- example: 2025-01-02
|
|
||||||
explode: false
|
|
||||||
in: path
|
|
||||||
name: date
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
format: date
|
|
||||||
type: string
|
|
||||||
style: simple
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/patch_notes'
|
|
||||||
type: array
|
|
||||||
description: returns list of all unseen Patch notes from the user
|
|
||||||
"404":
|
"404":
|
||||||
description: no Patch notes found
|
description: no patch note found
|
||||||
tags:
|
summary: Returns one patch note
|
||||||
- Patchnotes
|
|
||||||
x-openapi-router-controller: openapi_server.controllers.patchnotes_controller
|
|
||||||
/patchnotes/{patchID}:
|
|
||||||
delete:
|
|
||||||
description: deletes one Patch note
|
|
||||||
operationId: patchnotes_patch_iddelete
|
|
||||||
parameters:
|
|
||||||
- explode: false
|
|
||||||
in: path
|
|
||||||
name: patchID
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
format: uuid
|
|
||||||
type: string
|
|
||||||
style: simple
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: patch successfully deleted
|
|
||||||
"404":
|
|
||||||
description: patch not found
|
|
||||||
tags:
|
tags:
|
||||||
- Patchnotes
|
- Patchnotes
|
||||||
x-openapi-router-controller: openapi_server.controllers.patchnotes_controller
|
x-openapi-router-controller: openapi_server.controllers.patchnotes_controller
|
||||||
put:
|
put:
|
||||||
description: Updates one Patch
|
operationId: update_patchnote
|
||||||
operationId: patchnotes_patch_idput
|
|
||||||
parameters:
|
parameters:
|
||||||
- explode: false
|
- description: ID of the patch note
|
||||||
|
explode: false
|
||||||
in: path
|
in: path
|
||||||
name: patchID
|
name: patchID
|
||||||
required: true
|
required: true
|
||||||
@@ -109,52 +128,96 @@ paths:
|
|||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/patch_notes'
|
$ref: '#/components/schemas/patch_notes_input'
|
||||||
|
required: true
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/patch_notes'
|
||||||
description: patch updated
|
description: patch updated
|
||||||
"404":
|
"404":
|
||||||
description: no patch found
|
description: no patch note found
|
||||||
|
summary: Updates one patch note (full replace)
|
||||||
tags:
|
tags:
|
||||||
- Patchnotes
|
- Patchnotes
|
||||||
x-openapi-router-controller: openapi_server.controllers.patchnotes_controller
|
x-openapi-router-controller: openapi_server.controllers.patchnotes_controller
|
||||||
components:
|
components:
|
||||||
|
parameters:
|
||||||
|
SinceParam:
|
||||||
|
description: Only patchnotes newer than this date (YYYY-MM-DD)
|
||||||
|
explode: true
|
||||||
|
in: query
|
||||||
|
name: since
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
format: date
|
||||||
|
type: string
|
||||||
|
style: form
|
||||||
|
responses:
|
||||||
|
Error400:
|
||||||
|
description: Invalid request payload
|
||||||
|
Error404:
|
||||||
|
description: Resource not found
|
||||||
schemas:
|
schemas:
|
||||||
patch_notes:
|
patch_notes:
|
||||||
example:
|
example:
|
||||||
patchID: 29e80bcc-5981-4a52-99e1-373442dea9b9
|
patchID: 29e80bcc-5981-4a52-99e1-373442dea9b9
|
||||||
title: Patch note 1
|
title: Patch note 1
|
||||||
changes: changes
|
changes: Fixed export bug
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
date: 2025-01-02
|
patch_date: 2025-01-02
|
||||||
|
project: Test-Projekt
|
||||||
properties:
|
properties:
|
||||||
patchID:
|
patchID:
|
||||||
format: uuid
|
format: uuid
|
||||||
title: patchID
|
|
||||||
type: string
|
type: string
|
||||||
title:
|
title:
|
||||||
title: title
|
|
||||||
type: string
|
type: string
|
||||||
changes:
|
changes:
|
||||||
title: changes
|
|
||||||
type: string
|
type: string
|
||||||
version:
|
version:
|
||||||
title: version
|
|
||||||
type: string
|
type: string
|
||||||
patch_date:
|
patch_date:
|
||||||
title: patch_date
|
format: date
|
||||||
|
type: string
|
||||||
|
project:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- changes
|
||||||
|
- patchID
|
||||||
|
- patch_date
|
||||||
|
- project
|
||||||
|
- title
|
||||||
|
- version
|
||||||
|
title: patch_notes
|
||||||
|
type: object
|
||||||
|
patch_notes_input:
|
||||||
|
description: Schema for POST/PUT (server generates patchID if omitted)
|
||||||
|
example:
|
||||||
|
title: Patch note 1
|
||||||
|
changes: Fixed export bug
|
||||||
|
version: 1.0.0
|
||||||
|
patch_date: 2025-01-02
|
||||||
|
project: Test-Projekt
|
||||||
|
properties:
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
changes:
|
||||||
|
type: string
|
||||||
|
version:
|
||||||
|
type: string
|
||||||
|
patch_date:
|
||||||
|
format: date
|
||||||
|
type: string
|
||||||
|
project:
|
||||||
type: string
|
type: string
|
||||||
required:
|
required:
|
||||||
- changes
|
- changes
|
||||||
- patch_date
|
- patch_date
|
||||||
|
- project
|
||||||
- title
|
- title
|
||||||
- version
|
- version
|
||||||
title: patch_notes
|
title: patch_notes_input
|
||||||
user:
|
type: object
|
||||||
example:
|
|
||||||
lastSeenDate: 2025-01-02
|
|
||||||
properties:
|
|
||||||
lastSeenDate:
|
|
||||||
format: date
|
|
||||||
title: lastNoteChecked
|
|
||||||
type: string
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import jwt
|
||||||
|
from connexion import ProblemException
|
||||||
|
from flask import request
|
||||||
|
|
||||||
|
def current_user_id() -> str:
|
||||||
|
"""Liest die User-UUID (sub) aus dem Bearer-JWT im Authorization-Header."""
|
||||||
|
auth = request.headers.get("Authorization", "")
|
||||||
|
if not auth.startswith("Bearer "):
|
||||||
|
raise ProblemException(status=401, detail="Missing Bearer token")
|
||||||
|
|
||||||
|
token = auth.split()[1]
|
||||||
|
|
||||||
|
# ↓ Für Demo ohne Signaturprüfung – produktiv natürlich verifizieren!
|
||||||
|
payload = jwt.decode(token, options={"verify_signature": False})
|
||||||
|
return payload["sub"]
|
||||||
@@ -11,3 +11,9 @@ werkzeug == 3.1.3
|
|||||||
swagger-ui-bundle >= 0.0.2
|
swagger-ui-bundle >= 0.0.2
|
||||||
uvicorn >= 0.21.1
|
uvicorn >= 0.21.1
|
||||||
typing_extensions~=4.12.2
|
typing_extensions~=4.12.2
|
||||||
|
flask_cors >= 5.0.1
|
||||||
|
typing_extensions==4.12.2
|
||||||
|
Flask-Testing==0.8.1
|
||||||
|
starlette==0.46.1
|
||||||
|
typing_extensions==4.12.2
|
||||||
|
PyJWT==2.10.1
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
123
|
||||||
@@ -11,3 +11,10 @@ werkzeug == 3.1.3
|
|||||||
swagger-ui-bundle >= 0.0.2
|
swagger-ui-bundle >= 0.0.2
|
||||||
uvicorn >= 0.21.1
|
uvicorn >= 0.21.1
|
||||||
typing_extensions~=4.12.2
|
typing_extensions~=4.12.2
|
||||||
|
flask_cors >= 5.0.1
|
||||||
|
typing_extensions==4.12.2
|
||||||
|
Flask-Testing==0.8.1
|
||||||
|
starlette==0.46.1
|
||||||
|
|
||||||
|
typing_extensions==4.12.2
|
||||||
|
PyJWT==2.10.1
|
||||||
Reference in New Issue
Block a user