[PYTHON]

Danke für deine harte Arbeit. Python, Google, Übersetzung, GoogleTranslate, googletrans [AWS] Eine Geschichte, die für diejenigen hilfreich sein kann, die Lambda-Python und DynamoDB noch nicht kennen. Einführung Ich interessiere mich kürzlich für serverlose Architektur. Die folgenden 2 Einträge sind Artikel, wenn Java Script mit Google Apps Script verwendet wird. Dieses Mal möchte ich jedoch Lambda unter AWS verwenden, um Python-Code ohne Server auszuführen. Der Inhalt des Artikels ist Python, fast nett, Sie kennenzulernen. AWS Ich werde eine Aufzeichnung schreiben, bis Leute, die fast nett sind, Sie kennenzulernen, verschiedene Dinge mit Lambda und DynamoDB tun können. Außerdem war ich zuerst verzweifelt, weil ich AWS nicht zu gut verstand, Lambda einen Fehler bekam und mich zum ersten Mal tötete, und ich interessiere mich für Python, aber ich habe es weniger verwendet, deshalb würde ich gerne einen Artikel aus der Sicht eines Anfängers schreiben. Es ist, als würde man viele Bilder und Inhalte schreiben, die Anfänger einzeln verstehen können. Ich denke, dass Pythonist- und AWS-Fortgeschrittene möglicherweise neu sind, aber danke.

Der Artikel, den ich das letzte Mal geschrieben habe

Annahme

AWS Schön, Sie kennenzulernen Python-Geschichte ca. 2 Wochen AWS-Service registriert, kostenlose Stufe

AWS In meinem Fall war ich durch die Anzahl der AWS-Services verwirrt, sodass ich zunächst einen Überblick darüber erhielt, welche Services mit welchen Services verbunden sind. Ich denke, das Folgende wird hilfreich sein. Ich habe auch nach kostenlosen Büchern auf dem Kindle gesucht. "Aber ich habe verschiedene Dinge ausprobiert, als ich diesen Artikel durchgesehen habe, während ich ihn selbst benutzt habe.

Fassen wir "AWS ist was" in drei Zeilen zusammen Was ich getan habe und wovon ich in der freien Zeit des ersten Jahres von AWS abhängig war

Anmeldung

Weitere Informationen zur AWS-Registrierung finden Sie in einem anderen Artikel, da davon ausgegangen wird, dass er registriert ist.

Rollenerstellung

Es ist also eine Menge Ärger ohne eine AWS-Rolle Wir werden eine Rolle erstellen, die vollen Zugriff auf S3, DynamoDB und Lambda hat.

IAM von AWS Service List

スクリーンショット 2017-03-15 14.22.30.png

Rolle >> Erstellen Sie eine neue Rolle

スクリーンショット 2017-03-15 14.22.43.png

Rollenname Diesmal [lambda_dynamo]

スクリーンショット 2017-03-15 14.22.48.png

Amazon Lambda >> Auswählen

スクリーンショット 2017-03-15 14.27.00.png

Vorerst werde ich dieses Mal drei Vollzugriffe hinzufügen. AWSLambdaFullAccess AmazonS3FullAccess AmazonDynamoDBFullAccess

Nächster Schritt

スクリーンショット 2017-03-15 14.27.27.png

Rolle >> lambda_dynamo Okay, wenn der aufgerufene Gegenstand hinzugefügt wird.

スクリーンショット 2017-03-15 14.33.21.png

Lambda

Es ist ein Dienst, der Skripte ohne Server ausführen kann. Praktisch.

Gebührenstruktur

Grundsätzlich können Sie damit so viel testen, wie Sie möchtenOffiziell

Lambda-Freirahmen

1 Monat Anfrage Zeit berechnen[GB*Sekunden]
1,000,000 400,000

Anfragen: Gesamtzahl der Anfragen für die gesamte Funktion Rechenzeit: Speicheranzahl und Zeit

Da der Mindestspeicher von Lambda 128 MB beträgt, werden bei Verwendung von 3.200.000 Sekunden () pro Monat 400.000 [GB * Sek.] Erreicht. (128.0[MB] / 1024[MB/GB]) * 3200000[sec] = 400,000[GB*sec] Es ist also in Ordnung, das Skript etwa 888 Stunden lang auszuführen. Lass es uns stetig benutzen. (Bitte versuchen Sie die Zeit selbst zu berechnen!)

