Merged current state of develop

This commit is contained in:
Daniel Schick 2024-02-14 10:56:35 +01:00
commit 898cfdf07d
12 changed files with 145 additions and 70 deletions

View File

@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BreCalClient" xmlns:local="clr-namespace:BreCalClient"
StartupUri="MainWindow.xaml" Exit="Application_Exit"> StartupUri="MainWindow.xaml" Exit="Application_Exit" Startup="Application_Startup" >
<Application.Resources> <Application.Resources>
<ResourceDictionary> <ResourceDictionary>

View File

@ -1,4 +1,5 @@
using BreCalClient.misc.Model; using BreCalClient.misc.Model;
using BreCalClient.Properties;
using System.Windows; using System.Windows;
namespace BreCalClient namespace BreCalClient
@ -14,5 +15,20 @@ namespace BreCalClient
{ {
BreCalClient.Properties.Settings.Default.Save(); BreCalClient.Properties.Settings.Default.Save();
} }
private void Application_Startup(object sender, StartupEventArgs e)
{
// Window size sanity check
if(Settings.Default.Width == 0)
{
Settings.Default.Width = 800;
Settings.Default.Save();
}
if(Settings.Default.Height == 0)
{
Settings.Default.Height = 450;
Settings.Default.Save();
}
}
} }
} }

View File

@ -47,7 +47,7 @@
<Label Content="ETA" Grid.Column="2" Grid.Row="2" HorizontalContentAlignment="Right"/> <Label Content="ETA" Grid.Column="2" Grid.Row="2" HorizontalContentAlignment="Right"/>
<Label Content="ETD" Grid.Column="2" Grid.Row="3" HorizontalContentAlignment="Right"/> <Label Content="ETD" Grid.Column="2" Grid.Row="3" HorizontalContentAlignment="Right"/>
<ComboBox x:Name="comboBoxCategories" Grid.Column="3" Margin="2" Grid.Row="0" SelectedValuePath="Key" SelectionChanged="comboBoxCategories_SelectionChanged"/> <ComboBox x:Name="comboBoxCategories" Grid.Column="3" Margin="2" Grid.Row="0" SelectionChanged="comboBoxCategories_SelectionChanged"/>
<Label Content="{x:Static p:Resources.textBerth}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Right"/> <Label Content="{x:Static p:Resources.textBerth}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Right"/>
<Grid Grid.Row="1" Grid.Column="3"> <Grid Grid.Row="1" Grid.Column="3">

View File

