added port_id and ports endpoint to flask app (no validation yet!), reading works
This commit is contained in:
parent
c796be2892
commit
489dfc2ed6
@ -1,7 +1,7 @@
|
||||
|
||||
//----------------------
|
||||
// <auto-generated>
|
||||
// Generated REST API Client Code Generator v1.9.8.0 on 12.09.2024 16:39:15
|
||||
// Generated REST API Client Code Generator v1.9.8.0 on 13.09.2024 16:04:34
|
||||
// Using the tool OpenAPI Generator v7.4.0
|
||||
// </auto-generated>
|
||||
//----------------------
|
||||
@ -7729,10 +7729,11 @@ namespace BreCalClient.misc.Model
|
||||
/// <param name="city">city.</param>
|
||||
/// <param name="type">a logical combination (bitflag) of possible values. This cannot be encoded in a Enumeration type with discrete values in OpenAPI version < 3.1..</param>
|
||||
/// <param name="flags">Bit-encoded flag array for internal use.</param>
|
||||
/// <param name="ports">ports.</param>
|
||||
/// <param name="created">Readonly field set by the database when participant was created.</param>
|
||||
/// <param name="modified">Readonly field set by the database when participant was last modified.</param>
|
||||
/// <param name="deleted">marks the participant as logically deleted (default to false).</param>
|
||||
public Participant(int id = default(int), string name = default(string), string street = default(string), string postalCode = default(string), string city = default(string), int type = default(int), int? flags = default(int?), DateTime created = default(DateTime), DateTime? modified = default(DateTime?), bool deleted = false)
|
||||
public Participant(int id = default(int), string name = default(string), string street = default(string), string postalCode = default(string), string city = default(string), int type = default(int), int? flags = default(int?), List<int> ports = default(List<int>), DateTime created = default(DateTime), DateTime? modified = default(DateTime?), bool deleted = false)
|
||||
{
|
||||
this.Id = id;
|
||||
this.Name = name;
|
||||
@ -7741,6 +7742,7 @@ namespace BreCalClient.misc.Model
|
||||
this.City = city;
|
||||
this.Type = type;
|
||||
this.Flags = flags;
|
||||
this.Ports = ports;
|
||||
this.Created = created;
|
||||
this.Modified = modified;
|
||||
this.Deleted = deleted;
|
||||
@ -7790,6 +7792,12 @@ namespace BreCalClient.misc.Model
|
||||
[DataMember(Name = "flags", EmitDefaultValue = true)]
|
||||
public int? Flags { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or Sets Ports
|
||||
/// </summary>
|
||||
/// <example>[1,2]</example>
|
||||
[DataMember(Name = "ports", EmitDefaultValue = true)]
|
||||
public List<int> Ports { get; set; }
|
||||
/// <summary>
|
||||
/// Readonly field set by the database when participant was created
|
||||
/// </summary>
|
||||
/// <value>Readonly field set by the database when participant was created</value>
|
||||
@ -7825,6 +7833,7 @@ namespace BreCalClient.misc.Model
|
||||
sb.Append(" City: ").Append(City).Append("\n");
|
||||
sb.Append(" Type: ").Append(Type).Append("\n");
|
||||
sb.Append(" Flags: ").Append(Flags).Append("\n");
|
||||
sb.Append(" Ports: ").Append(Ports).Append("\n");
|
||||
sb.Append(" Created: ").Append(Created).Append("\n");
|
||||
sb.Append(" Modified: ").Append(Modified).Append("\n");
|
||||
sb.Append(" Deleted: ").Append(Deleted).Append("\n");
|
||||
@ -7893,6 +7902,12 @@ namespace BreCalClient.misc.Model
|
||||
(this.Flags != null &&
|
||||
this.Flags.Equals(input.Flags))
|
||||
) &&
|
||||
(
|
||||
this.Ports == input.Ports ||
|
||||
this.Ports != null &&
|
||||
input.Ports != null &&
|
||||
this.Ports.SequenceEqual(input.Ports)
|
||||
) &&
|
||||
(
|
||||
this.Created == input.Created ||
|
||||
(this.Created != null &&
|
||||
@ -7939,6 +7954,10 @@ namespace BreCalClient.misc.Model
|
||||
{
|
||||
hashCode = (hashCode * 59) + this.Flags.GetHashCode();
|
||||
}
|
||||
if (this.Ports != null)
|
||||
{
|
||||
hashCode = (hashCode * 59) + this.Ports.GetHashCode();
|
||||
}
|
||||
if (this.Created != null)
|
||||
{
|
||||
hashCode = (hashCode * 59) + this.Created.GetHashCode();
|
||||
|
||||
@ -789,7 +789,6 @@ paths:
|
||||
$ref: '#/components/responses/500'
|
||||
'503':
|
||||
$ref: '#/components/responses/503'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
credentials:
|
||||
@ -1593,6 +1592,17 @@ components:
|
||||
participant:
|
||||
type: object
|
||||
description: A organisational entity that participates in Bremen Calling
|
||||
example:
|
||||
id: 42
|
||||
name: BSMD
|
||||
street: Hermann-Hollerith-Str. 7
|
||||
postal code: '28359'
|
||||
city: Bremen
|
||||
type: 10
|
||||
flags: 0
|
||||
created: '2023-08-21T08:23:35Z'
|
||||
modified: '2023-08-21T08:23:35Z'
|
||||
deleted: false
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
@ -1620,8 +1630,21 @@ components:
|
||||
flags:
|
||||
description: Bit-encoded flag array for internal use
|
||||
type: integer
|
||||
nullable: true
|
||||
example: 0
|
||||
nullable: true
|
||||
ports:
|
||||
type: array
|
||||
x-stoplight:
|
||||
id: cj29rdqeg15b3
|
||||
items:
|
||||
x-stoplight:
|
||||
id: is7kj0fmlc1nz
|
||||
type: integer
|
||||
minimum: 1
|
||||
example: 1
|
||||
example:
|
||||
- 1
|
||||
- 2
|
||||
created:
|
||||
type: string
|
||||
format: date-time
|
||||
@ -1630,25 +1653,14 @@ components:
|
||||
modified:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
description: Readonly field set by the database when participant was last modified
|
||||
example: '2023-08-21T08:23:35Z'
|
||||
nullable: true
|
||||
deleted:
|
||||
description: marks the participant as logically deleted
|
||||
type: boolean
|
||||
default: false
|
||||
example: false
|
||||
example:
|
||||
id: 42
|
||||
name: BSMD
|
||||
street: Hermann-Hollerith-Str. 7
|
||||
postal code: '28359'
|
||||
city: Bremen
|
||||
type: 10
|
||||
flags: 0
|
||||
created: '2023-08-21T08:23:35Z'
|
||||
modified: '2023-08-21T08:23:35Z'
|
||||
deleted: false
|
||||
participant_list:
|
||||
description: List of participants
|
||||
type: array
|
||||
|
||||
@ -13,6 +13,7 @@ from .api import ships
|
||||
from .api import login
|
||||
from .api import user
|
||||
from .api import history
|
||||
from .api import ports
|
||||
|
||||
from BreCal.brecal_utils.file_handling import get_project_root, ensure_path
|
||||
from BreCal.brecal_utils.test_handling import execute_test_with_pytest, execute_coverage_test
|
||||
@ -65,6 +66,7 @@ def create_app(test_config=None, instance_path=None):
|
||||
app.register_blueprint(login.bp)
|
||||
app.register_blueprint(user.bp)
|
||||
app.register_blueprint(history.bp)
|
||||
app.register_blueprint(ports.bp)
|
||||
|
||||
logging.basicConfig(filename='brecaldevel.log', level=logging.DEBUG, format='%(asctime)s | %(name)s | %(levelname)s | %(message)s')
|
||||
local_db.initPool(os.path.dirname(app.instance_path))
|
||||
|
||||
@ -3,6 +3,7 @@ from flask import Blueprint, request
|
||||
from webargs.flaskparser import parser
|
||||
from .. import impl
|
||||
from ..services.auth_guard import auth_guard
|
||||
from ..services.jwt_handler import decode_jwt
|
||||
import json
|
||||
from BreCal.validators.validation_error import create_dynamic_exception_response
|
||||
|
||||
@ -16,7 +17,10 @@ def GetBerths():
|
||||
try:
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization')
|
||||
return impl.berths.GetBerths(token)
|
||||
payload = decode_jwt(token.split("Bearer ")[-1])
|
||||
options = {}
|
||||
options["participant_id"] = payload["participant_id"]
|
||||
return impl.berths.GetBerths(options)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ import logging
|
||||
from flask import Blueprint, request
|
||||
from .. import impl
|
||||
from ..services.auth_guard import auth_guard
|
||||
from ..services.jwt_handler import decode_jwt
|
||||
import json
|
||||
from BreCal.validators.validation_error import create_dynamic_exception_response
|
||||
|
||||
@ -13,9 +14,14 @@ def GetParticipant():
|
||||
|
||||
try:
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization')
|
||||
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
||||
options = {}
|
||||
options["user_id"] = request.args.get("user_id")
|
||||
if "participant_id" in payload:
|
||||
options["participant_id"] = payload["participant_id"]
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authorized")
|
||||
|
||||
return impl.participant.GetParticipant(options)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
|
||||
24
src/server/BreCal/api/ports.py
Normal file
24
src/server/BreCal/api/ports.py
Normal file
@ -0,0 +1,24 @@
|
||||
import logging
|
||||
from flask import Blueprint, request
|
||||
from webargs.flaskparser import parser
|
||||
from .. import impl
|
||||
from ..services.auth_guard import auth_guard
|
||||
import json
|
||||
from BreCal.validators.validation_error import create_dynamic_exception_response
|
||||
|
||||
bp = Blueprint('ports', __name__)
|
||||
|
||||
|
||||
@bp.route('/ports', methods=['get'])
|
||||
@auth_guard() # no restriction by role
|
||||
def GetPorts():
|
||||
|
||||
try:
|
||||
if 'Authorization' in request.headers:
|
||||
token = request.headers.get('Authorization')
|
||||
return impl.ports.GetPorts(token)
|
||||
else:
|
||||
return create_dynamic_exception_response(ex=None, status_code=403, message="not authenticated")
|
||||
|
||||
except Exception as ex:
|
||||
return create_dynamic_exception_response(ex=ex, status_code=400)
|
||||
@ -7,6 +7,7 @@ from ..services.auth_guard import auth_guard, check_jwt
|
||||
from BreCal.validators.input_validation import validate_posted_shipcall_data, check_if_user_is_bsmd_type
|
||||
from BreCal.validators.input_validation_shipcall import InputValidationShipcall
|
||||
from BreCal.database.sql_handler import execute_sql_query_standalone
|
||||
from BreCal.services.jwt_handler import decode_jwt
|
||||
from BreCal.validators.validation_error import create_validation_error_response, create_werkzeug_error_response, create_dynamic_exception_response
|
||||
from . import verify_if_request_is_json
|
||||
|
||||
@ -32,9 +33,10 @@ def GetShipcalls():
|
||||
# oneline:
|
||||
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
||||
"""
|
||||
payload = decode_jwt(request.headers.get("Authorization").split("Bearer ")[-1])
|
||||
options = {}
|
||||
options["participant_id"] = request.args.get("participant_id")
|
||||
options["past_days"] = request.args.get("past_days", default=1, type=int)
|
||||
options["participant_id"] = payload["participant_id"]
|
||||
|
||||
return impl.shipcalls.GetShipcalls(options)
|
||||
else:
|
||||
|
||||
@ -10,20 +10,22 @@ def create_sql_query_shipcall_get(options:dict)->str:
|
||||
options : dict. A dictionary, which must contains the 'past_days' key (int). Determines the range
|
||||
by which shipcalls are filtered.
|
||||
"""
|
||||
query = ("SELECT s.id as id, ship_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, " +
|
||||
query = ("SELECT s.id as id, ship_id, port_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, " +
|
||||
"flags, s.pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, " +
|
||||
"tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, evaluation, " +
|
||||
"evaluation_message, evaluation_time, evaluation_notifications_sent, s.created as created, s.modified as modified, time_ref_point " +
|
||||
"FROM shipcall s " +
|
||||
"LEFT JOIN times t ON t.shipcall_id = s.id AND t.participant_type = 8 " +
|
||||
"WHERE " +
|
||||
"port_id in (SELECT port_id FROM participant_port_map WHERE participant_id = %d)" +
|
||||
" AND (" +
|
||||
"(type = 1 AND " +
|
||||
"((t.id IS NOT NULL AND t.eta_berth >= DATE(NOW() - INTERVAL %d DAY)) OR " +
|
||||
"(eta >= DATE(NOW() - INTERVAL %d DAY)))) OR " +
|
||||
"((type = 2 OR type = 3) AND " +
|
||||
"((t.id IS NOT NULL AND t.etd_berth >= DATE(NOW() - INTERVAL %d DAY)) OR " +
|
||||
"(etd >= DATE(NOW() - INTERVAL %d DAY)))) " +
|
||||
"ORDER BY eta") % (options["past_days"], options["past_days"], options["past_days"], options["past_days"])
|
||||
"(etd >= DATE(NOW() - INTERVAL %d DAY))))) " +
|
||||
"ORDER BY eta") % (options["participant_id"], options["past_days"], options["past_days"], options["past_days"], options["past_days"])
|
||||
|
||||
return query
|
||||
|
||||
|
||||
@ -7,3 +7,4 @@ from . import ships
|
||||
from . import login
|
||||
from . import user
|
||||
from . import history
|
||||
from . import ports
|
||||
@ -4,9 +4,8 @@ import pydapper
|
||||
|
||||
from ..schemas import model
|
||||
from .. import local_db
|
||||
from BreCal.database.sql_queries import SQLQuery
|
||||
|
||||
def GetBerths(token):
|
||||
def GetBerths(options):
|
||||
"""
|
||||
No parameters, gets all entries
|
||||
"""
|
||||
@ -14,9 +13,13 @@ def GetBerths(token):
|
||||
try:
|
||||
pooledConnection = local_db.getPoolConnection()
|
||||
commands = pydapper.using(pooledConnection)
|
||||
# query = SQLQuery.get_berth()
|
||||
# data = commands.query(query, model=model.Berth)
|
||||
data = commands.query("SELECT id, name, `lock`, owner_id, authority_id, created, modified, deleted FROM berth WHERE deleted = 0 ORDER BY name", model=model.Berth)
|
||||
|
||||
# only load berths to ports that the participant is assigned to
|
||||
query = ("SELECT id, name, `lock`, owner_id, port_id, authority_id, created, modified, deleted FROM berth WHERE " +
|
||||
"deleted = 0 AND + "
|
||||
"port_id IN (SELECT port_id FROM participant_port_map WHERE participant_id = %d) " +
|
||||
"ORDER BY name") % (options["participant_id"])
|
||||
data = commands.query(query, model=model.Berth)
|
||||
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
||||
|
||||
except Exception as ex:
|
||||
|
||||
@ -10,7 +10,6 @@ def GetParticipant(options):
|
||||
"""
|
||||
:param options: A dictionary containing all the paramters for the Operations
|
||||
options["user_id"]: **Id of user**. *Example: 2*. User id returned by login call.
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
@ -18,10 +17,28 @@ def GetParticipant(options):
|
||||
commands = pydapper.using(pooledConnection)
|
||||
if "user_id" in options and options["user_id"]:
|
||||
# query = SQLQuery.get_participant_by_user_id()
|
||||
data = commands.query("SELECT p.id as id, p.name as name, p.street as street, p.postal_code as postal_code, p.city as city, p.type as type, p.flags as flags, p.created as created, p.modified as modified, p.deleted as deleted FROM participant p INNER JOIN user u WHERE u.participant_id = p.id and u.id = ?userid?", model=model.Participant, param={"userid" : options["user_id"]})
|
||||
query = ("SELECT p.id as id, p.name as name, p.street as street, p.postal_code as postal_code, p.city as city, p.type as type, p.flags as flags, " +
|
||||
"p.created as created, p.modified as modified, p.deleted as deleted FROM participant p " +
|
||||
"INNER JOIN user u WHERE u.participant_id = p.id and u.id = %d") % options["user_id"]
|
||||
data = commands.query(query, model=model.Participant)
|
||||
else:
|
||||
# query = SQLQuery.get_participants()
|
||||
data = commands.query("SELECT id, name, street, postal_code, city, type, flags, created, modified, deleted FROM participant p ORDER BY p.name", model=model.Participant)
|
||||
|
||||
# list only participants that are assigned to the same ports than participant of caller
|
||||
query = ("SELECT p.id as id, name, street, postal_code, city, type, flags, p.created, p.modified, p.deleted " +
|
||||
"FROM participant p " +
|
||||
"JOIN participant_port_map ON p.id = participant_port_map.participant_id " +
|
||||
"WHERE participant_port_map.port_id IN " +
|
||||
"(SELECT port_id FROM participant_port_map where participant_id = %d) " +
|
||||
"GROUP BY id " +
|
||||
"ORDER BY p.name") % options["participant_id"]
|
||||
|
||||
data = commands.query(query, model=model.Participant)
|
||||
for participant in data:
|
||||
port_query = "SELECT port_id FROM participant_port_map WHERE participant_id=?id?";
|
||||
for record in commands.query(port_query, model=model.Port_Assignment, param={"id" : participant.id}, buffered=False):
|
||||
pa = model.Port_Assignment(record.port_id)
|
||||
participant.ports.append(pa.port_id)
|
||||
|
||||
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
||||
|
||||
|
||||
33
src/server/BreCal/impl/ports.py
Normal file
33
src/server/BreCal/impl/ports.py
Normal file
@ -0,0 +1,33 @@
|
||||
import json
|
||||
import logging
|
||||
import pydapper
|
||||
|
||||
from ..schemas import model
|
||||
from .. import local_db
|
||||
from BreCal.database.sql_queries import SQLQuery
|
||||
|
||||
def GetPorts(token):
|
||||
"""
|
||||
No parameters, gets all entries
|
||||
"""
|
||||
|
||||
try:
|
||||
pooledConnection = local_db.getPoolConnection()
|
||||
commands = pydapper.using(pooledConnection)
|
||||
data = commands.query("SELECT id, name, locode, created, modified, deleted FROM port WHERE deleted = 0 ORDER BY name", model=model.Port)
|
||||
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
|
||||
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
result = {}
|
||||
result["message"] = "call failed"
|
||||
return json.dumps(result), 500
|
||||
|
||||
finally:
|
||||
if pooledConnection is not None:
|
||||
pooledConnection.close()
|
||||
|
||||
|
||||
|
||||
|
||||
@ -29,6 +29,15 @@ class Berth(Schema):
|
||||
lock: bool
|
||||
owner_id: int
|
||||
authority_id: int
|
||||
port_id: int
|
||||
created: datetime
|
||||
modified: datetime
|
||||
deleted: bool
|
||||
|
||||
class Port(Schema):
|
||||
id: int
|
||||
name: str
|
||||
locode: str
|
||||
created: datetime
|
||||
modified: datetime
|
||||
deleted: bool
|
||||
@ -168,6 +177,7 @@ class Participant(Schema):
|
||||
created: datetime
|
||||
modified: datetime
|
||||
deleted: bool
|
||||
ports: List[int] = field(default_factory=list)
|
||||
|
||||
@validates("type")
|
||||
def validate_type(self, value):
|
||||
@ -269,6 +279,16 @@ class Participant_Assignment:
|
||||
def to_json(self):
|
||||
return self.__dict__
|
||||
|
||||
@dataclass
|
||||
class Port_Assignment:
|
||||
def __init__(self, port_id):
|
||||
self.port_id = port_id
|
||||
pass
|
||||
|
||||
port_id: int
|
||||
|
||||
def to_json(self):
|
||||
return self.__dict__
|
||||
|
||||
@dataclass
|
||||
class Shipcall:
|
||||
@ -301,6 +321,7 @@ class Shipcall:
|
||||
evaluation_time: datetime
|
||||
evaluation_notifications_sent: bool
|
||||
time_ref_point: int
|
||||
port_id: int
|
||||
created: datetime
|
||||
modified: datetime
|
||||
participants: List[Participant_Assignment] = field(default_factory=list)
|
||||
@ -335,6 +356,7 @@ class Shipcall:
|
||||
"evaluation_time": self.evaluation_time.isoformat() if self.evaluation_time else "",
|
||||
"evaluation_notifications_sent": self.evaluation_notifications_sent,
|
||||
"time_ref_point": self.time_ref_point,
|
||||
"port_id": self.port_id,
|
||||
"created": self.created.isoformat() if self.created else "",
|
||||
"modified": self.modified.isoformat() if self.modified else "",
|
||||
"participants": [participant.__dict__ for participant in self.participants]
|
||||
@ -343,8 +365,8 @@ class Shipcall:
|
||||
|
||||
|
||||
@classmethod
|
||||
def from_query_row(self, id, ship_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, flags, pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, evaluation, evaluation_message, evaluation_time, evaluation_notifications_sent, time_ref_point, created, modified):
|
||||
return self(id, ship_id, ShipcallType(type), eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, flags, pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, EvaluationType(evaluation), evaluation_message, evaluation_time, evaluation_notifications_sent, time_ref_point, created, modified)
|
||||
def from_query_row(self, id, ship_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, flags, pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, evaluation, evaluation_message, evaluation_time, evaluation_notifications_sent, time_ref_point, port_id, created, modified):
|
||||
return self(id, ship_id, ShipcallType(type), eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, flags, pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, EvaluationType(evaluation), evaluation_message, evaluation_time, evaluation_notifications_sent, time_ref_point, port_id, created, modified)
|
||||
|
||||
class ShipcallId(Schema):
|
||||
pass
|
||||
|
||||
Loading…
Reference in New Issue
Block a user