Versuchen Sie es mit Testcode (Python-Fehler)

Lambda aus AWS Service List

Erste Funktionserstellung

Erstellen einer Lambda-Funktion >> Lambda-Kanarienvogel

スクリーンショット 2017-03-15 14.52.52.png

[Triggereinstellungen] >> Löschen >> Weiter Hier können Sie das Skript alle paar Minuten einmal ausführen. Kann später eingestellt werden, löschen Sie es also dieses Mal.

[Funktionseinstellungen] Ich habe den Namen vorerst in [sample] geändert.

スクリーンショット 2017-03-15 14.57.34.png

Erstellen Sie eine Funktion, indem Sie die Rolle zu der zuvor erstellten Rolle machen. lambda_dynamo

Erster Test

from __future__ import print_function

import os
from datetime import datetime
from urllib2 import urlopen

SITE = os.environ['site']  # URL of the site to check, stored in the site environment variable
EXPECTED = os.environ['expected']  # String expected to be on the page, stored in the expected environment variable


def validate(res):
    return EXPECTED in res


def lambda_handler(event, context):
    print('Checking {} at {}...'.format(SITE, event['time']))
    try:
        if not validate(urlopen(SITE).read()):
            raise Exception('Validation failed')
    except:
        print('Check failed!')
        raise
    else:
        print('Check passed!')
        return event['time']
    finally:
        print('Check complete at {}'.format(str(datetime.now())))

スクリーンショット 2017-03-15 15.06.42.png

Ja, ich habe einen Fehler erhalten.

    print('Checking {} at {}...'.format(SITE, event['time']))
KeyError: 'time'

Schauen wir uns die standardmäßig verwendeten Variablen an, bevor wir diesen Fehler beheben.

Standardmäßig verwendete Variablen

event >> AWS Lambda verwendet diesen Parameter, um Ereignisdaten an den Handler zu übergeben. Dieser Parameter ist normalerweise ein Python-Diktattyp. Sie können auch die Typen list, str, int, float oder NoneType verwenden.

context >> AWS Lambda verwendet diesen Parameter, um dem Handler Laufzeitinformationen bereitzustellen. Dieser Parameter ist vom Typ LambdaContext.

Es ist geworden.

Diese Umgebungsvariable kann von os.environ übernommen werden

スクリーンショット 2017-03-15 15.15.28.png

time ?

Jetzt werden wir den vorherigen Fehler behandeln.

スクリーンショット 2017-03-15 15.11.53.png

Fügen Sie Zeit für Testereigniseinstellungen hinzu.

{
  "key3": "value3",
  "key2": "value2",
  "key1": "value1",
  "time": "now...!"
}

Ich glaube nicht, dass im Zeitteil ein Fehler vorliegt.

START RequestId: a8708105-0948-11e7-b83e-b71ae2e4dbbe Version: $LATEST
Checking https://www.amazon.com/ at now...!...
Check failed!
Check complete at 2017-03-15 06:28:53.016209
HTTP Error 503: Service Unavailable: HTTPError
Traceback (most recent call last):
  (Kürzung)
  File "/usr/lib64/python2.7/urllib2.py", line 556, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
HTTPError: HTTP Error 503: Service Unavailable

END RequestId: a8708105-0948-11e7-b83e-b71ae2e4dbbe
REPORT RequestId: a8708105-0948-11e7-b83e-b71ae2e4dbbe	Duration: 348.59 ms	Billed Duration: 400 ms 	Memory Size: 128 MB	Max Memory Used: 17 MB

Ich erhalte immer noch eine Fehlermeldung, daher werde ich verschiedene Dinge tun.

außer ich behandle Ausnahmen, also bekomme ich einen Fehler!

Erstens mag ich den roten Bildschirm nicht. Selbst wenn die URL-Anforderung fehlschlägt, verschwindet der Fehler.


    try:
        if not validate(urlopen(SITE).read()):
            raise Exception('Validation failed')
    except:
        print('Check failed!')
        raise

Wenn im Fall von Python am Ende eine Erhöhung eingefügt wird, wird der Fehler an die einfache Python-Anweisung zurückgegeben, wie er ist, nachdem der Fehler mit Ausnahme abgefangen wurde. Schreiben Sie dies neu.


