VBV-488: create edoniq sftp client
This commit is contained in:
parent
7c6d448268
commit
884fc8d5b0
Binary file not shown.
Binary file not shown.
|
|
@ -43,6 +43,8 @@ azure-storage-blob==12.17.0
|
||||||
# django-storages
|
# django-storages
|
||||||
backcall==0.2.0
|
backcall==0.2.0
|
||||||
# via ipython
|
# via ipython
|
||||||
|
bcrypt==4.0.1
|
||||||
|
# via paramiko
|
||||||
beautifulsoup4==4.11.2
|
beautifulsoup4==4.11.2
|
||||||
# via wagtail
|
# via wagtail
|
||||||
black==23.7.0
|
black==23.7.0
|
||||||
|
|
@ -69,6 +71,7 @@ cffi==1.15.1
|
||||||
# via
|
# via
|
||||||
# argon2-cffi-bindings
|
# argon2-cffi-bindings
|
||||||
# cryptography
|
# cryptography
|
||||||
|
# pynacl
|
||||||
cfgv==3.3.1
|
cfgv==3.3.1
|
||||||
# via pre-commit
|
# via pre-commit
|
||||||
charset-normalizer==3.2.0
|
charset-normalizer==3.2.0
|
||||||
|
|
@ -95,6 +98,7 @@ cryptography==41.0.3
|
||||||
# azure-identity
|
# azure-identity
|
||||||
# azure-storage-blob
|
# azure-storage-blob
|
||||||
# msal
|
# msal
|
||||||
|
# paramiko
|
||||||
# pyjwt
|
# pyjwt
|
||||||
decorator==5.1.1
|
decorator==5.1.1
|
||||||
# via
|
# via
|
||||||
|
|
@ -336,6 +340,8 @@ packaging==23.1
|
||||||
# marshmallow
|
# marshmallow
|
||||||
# pytest
|
# pytest
|
||||||
# pytest-sugar
|
# pytest-sugar
|
||||||
|
paramiko==3.3.1
|
||||||
|
# via -r requirements.in
|
||||||
parso==0.8.3
|
parso==0.8.3
|
||||||
# via jedi
|
# via jedi
|
||||||
pathspec==0.11.2
|
pathspec==0.11.2
|
||||||
|
|
@ -400,6 +406,8 @@ pylint-django==2.5.3
|
||||||
# via -r requirements-dev.in
|
# via -r requirements-dev.in
|
||||||
pylint-plugin-utils==0.8.2
|
pylint-plugin-utils==0.8.2
|
||||||
# via pylint-django
|
# via pylint-django
|
||||||
|
pynacl==1.5.0
|
||||||
|
# via paramiko
|
||||||
pyproject-hooks==1.0.0
|
pyproject-hooks==1.0.0
|
||||||
# via build
|
# via build
|
||||||
pytest==7.4.0
|
pytest==7.4.0
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ python-json-logger
|
||||||
concurrent-log-handler
|
concurrent-log-handler
|
||||||
python-dateutil
|
python-dateutil
|
||||||
pycryptodome
|
pycryptodome
|
||||||
|
paramiko
|
||||||
|
|
||||||
wagtail>=4
|
wagtail>=4
|
||||||
wagtail-factories>=4
|
wagtail-factories>=4
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ azure-storage-blob==12.17.0
|
||||||
# via
|
# via
|
||||||
# -r requirements.in
|
# -r requirements.in
|
||||||
# django-storages
|
# django-storages
|
||||||
|
bcrypt==4.0.1
|
||||||
|
# via paramiko
|
||||||
beautifulsoup4==4.11.2
|
beautifulsoup4==4.11.2
|
||||||
# via wagtail
|
# via wagtail
|
||||||
boto3==1.28.23
|
boto3==1.28.23
|
||||||
|
|
@ -52,6 +54,7 @@ cffi==1.15.1
|
||||||
# via
|
# via
|
||||||
# argon2-cffi-bindings
|
# argon2-cffi-bindings
|
||||||
# cryptography
|
# cryptography
|
||||||
|
# pynacl
|
||||||
charset-normalizer==3.2.0
|
charset-normalizer==3.2.0
|
||||||
# via requests
|
# via requests
|
||||||
click==8.1.6
|
click==8.1.6
|
||||||
|
|
@ -67,6 +70,7 @@ cryptography==41.0.3
|
||||||
# azure-identity
|
# azure-identity
|
||||||
# azure-storage-blob
|
# azure-storage-blob
|
||||||
# msal
|
# msal
|
||||||
|
# paramiko
|
||||||
# pyjwt
|
# pyjwt
|
||||||
defusedxml==0.7.1
|
defusedxml==0.7.1
|
||||||
# via willow
|
# via willow
|
||||||
|
|
@ -211,6 +215,8 @@ packaging==23.1
|
||||||
# via
|
# via
|
||||||
# gunicorn
|
# gunicorn
|
||||||
# marshmallow
|
# marshmallow
|
||||||
|
paramiko==3.3.1
|
||||||
|
# via -r requirements.in
|
||||||
pillow==10.0.0
|
pillow==10.0.0
|
||||||
# via
|
# via
|
||||||
# -r requirements.in
|
# -r requirements.in
|
||||||
|
|
@ -234,6 +240,8 @@ pycryptodome==3.18.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
pyjwt[crypto]==2.8.0
|
pyjwt[crypto]==2.8.0
|
||||||
# via msal
|
# via msal
|
||||||
|
pynacl==1.5.0
|
||||||
|
# via paramiko
|
||||||
python-dateutil==2.8.2
|
python-dateutil==2.8.2
|
||||||
# via
|
# via
|
||||||
# -r requirements.in
|
# -r requirements.in
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
import csv
|
||||||
|
import os
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
import paramiko
|
||||||
|
import structlog
|
||||||
|
|
||||||
|
logger = structlog.get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _create_edoniq_sftp_client():
|
||||||
|
client = paramiko.SSHClient()
|
||||||
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
|
|
||||||
|
# Get the private key from the environment variable and convert it to a key object
|
||||||
|
private_key_env_var_name = "IT_EDONIQ_SFTP_PRIVATE_KEY"
|
||||||
|
private_key_str = os.environ.get(private_key_env_var_name).replace("\\n", "\n")
|
||||||
|
if not private_key_str:
|
||||||
|
logger.warn(
|
||||||
|
"Environment variable not set or empty",
|
||||||
|
env_var=private_key_env_var_name,
|
||||||
|
label="edoniq_import",
|
||||||
|
)
|
||||||
|
raise ValueError(
|
||||||
|
f"Environment variable {private_key_env_var_name} not set or empty."
|
||||||
|
)
|
||||||
|
|
||||||
|
private_key_file = StringIO(private_key_str)
|
||||||
|
private_key = paramiko.Ed25519Key.from_private_key(private_key_file)
|
||||||
|
|
||||||
|
client.connect(
|
||||||
|
hostname="217.20.192.94",
|
||||||
|
port=20041,
|
||||||
|
username="sftpuser",
|
||||||
|
pkey=private_key,
|
||||||
|
)
|
||||||
|
|
||||||
|
return client.open_sftp(), client
|
||||||
|
|
||||||
|
|
||||||
|
class EdoniqSftpClient:
|
||||||
|
def __enter__(self):
|
||||||
|
(self.sftp_client, self.ssh_client) = _create_edoniq_sftp_client()
|
||||||
|
return self.sftp_client
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_value, exc_traceback):
|
||||||
|
# self.sftp_client.close()
|
||||||
|
self.ssh_client.close()
|
||||||
|
|
||||||
|
|
||||||
|
def load_edoniq_test_results_csv_data():
|
||||||
|
with EdoniqSftpClient() as sftp_client:
|
||||||
|
with sftp_client.file("/upload/PruefungResultate.csv", "r") as file:
|
||||||
|
data = file.read().decode("utf-8")
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
csv_data = load_edoniq_test_results_csv_data()
|
||||||
|
csv_reader = csv.reader(StringIO(csv_data), delimiter=";")
|
||||||
|
for i, row in enumerate(csv_reader):
|
||||||
|
if len(row) > 4 and row[4] == "AG 2023 A" and row[5] == "de_üK1_BA_KN":
|
||||||
|
print(row)
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
Benutzer Login;Benutzer Name;Benutzer Vorname;Korrespondenzsprache;OE;Sequenztitel;Sequenz ID;letztes Datum der Durchführung des Kandidaten;Zeitstempel Beginn;Bearbeitungsdauer;erreichte Punkte absolut ; erreichbares Punktetotal absolut;erreichte Punkte;Bestehensgrenze prozentual;Bestanden-/Nicht-Bestanden Status;Note;prozentualer Durchschnitt der Versuche dieses Kandidaten;prozentualer Durchschnitt aller Kandidaten
|
||||||
|
;
|
||||||
|
cc36ad95-d09c-4187-b1d4-689ada3ef497;Sommer;Diego;de;AG 2023 A;de_üK1_BA_KN;1688059890497;06.09.2023;06.09.2023 18:48;00:17:10.4650;21.25 ; 29;73.28;60;Bestanden;;73.28;65.91
|
||||||
|
58fdb8e2-881d-48fd-8df9-05f31586e909;Demirel;Beyzanur;de;AG 2023 A;de_üK1_BA_KN;1688059890497;07.09.2023;07.09.2023 19:00;00:17:49.8550;12.23 ; 29;42.16;60;Nicht bestanden;;42.16;65.91
|
||||||
|
19d4e374-7300-45cc-a420-bebe184c5c4e;Appert;Mascha;de;AG 2023 A;de_üK1_BA_KN;1688059890497;10.09.2023;10.09.2023 10:48;00:18:22.9710;17.62 ; 29;60.76;60;Bestanden;;60.76;65.91
|
||||||
|
29610d7c-ed48-43b8-ab71-ce0e726aada4;Gianformaggio;Ylaria;de;AG 2023 A;de_üK1_KO_Testlauf;1686325621487;10.09.2023;10.09.2023 16:32;00:00:00.0000;0.00 ; 15;0.00;60;Begonnen;;38.11;55.30
|
||||||
|
Loading…
Reference in New Issue