@ -18,9 +18,12 @@ using BreCalClient.misc.Model;
using static BreCalClient.Extensions; using static BreCalClient.Extensions;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Security.Principal;
using Polly;
using System.Net.Http;
using System.Net; using System.Net;
namespace BreCalClient namespace BreCalClient
{ {
/// <summary> /// <summary>
@ -35,8 +38,7 @@ namespace BreCalClient
#region Fields #region Fields
private static Int32 _uiUpdateRunning = 0; private static Int32 _uiUpdateRunning = 0;
private Timer? _timer;
private Credentials? _credentials; private Credentials? _credentials;
private readonly ConcurrentDictionary<int, ShipcallControlModel> _allShipcallsDict = new(); private readonly ConcurrentDictionary<int, ShipcallControlModel> _allShipcallsDict = new();
@ -87,7 +89,29 @@ namespace BreCalClient
_staticApi = new StaticApi(Properties.Settings.Default.API_URL); _staticApi = new StaticApi(Properties.Settings.Default.API_URL);
_staticApi.Configuration.ApiKeyPrefix["Authorization"] = "Bearer"; _staticApi.Configuration.ApiKeyPrefix["Authorization"] = "Bearer";
_shipApi = new ShipApi(Properties.Settings.Default.API_URL); _shipApi = new ShipApi(Properties.Settings.Default.API_URL);
_shipApi.Configuration.ApiKeyPrefix["Authorization"] = "Bearer"; _shipApi.Configuration.ApiKeyPrefix["Authorization"] = "Bearer";
const int maxDelayInMilliseconds = 32 * 1000;
var jitterer = new Random();
var retryPolicy =
Policy.Handle<HttpRequestException>()
.OrResult<RestSharp.RestResponse>(resp => resp.StatusCode == HttpStatusCode.Unauthorized)
.WaitAndRetryAsync(3,
retryAttempt =>
{
var calculatedDelayInMilliseconds = Math.Pow(2, retryAttempt) * 1000;
var jitterInMilliseconds = jitterer.Next(0, 1000);
var actualDelay = Math.Min(calculatedDelayInMilliseconds + jitterInMilliseconds, maxDelayInMilliseconds);
return TimeSpan.FromMilliseconds(actualDelay);
},
onRetry: (resp, timespan, context) =>
{
this.RefreshToken(null);
Trace.WriteLine("token refreshed");
});
RetryConfiguration.AsyncRetryPolicy = retryPolicy;
} }
#endregion #endregion
@ -141,8 +165,7 @@ namespace BreCalClient
this._staticApi.Configuration.ApiKey["Authorization"] = _loginResult.Token; this._staticApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
this._shipApi.Configuration.ApiKey["Authorization"] = _loginResult.Token; this._shipApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
this.LoadStaticLists(); this.LoadStaticLists();
this.labelUsername.Text = $"{_loginResult.FirstName} {_loginResult.LastName}"; this.labelUsername.Text = $"{_loginResult.FirstName} {_loginResult.LastName}";
_timer = new Timer(RefreshToken, null, 4000000, Timeout.Infinite);
} }
} }
labelGeneralStatus.Text = $"Connection {ConnectionStatus.SUCCESSFUL}"; labelGeneralStatus.Text = $"Connection {ConnectionStatus.SUCCESSFUL}";
@ -168,8 +191,9 @@ namespace BreCalClient
} }
} }
private void RefreshToken(object? state) private bool RefreshToken(object? state)
{ {
bool result = false;
try try
{ {
_loginResult = _userApi.Login(_credentials); _loginResult = _userApi.Login(_credentials);
@ -181,8 +205,9 @@ namespace BreCalClient
this._timesApi.Configuration.ApiKey["Authorization"] = _loginResult.Token; this._timesApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
this._shipcallApi.Configuration.ApiKey["Authorization"] = _loginResult.Token; this._shipcallApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
this._staticApi.Configuration.ApiKey["Authorization"] = _loginResult.Token; this._staticApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
this._shipApi.Configuration.ApiKey["Authorization"] = _loginResult.Token; this._shipApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
} result = true;
}
} }
else else
{ {
@ -193,6 +218,7 @@ namespace BreCalClient
{ {
_log.ErrorFormat("Error refreshing token: {0}", ex.Message); _log.ErrorFormat("Error refreshing token: {0}", ex.Message);
} }
return result;
} }
private void buttonExit_Click(object sender, RoutedEventArgs e) private void buttonExit_Click(object sender, RoutedEventArgs e)
@ -835,10 +861,13 @@ namespace BreCalClient
private void ShowErrorDialog(string message, string caption) private void ShowErrorDialog(string message, string caption)
{ {
_log.ErrorFormat("{0} - {1}", caption, message);
/*
Dispatcher.Invoke(new Action(() => Dispatcher.Invoke(new Action(() =>
{ {
MessageBox.Show(message, caption, MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(message, caption, MessageBoxButton.OK, MessageBoxImage.Error);
})); }));
*/
} }
private void EnableControlsForParticipant() private void EnableControlsForParticipant()

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->
@ -284,10 +284,10 @@
<value>Neues Passwort wiederholen</value> <value>Neues Passwort wiederholen</value>
</data> </data>
<data name="textReplenishingLock" xml:space="preserve"> <data name="textReplenishingLock" xml:space="preserve">
<value>Versorgungsaufnahme Schleuse</value> <value>Güterübernahme in der Schleuse geplant</value>
</data> </data>
<data name="textReplenishingTerminal" xml:space="preserve"> <data name="textReplenishingTerminal" xml:space="preserve">
<value>Versorgungsaufnahme Terminal</value> <value>Güterübernahme am Terminal geplant</value>
</data> </data>
<data name="textRotated" xml:space="preserve"> <data name="textRotated" xml:space="preserve">
<value>Gedreht</value> <value>Gedreht</value>

View File