def lambda_handler(event, context):
    print('Checking {} at {}...'.format(SITE, event['time']))
    try:
        if not validate(urlopen(SITE).read()):
            raise Exception('Validation failed')
    except Exception as e:
        print('Check failed!')
        print(e)
    else:
        print('Check passed!')
        return event['time']
    finally:
        print('Check complete at {}'.format(str(datetime.now())))

Endlich war der Green Check erfolgreich ...! !! !! !!

スクリーンショット 2017-03-15 15.44.10.png

Fangen Sie den Fehler mit "außer Ausnahme als e:" ab Geben Sie einen Fehler mit "print (e)" aus Ich habe "Raise" gelöscht und vorerst keinen Fehler gemacht.

Ich habe hier viel über die Fehlerbehandlung von Python recherchiert. erziehen. ..

HTTP Error 503

Da der Fehler weiterhin besteht, schauen wir uns den Teil von "HTTP-Fehler 503: Dienst nicht verfügbar: HTTP-Fehler" an. Da kein Wort "Validierung fehlgeschlagen" vorhanden ist, stellt "validate (urlopen (SITE) .read ())" fest, dass der in diesem Teil zurückgegebene Fehler der oben genannte Fehler ist.

def validate(res):
    return EXPECTED in res

Dies geht zu https://www.amazon.com/ und diagnostiziert, ob die zurückgegebene HTML-Datei das Wort "Online-Shopping" enthält.

Ändern Sie vorerst die Umgebungsvariable von Amazon, um auf Google zuzugreifen

Dann


Checking https://www.google.co.jp/ at now...!...
Check passed!
Check complete at 2017-03-15 07:00:05.723916

Endlich Scheck bestanden! Wird ausgestellt.

503 Service Unavailable Service nicht verfügbar. Der Dienst ist aufgrund von Überlastung oder Wartung vorübergehend nicht verfügbar. Beispielsweise wird es zurückgegeben, wenn der Zugriff überflutet wird und nicht mehr verarbeitet werden kann.

https://www.amazon.com/ Kann nicht fallen. Ich habe vergessen, die Umgebungsvariable zurückzugeben und sie von ganzem Herzen zu überprüfen. Ich habe es in einen Google-Dienst geändert und es hat funktioniert. Verweigern Sie den Zugang von Lambda?

Ich bin süchtig danach.

indent

Es ist ein Python-Fehler, aber ich habe trotz der Anzahl der Indizes mehrmals einen Fehler erhalten.

Syntax error in module 'lambda_function': 
unexpected indent (lambda_function.py, line 30)

Ich habe hier studiert, aber es ist ein Krieg zwischen Tabulatoren und Leerzeichen (4). Tab vs Space War beim Schreiben des Programmcodes ist endgültig erledigt Es wird geschrieben, dass Python im Allgemeinen mit Leerzeichen geschrieben wird.

Die Datei, die ich lokal bearbeitet habe, ist in der Registerkarte enthalten In AWS bearbeiteter Code kann mit 4 Leerzeichen eingegeben werden. Ich wollte diesen Einrückungsfehler nicht sehen, also wechselte ich zur Raumschule.

Requests

Sie können urlopen so wie es ist verwenden, aber ich möchte Anfragen einführen.

Python Urllib2-Modul Anfragen: HTTP für Menschen Code, um dasselbe ohne Anfragen zu tun

Es wird einfacher sein, Nachrichten wie Slack zu senden.

Code jetzt.py


# coding: utf-8
from __future__ import print_function

import os
import json
import requests
from datetime import datetime
from urllib2 import urlopen

SITE = os.environ['site']
EXPECTED = os.environ['expected']

def validate(res):
    return EXPECTED in res

def lambda_handler(event, context):
    print('Checking {} at {}...'.format(SITE, event['time']))
    try:
        if not validate(urlopen(SITE).read()):
            raise Exception('Validation failed')
    except Exception as e:
        print('Check failed!')
        print(e)
    else:
        print('Check passed!')
    finally:
        print('Check complete at {}'.format(str(datetime.now())))
        return "Finish"

Unable to import module 'lambda_function': No module named requests