@ -14,7 +14,7 @@ def GetBerths(token):
pooledConnection = local_db.getPoolConnection() pooledConnection = local_db.getPoolConnection()
commands = pydapper.using(pooledConnection) commands = pydapper.using(pooledConnection)
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) 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)
pooledConnection.close() return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex: except Exception as ex:
logging.error(ex) logging.error(ex)
@ -23,7 +23,9 @@ def GetBerths(token):
result["message"] = "call failed" result["message"] = "call failed"
return json.dumps(result), 500 return json.dumps(result), 500
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'} finally:
if pooledConnection is not None:
pooledConnection.close()

View File

@ -16,7 +16,6 @@ def GetUser(options):
commands = pydapper.using(pooledConnection) commands = pydapper.using(pooledConnection)
data = commands.query("SELECT id, participant_id, first_name, last_name, user_name, user_email, user_phone, password_hash, api_key, created, modified FROM user WHERE user_name = ?username? OR user_email = ?username?", data = commands.query("SELECT id, participant_id, first_name, last_name, user_name, user_email, user_phone, password_hash, api_key, created, modified FROM user WHERE user_name = ?username? OR user_email = ?username?",
model=model.User, param={"username" : options["username"]}) model=model.User, param={"username" : options["username"]})
pooledConnection.close()
# print(data) # print(data)
if len(data) == 1: if len(data) == 1:
if bcrypt.checkpw(options["password"].encode("utf-8"), bytes(data[0].password_hash, "utf-8")): if bcrypt.checkpw(options["password"].encode("utf-8"), bytes(data[0].password_hash, "utf-8")):
@ -49,6 +48,10 @@ def GetUser(options):
result["message"] = "call failed: " + str(ex) result["message"] = "call failed: " + str(ex)
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
finally:
if pooledConnection is not None:
pooledConnection.close()
# $2b$12$uWLE0r32IrtCV30WkMbVwOdltgeibymZyYAf4ZnQb2Bip8hrkGGwG # $2b$12$uWLE0r32IrtCV30WkMbVwOdltgeibymZyYAf4ZnQb2Bip8hrkGGwG
# $2b$12$.vEapj9xU8z0RK0IpIGeYuRIl0ktdMt4XdJQBhVn.3K2hmvm7qD3y # $2b$12$.vEapj9xU8z0RK0IpIGeYuRIl0ktdMt4XdJQBhVn.3K2hmvm7qD3y
# $2b$12$yL3PiseU70ciwEuMVM4OtuMwR6tNuIT9vvBiBG/uyMrPxa16E2Zqu # $2b$12$yL3PiseU70ciwEuMVM4OtuMwR6tNuIT9vvBiBG/uyMrPxa16E2Zqu

View File

@ -19,7 +19,8 @@ def GetParticipant(options):
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"]}) 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"]})
else: else:
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) 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)
pooledConnection.close()
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex: except Exception as ex:
logging.error(ex) logging.error(ex)
@ -28,5 +29,7 @@ def GetParticipant(options):
result["message"] = "call failed" result["message"] = "call failed"
return json.dumps("call failed"), 500 return json.dumps("call failed"), 500
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'} finally:
if pooledConnection is not None:
pooledConnection.close()

View File