Da es sich bei Requests um ein externes Modul handelt, tritt dieser Fehler auf.

Verwendung externer Module

Ich hatte die Angewohnheit, nicht standardmäßige Python-Module wie Anfragen zu platzieren, also werde ich es schreiben.

lambda-uploader Dieser Bereich wird hilfreich sein.

AWS Lambda mithilfe von Lambda-Uploader remote entwickeln, ausführen und bereitstellen AWS Lambda Python mit Lambda-Uploader bereitstellen

ZIP lade deinen Code hoch

Ich habe es damit gemacht. Sie können es tun, sobald es ein einzelner Schuss ist. [AWS] Was tun, wenn Sie mit Lambda pipen möchten?

Es ist wie "pip install request -t." In Ihrem Arbeitsordner und komprimieren Sie es.

Wenn Sie erfolgreich hochladen können, beginnen Sie mit dem vorherigen "aktuellen Code .py".

Slack

import

api

Sie können eine beliebige Kombination verwenden, diesmal verwenden wir jedoch einen einfachen Anfrage-Webhook.

Klicken Sie hier, um die URL des Webhooks abzurufen. Verfahren zur Erfassung der Slack Webhook-URL

def send_slack(text):
    url = "Die URL, die genau richtig war"
    payload_dic = {
        "text":text,
        "icon_emoji":':grin:',
        "channel":'bot-test2',
    }

    r = requests.post(url, data=json.dumps(payload_dic))

Sie können Slack mit genau diesem senden!

# coding: utf-8
from __future__ import print_function

import os
import json
import requests
from datetime import datetime
from urllib2 import urlopen

SITE = os.environ['site']
EXPECTED = os.environ['expected']

def validate(res):
    return EXPECTED in res

def web_check():
    try:
        if not validate(urlopen(SITE).read()):
            raise Exception('Validation failed')
    except Exception as e:
        print('Check failed!')
        print(e)
    else:
        print('Check passed!')
    finally:
        print('Check complete at {}'.format(str(datetime.now())))

def lambda_handler(event, context):
    print('Checking {} at {}...'.format(SITE, event['time']))
    # web_check()
    send_slack("test")
    return "success!"

def send_slack(text):
    url = "Das ist meine URL"
    payload_dic = {
        "text":text,
        "icon_emoji":':grin:',
        "channel":'bot-test2',
    }

    r = requests.post(url, data=json.dumps(payload_dic))


Ich habe den Prozess auf "def web_check ():" verschoben.

def lambda_handler(event, context):
    print('Checking {} at {}...'.format(SITE, event['time']))
    # web_check()
    send_slack("test")
    return "success!"

mit diesem

スクリーンショット 2017-03-15 16.55.31.png Slack ist angekommen.

Okay。 Als nächstes werden wir die Daten aus DynamoDB abrufen.

DynamoDB

Gebührenstruktur

DynamoDB Free Tier als Teil von AWS Free Tier

Lager Schreibkapazität Schreibkapazität
25GB 25 25

Eine Kapazitätseinheit verarbeitet eine Anforderung pro Sekunde Schreibkapazität von 1 Einheit: Schreibt bis zu 1 KB Daten einmal pro Sekunde Lesekapazität von 1 Einheit: Bis zu 4 KB Daten können einmal pro Sekunde gelesen werden 2,5 Millionen Leseanfragen von DynamoDB-Streams sind kostenlos verfügbar.

Wenn Sie beim Erstellen einer Datenbank die Schreib- und Lesekapazität auf 1 setzen, wird dies vorerst kein Geld kosten, wenn es sich um einen freien Frame handelt. Diesmal kann es ungefähr einmal pro Minute sein, wählen Sie also die Mindesteinheit 1 (eine Ebene, auf die einmal pro Sekunde zugegriffen werden kann).

Versuchen Sie zu machen

Die Einstellungen sind vorerst so.

スクリーンショット 2017-03-15 17.10.25.png

Auf DynamoDB kann nur mit dem Schlüssel des Hash zugegriffen werden (Wörterbuchtyp, assoziatives Array usw. je nach Sprache). Diesmal Zugriff mit ID als Schlüssel.

スクリーンショット 2017-03-15 17.15.28.png


{
  "id": 1,
  "target": "Online Shopping",
  "url": "https://www.amazon.com/"
}

{
  "id": 2,
  "target": "Gmail",
  "url": "https://www.google.co.jp/"
}

Es wird als Tabelle verwendet, um das Ziel aus der URL zu ermitteln.

Nehmen Sie die vorherigen Daten aus dem Python-Code

#Fügen Sie zwei hinzu
import boto3
from boto3.dynamodb.conditions import Key, Attr

def get_urls():
    table    = dynamodb.Table('sites')
    response = table.scan()
    sites = response["Items"]
    return sites

Ich habe eine Funktion hinzugefügt und nach dem Zielsatz aus der URL gesucht, die mit get_urls () aus DynamoDB abgerufen wurde.

Aktuell.py


# coding: utf-8
from __future__ import print_function

import os
import json
import requests
from datetime import datetime
from urllib2 import urlopen
import boto3
from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb')

def validate(res, target):
    return target in res

def web_check(url, target):
    print("Serching ... " + target)
    try:
        if validate(urlopen(url).read(), target):
            print("Find!")
        else:
            print("Not Find!")
    except Exception as e:
        print('Error')
        print(e)

def get_urls():
    table    = dynamodb.Table('sites')
    response = table.scan()
    sites = response["Items"]
    return sites

def send_slack(text):
    url = "https://hooks.slack.com/services/"
    payload_dic = {
        "text":text,
        "icon_emoji":':grin:',
        "channel":'bot-test2',
    }
    r = requests.post(url, data=json.dumps(payload_dic))

def lambda_handler(event, context):
    print('Check start')

    sites = get_urls()
    for site in sites:
        web_check(str(site["url"]), str(site["target"]))
    
    return "success!"


Ausgabeergebnis


Check start
Serching ...Technischer Informationsaustausch unter https://qiita.com/
Find!
Serching ... Gmail at https://www.google.co.jp/
Find!
Serching ...Ist es Google Mail? bei https://www.google.co.jp/
Not Find!
Serching ... Online Shopping at https://www.amazon.com/
Error
HTTP Error 503: Service Unavailable
END RequestId: 3992d81e-095e-11e7-b30a-1ddc7da9e992

Ich habe auch hier einen Fehler bekommen. Python stolpert!


'utf8' codec can't decode byte 0x90 in position 102: invalid start byte

Python UnicodeEncodeError kennen Ich habe den Fehler behoben, indem ich mich hier bezog. Als type (site [" url "]) fertig war, war es <type'unicode '>, also Ich habe "str (site [" url "])" gemacht und es in "<type'str"> "geändert.

Schreiben Sie DynamoDB von Lambda

sites_check1 Tabelle hinzufügen

スクリーンショット 2017-03-15 18.19.12.png

hinzufügen

from datetime import datetime, timedelta

def insert(results):
    date = datetime.now() + timedelta(hours=9)

    id = 0
    table = dynamodb.Table('sites_check')
    table.put_item(
        Item={
            "id": id,
            "date": date.strftime("%Y/%m/%d %H:%M"),
            "result": results
       }
    )

Zeitdelta hinzugefügt, um die Zeit zu erhöhen oder zu verringern. Titel zur DynamoDB-Site-Tabelle hinzugefügt. Aktueller Code


# coding: utf-8
from __future__ import print_function

import os
import json
import requests
from datetime import datetime, timedelta
from urllib2 import urlopen
import boto3
from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb')

def validate(res, target):
    return target in res

def web_check(url, target):
    print("Serching ... " + target + " at " + url)
    try:
        if validate(urlopen(url).read(), target):
            return "Find!"
        else:
            return "Not Find!"
    except Exception as e:
        return str(e)

def get_urls():
    table    = dynamodb.Table('sites')
    response = table.scan()
    sites = response["Items"]
    return sites

def send_slack(text):
    url = "https://hooks.slack.com/"
    payload_dic = {
        "text":text,
        "icon_emoji":':grin:',
        "channel":'bot-test2',
    }
    r = requests.post(url, data=json.dumps(payload_dic))

def insert(results):
    date = datetime.now() + timedelta(hours=9)

    id = 0
    table = dynamodb.Table('sites_check')
    table.put_item(
        Item={
            "id": id,
            "date": date.strftime("%Y/%m/%d %H:%M"),
            "result": results
       }
    )