@ -18,11 +18,20 @@ def GetShipcalls(options):
pooledConnection = local_db.getPoolConnection() pooledConnection = local_db.getPoolConnection()
commands = pydapper.using(pooledConnection) commands = pydapper.using(pooledConnection)
query = ("SELECT 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, 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, " "flags, s.pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, " +
"anchored, moored_lock, canceled, evaluation, evaluation_message, evaluation_time, evaluation_notifications_sent, created, modified FROM shipcall WHERE ((type = 1 OR type = 3) AND eta >= DATE(NOW() - INTERVAL %d DAY)" "tidal_window_to, rain_sensitive_cargo, recommended_tugs, anchored, moored_lock, canceled, evaluation, " +
"OR (type = 2 AND etd >= DATE(NOW() - INTERVAL %d DAY))) " "evaluation_message, evaluation_time, evaluation_notifications_sent, s.created as created, s.modified as modified " +
"ORDER BY eta") % (options["past_days"], options["past_days"]) "FROM shipcall s " +
"LEFT JOIN times t ON t.shipcall_id = s.id AND t.participant_type = 8 " +
"WHERE " +
"(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"])
data = commands.query(query, model=model.Shipcall) data = commands.query(query, model=model.Shipcall)
for shipcall in data: for shipcall in data:
@ -32,7 +41,7 @@ def GetShipcalls(options):
pa = model.Participant_Assignment(record["participant_id"], record["type"]) pa = model.Participant_Assignment(record["participant_id"], record["type"])
shipcall.participants.append(pa) shipcall.participants.append(pa)
pooledConnection.close() return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex: except Exception as ex:
logging.error(traceback.format_exc()) logging.error(traceback.format_exc())
@ -42,7 +51,9 @@ def GetShipcalls(options):
result["message"] = "call failed" result["message"] = "call failed"
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'} finally:
if pooledConnection is not None:
pooledConnection.close()
def PostShipcalls(schemaModel): def PostShipcalls(schemaModel):
@ -116,8 +127,6 @@ def PostShipcalls(schemaModel):
query = "INSERT INTO history (participant_id, shipcall_id, user_id, timestamp, eta, type, operation) VALUES (?pid?, ?scid?, ?uid?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 1, 1)" query = "INSERT INTO history (participant_id, shipcall_id, user_id, timestamp, eta, type, operation) VALUES (?pid?, ?scid?, ?uid?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 1, 1)"
commands.execute_scalar(query, {"scid" : new_id, "pid" : user_data["participant_id"], "uid" : user_data["id"]}) commands.execute_scalar(query, {"scid" : new_id, "pid" : user_data["participant_id"], "uid" : user_data["id"]})
pooledConnection.close()
return json.dumps({"id" : new_id}), 201, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps({"id" : new_id}), 201, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex: except Exception as ex:
@ -128,6 +137,10 @@ def PostShipcalls(schemaModel):
result["message"] = "call failed" result["message"] = "call failed"
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
finally:
if pooledConnection is not None:
pooledConnection.close()
def PutShipcalls(schemaModel): def PutShipcalls(schemaModel):
""" """
@ -207,8 +220,6 @@ def PutShipcalls(schemaModel):
query = "INSERT INTO history (participant_id, shipcall_id, user_id, timestamp, eta, type, operation) VALUES (?pid?, ?scid?, ?uid?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 1, 2)" query = "INSERT INTO history (participant_id, shipcall_id, user_id, timestamp, eta, type, operation) VALUES (?pid?, ?scid?, ?uid?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 1, 2)"
commands.execute(query, {"scid" : schemaModel["id"], "pid" : user_data["participant_id"], "uid" : user_data["id"]}) commands.execute(query, {"scid" : schemaModel["id"], "pid" : user_data["participant_id"], "uid" : user_data["id"]})
pooledConnection.close()
return json.dumps({"id" : schemaModel["id"]}), 200 return json.dumps({"id" : schemaModel["id"]}), 200
except Exception as ex: except Exception as ex:
@ -219,5 +230,7 @@ def PutShipcalls(schemaModel):
result["message"] = "call failed" result["message"] = "call failed"
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
finally:
if pooledConnection is not None:
pooledConnection.close()

View File

@ -15,7 +15,8 @@ def GetShips(token):
pooledConnection = local_db.getPoolConnection() pooledConnection = local_db.getPoolConnection()
commands = pydapper.using(pooledConnection) commands = pydapper.using(pooledConnection)
data = commands.query("SELECT id, name, imo, callsign, participant_id, length, width, is_tug, bollard_pull, eni, created, modified, deleted FROM ship ORDER BY name", model=model.Ship) data = commands.query("SELECT id, name, imo, callsign, participant_id, length, width, is_tug, bollard_pull, eni, created, modified, deleted FROM ship ORDER BY name", model=model.Ship)
pooledConnection.close()
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex: except Exception as ex:
logging.error(ex) logging.error(ex)
@ -24,7 +25,10 @@ def GetShips(token):
result["message"] = "call failed" result["message"] = "call failed"
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
return json.dumps(data, default=model.obj_dict), 200, {'Content-Type': 'application/json; charset=utf-8'} finally:
if pooledConnection is not None:
pooledConnection.close()

View File