def lambda_handler(event, context):
    print('Check start')

    results = {}
    sites = get_urls()
    for site in sites:
        msg = web_check(str(site["url"]), str(site["target"]))
        results[str(site["title"])] = msg
    
    insert(results)
    return "success!"



Hier ist das Ergebnis des Einfügens der Daten.


{
  "date": "2017/03/15 18:37",
  "id": 0,
  "result": {
    "Amazon": "Find!", #Aus irgendeinem Grund wird es zu Suchen und es tritt kein Fehler auf
    "Google": "Find!",
    "Google-2": "Not Find!",
    "Qiita": "Find!"
  }
}

{
  "date": "2017/03/15 18:48",
  "id": 0,
  "result": {
    "Amazon": "HTTP Error 503: Service Unavailable", #Str, wenn hier ein Fehler auftritt(e)ich habe es gemacht
    "Google": "Find!",
    "Google-2": "Not Find!",
    "Qiita": "Find!"
  }
}

Wenn Sie nicht "str (e)" ausführen, tritt ein Fehler auf, da e kein str-Typ ist. Ich bin an Python gewöhnt, daher dauert es ungefähr 10 Minuten. Ich kann json nicht kommentieren.

def get_recent_codes():
    date = datetime.now() + timedelta(hours=9)
    now = date.strftime("%Y/%m/%d %H:%M")
    last = (date + timedelta(minutes=-9)).strftime("%Y/%m/%d %H:%M")

    #Abfrage mit ID 0 und Abrufen von Daten innerhalb von 10 Minuten
    response = table.query(
        KeyConditionExpression=Key('id').eq(0) & Key('date').between(last, now)
    )

    return response

Die Anzahl der abgerufenen Abfragen wird in "response ['Count']" eingegeben. Die in response ['Items'] abgerufenen Tabellendaten sind enthalten. Wenn Sie andere Daten benötigen, nehmen Sie diese bitte beim Drucken heraus.

Das Ergebnis sieht so aus

# coding: utf-8
from __future__ import print_function

import os
import json
import requests
from datetime import datetime, timedelta
from urllib2 import urlopen
import boto3
from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb')

def validate(res, target):
    return target in res

def web_check(url, target):
    print("Serching ... " + target + " at " + url)
    try:
        if validate(urlopen(url).read(), target):
            return "Find!"
        else:
            return "Not Find!"
    except Exception as e:
        return str(e)

def get_urls():
    table    = dynamodb.Table('sites')
    response = table.scan()
    sites = response["Items"]
    return sites

def send_slack(text):
    url = "https://hooks.slack.com/"
    payload_dic = {
        "text":text,
        "icon_emoji":':grin:',
        "channel":'bot-test2',
    }
    r = requests.post(url, data=json.dumps(payload_dic))

def insert(results):
    table = dynamodb.Table('sites_check')
    date = datetime.now() + timedelta(hours=9)
    id = 0
    table.put_item(
        Item={
            "id": id,
            "date": date.strftime("%Y/%m/%d %H:%M"),
            "result": results
       }
    )

def get_recent_codes():
    table = dynamodb.Table('sites_check')

    date = datetime.now() + timedelta(hours=9)
    now = date.strftime("%Y/%m/%d %H:%M")
    last = (date + timedelta(minutes=-9)).strftime("%Y/%m/%d %H:%M")
    print(last + "Von" + now + "Überprüfen Sie bis zu")

    response = table.query(
        KeyConditionExpression=Key('id').eq(0) & Key('date').between(last, now)
    )
    
    return response

def lambda_handler(event, context):
    print('Check start')

    results = {}
    sites = get_urls()
    for site in sites:
        msg = web_check(str(site["url"]), str(site["target"]))
        results[str(site["title"])] = msg
    
    insert(results)
    print(get_recent_codes())
    return "success!"



Es scheint, dass Sie es regelmäßig laufen lassen und verschiedene Dinge tun können.

schließlich

Ich bin ein Amateur von Python und Lambda, also habe ich viele Fehler gemacht. Ich denke jedoch, dass Architekten mit Python und Lambda sehr nützlich sein werden, daher würde ich sie gerne weiter verwenden.

Recommended Posts