@ -90,8 +90,6 @@ def PostTimes(schemaModel):
query = "INSERT INTO history (participant_id, shipcall_id, user_id, timestamp, eta, type, operation) VALUES (?pid?, ?scid?, ?uid?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 2, 1)" query = "INSERT INTO history (participant_id, shipcall_id, user_id, timestamp, eta, type, operation) VALUES (?pid?, ?scid?, ?uid?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 2, 1)"
commands.execute_scalar(query, {"scid" : schemaModel["shipcall_id"], "pid" : user_data["participant_id"], "uid" : user_data["id"]}) commands.execute_scalar(query, {"scid" : schemaModel["shipcall_id"], "pid" : user_data["participant_id"], "uid" : user_data["id"]})
pooledConnection.close()
return json.dumps({"id" : new_id}), 201, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps({"id" : new_id}), 201, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex: except Exception as ex:
@ -101,6 +99,10 @@ def PostTimes(schemaModel):
result["message"] = "call failed" result["message"] = "call failed"
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
finally:
if pooledConnection is not None:
pooledConnection.close()
def PutTimes(schemaModel): def PutTimes(schemaModel):
""" """
@ -141,14 +143,10 @@ def PutTimes(schemaModel):
query = "INSERT INTO history (participant_id, shipcall_id, user_id, timestamp, eta, type, operation) VALUES (?pid?, ?scid?, ?uid?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 2, 2)" query = "INSERT INTO history (participant_id, shipcall_id, user_id, timestamp, eta, type, operation) VALUES (?pid?, ?scid?, ?uid?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 2, 2)"
commands.execute_scalar(query, {"scid" : schemaModel["shipcall_id"], "pid" : user_data["participant_id"], "uid" : user_data["id"]}) commands.execute_scalar(query, {"scid" : schemaModel["shipcall_id"], "pid" : user_data["participant_id"], "uid" : user_data["id"]})
pooledConnection.close()
# if affected_rows == 1: # this doesn't work as expected # if affected_rows == 1: # this doesn't work as expected
return json.dumps({"id" : schemaModel["id"]}), 200, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps({"id" : schemaModel["id"]}), 200, {'Content-Type': 'application/json; charset=utf-8'}
# return json.dumps("no such record"), 404, {'Content-Type': 'application/json; charset=utf-8'}
except Exception as ex: except Exception as ex:
logging.error(ex) logging.error(ex)
print(ex) print(ex)
@ -156,6 +154,10 @@ def PutTimes(schemaModel):
result["message"] = "call failed" result["message"] = "call failed"
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
finally:
if pooledConnection is not None:
pooledConnection.close()
def DeleteTimes(options): def DeleteTimes(options):
""" """
:param options: A dictionary containing all the paramters for the Operations :param options: A dictionary containing all the paramters for the Operations
@ -176,8 +178,6 @@ def DeleteTimes(options):
query = "INSERT INTO history (participant_id, shipcall_id, user_id, timestamp, eta, type, operation) VALUES (?pid?, 0, ?uid?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 2, 3)" query = "INSERT INTO history (participant_id, shipcall_id, user_id, timestamp, eta, type, operation) VALUES (?pid?, 0, ?uid?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 2, 3)"
commands.execute_scalar(query, {"pid" : user_data["participant_id"], "uid" : user_data["id"]}) commands.execute_scalar(query, {"pid" : user_data["participant_id"], "uid" : user_data["id"]})
pooledConnection.close()
if affected_rows == 1: if affected_rows == 1:
return json.dumps({"id" : options["id"]}), 200, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps({"id" : options["id"]}), 200, {'Content-Type': 'application/json; charset=utf-8'}
@ -190,4 +190,8 @@ def DeleteTimes(options):
print(ex) print(ex)
result = {} result = {}
result["message"] = "call failed" result["message"] = "call failed"
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
finally:
if pooledConnection is not None:
pooledConnection.close()

View File

@ -56,8 +56,6 @@ def PutUser(schemaModel):
result["message"] = "old password invalid" result["message"] = "old password invalid"
return json.dumps(result), 400, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(result), 400, {'Content-Type': 'application/json; charset=utf-8'}
pooledConnection.close()
return json.dumps({"id" : schemaModel["id"]}), 200 return json.dumps({"id" : schemaModel["id"]}), 200
except Exception as ex: except Exception as ex:
@ -67,5 +65,8 @@ def PutUser(schemaModel):
result["message"] = "call failed" result["message"] = "call failed"
return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'} return json.dumps(result), 500, {'Content-Type': 'application/json; charset=utf-8'}
finally:
if pooledConnection is not None:
pooledConnection.close()