Posts Tagged ‘JSON’

Samstag, 14. Oktober 2017

upc cablecoms Verfügbarkeitsabfrage ist äusserst geschwätzig

upc cablecom bietet auf ihrer Web-Site die Möglichkeit, eine Wohnadresse auf die Verfügbarkeit von upc-Produkten zu überprüfen:

Verfügbarkeit prüfen

Füllt man die erforderlichen Angaben in das Formular ein, erhält man eine rein binäre Antwort für jede der drei Produktkategorien Internet, TV und Festnetz:

image-7498

Im Hintergrund setzt dafür JavaScript eine Abfrage auf eine upc API ab. Die URL lautet für das vorliegende Beispiel:

https://www.upc.ch/aff-upc-cablecom-ch/aav/availability.json?streetName=Schl%C3%B6sslistrasse&streetNumber=39&postalCode=3008&_charset_=UTF-8&lang=de

Als Antwort erhält man eine Datei namens availability.json zurück. Nachfolgend das Beispiel für meine Wohnadresse:

{
    "addressResultState": "uniqueAddress",
    "addresses": [
        {
            "buildingNumber": 39,
            "buildingNumberAnnex": null,
            "buildingStatusId": 3,
            "buildingStatusName": "completed",
            "communeName": "Bern",
            "coordinateX": "599190",
            "coordinateY": "199475",
            "countryCodeA2": "CH",
            "idBuilding": 131767,
            "locationName1": "Bern",
            "locationName2": "Bern",
            "networkOperatorId": 0,
            "postCode": "3008",
            "postCodeAnnex": "00",
            "postOfficeName": "Bern",
            "stateName": "Bern/Berne",
            "stateShort": "BE",
            "streetName1": "Schl\u00f6sslistrasse"
        }
    ],
    "availability": {
        "accessProvider": null,
        "accessTechnology": null,
        "cablecomRegion": "Nord-West",
        "catv": {
            "available": true,
            "houseUpgradeNeeded": false,
            "packages": {
                "_package": [
                    "not available"
                ]
            },
            "partnerNetFlag": false
        },
        "dp": {
            "available": true,
            "availableFrom": {
                "day": 5,
                "fractionalSecond": 0.0,
                "hour": 0,
                "minute": 0,
                "month": 9,
                "second": 0,
                "timezone": 120,
                "year": 2000
            },
            "houseUpgradeNeeded": false,
            "packages": {
                "_package": [
                    "RVO_VSB01",
                    "RVO_VSB02",
                    "RVO_VSB03",
                    "RVO_VSB04",
                    "RVO_VSB05",
                    "RVO_FRC1",
                    "RVO_GBL1",
                    "RVO_FCG1",
                    "RVO_FRC2",
                    "RVO_GBL2",
                    "RVO_FCG2",
                    "RVO_FCE1",
                    "RVO_FCE2",
                    "RVO_FPW1",
                    "RVO_FPW2",
                    "RVO_FPS1",
                    "RVO_FPS2",
                    "RVO_FPP1",
                    "RVO_FPP2",
                    "RVO_BP1",
                    "RVO_BDS13",
                    "RVO_BDS14",
                    "RVO_BDS08",
                    "RVO_BDS11",
                    "RVO_BDS09",
                    "RVO_BDS12"
                ]
            },
            "partnerNetFlag": false
        },
        "dtv": {
            "available": true,
            "availableFrom": {
                "day": 1,
                "fractionalSecond": 0.0,
                "hour": 0,
                "minute": 0,
                "month": 1,
                "second": 0,
                "timezone": 60,
                "year": 1999
            },
            "houseUpgradeNeeded": false,
            "packages": {
                "_package": [
                    "",
                    "NR_SVD01",
                    "RDC_SFRSD",
                    "RDC_SFRS_M",
                    "RDI_CH01",
                    "RDI_CH04",
                    "RDI_CH05",
                    "RDI_CH06",
                    "RDI_CH07",
                    "RDI_CH08",
                    "RDI_CH09",
                    "RDI_CH09",
                    "RDI_CH10",
                    "RDI_CH11",
                    "RDI_CH17",
                    "RDI_CH17H",
                    "RDI_CH18",
                    "RDI_CH18H",
                    "RDI_CH19",
                    "RDI_CH19H",
                    "RDI_CH20",
                    "RDI_CH20H",
                    "RDI_CH21",
                    "RDI_CH21",
                    "RDI_CH21_M",
                    "RDI_CH21_M",
                    "RDI_CH22",
                    "RDI_CH22_M",
                    "RDI_CH24",
                    "RDI_CH24_M",
                    "RDI_CH25",
                    "RDI_CH25_M",
                    "RDI_CH26",
                    "RDI_CH26_M",
                    "RDI_CH27",
                    "RDI_CH27_M",
                    "RDI_CH28",
                    "RDI_CH28_M",
                    "RDI_CH30",
                    "RDI_CH31",
                    "RDI_CH32",
                    "RDI_CH33",
                    "RDI_CH40",
                    "RDI_CH40_M",
                    "RDI_CH41",
                    "RDI_CH41",
                    "RDI_CH42",
                    "RDI_CH44",
                    "RDI_CH47",
                    "RDI_CH47",
                    "RDI_CH48",
                    "RDI_CH49",
                    "RDI_CH50",
                    "RDI_CH51",
                    "RDI_CH52",
                    "RDI_CH53",
                    "RDI_CH54",
                    "RDI_CH55",
                    "RDI_CH56",
                    "RDI_CH57",
                    "RDI_CH59",
                    "RDI_CH60",
                    "RDI_CH61",
                    "RDI_CH62",
                    "RDI_CH65",
                    "RDI_CH66",
                    "RDI_CH67",
                    "RDI_CH68",
                    "RDI_CH72",
                    "RDI_CH73",
                    "RDI_CH74",
                    "RDI_CH81",
                    "RDI_CH93",
                    "RDI_CH97_M",
                    "RDI_D4A_97",
                    "RDI_DUMW",
                    "RDI_DWISR1",
                    "RDI_DWISS1",
                    "RDI_DWR1",
                    "RDI_DWS1",
                    "RDI_HCOD",
                    "RDI_HRZ06",
                    "RDI_HRZ11",
                    "RDI_HRZ17",
                    "RDI_HRZ17",
                    "RDI_CH81",
                    "RDI_HRZ17H",
                    "RDI_HRZ81",
                    "RDI_HRZ18",
                    "RDI_HRZ18H",
                    "RDI_HRZ19",
                    "RDI_HRZ19H",
                    "RDI_HRZ20",
                    "RDI_HRZ20H",
                    "RDI_HRZ21",
                    "RDI_HRZ21",
                    "RDI_HRZ22",
                    "RDI_HRZ24",
                    "RDI_HRZ25",
                    "RDI_HRZ26",
                    "RDI_HRZ27",
                    "RDI_HRZ28",
                    "RDI_HRZ40",
                    "RDI_HRZ52",
                    "RDI_HRZ53",
                    "RDI_HRZ83",
                    "RDI_HRZCL",
                    "RDI_HRZCO",
                    "RDI_HRZDS",
                    "RDI_HRZ_97",
                    "RDI_PREM1",
                    "RDI_PREM2",
                    "RDI_PREM_M",
                    "RDI_PRM",
                    "RDI_PRMM",
                    "RDI_SPTV",
                    "RDI_SPTV_M",
                    "RDI_SVD_51",
                    "RDI_SVD_51",
                    "RDI_SVD_51",
                    "RDI_SVD_52",
                    "RDI_SVD_52",
                    "RDI_SVD_52",
                    "RDI_SVD_59",
                    "RDI_SVD_60",
                    "RHZ_CLAS7",
                    "RHZ_CLAS8",
                    "RHZ_PREM1",
                    "RHZ_PREM2",
                    "RHZ_PRM",
                    "RHZ_SFRSH",
                    "RHZ_SPTV",
                    "RDI_CTDV",
                    "RDI_DUMS",
                    "RDI_DUMM"
                ]
            },
            "partnerNetFlag": false
        },
        "dtvActicationCode": "203",
        "dtvDistributionModel": "Vertriebsmodell Cablecom",
        "dtvSetupId": "01810000",
        "ftthBuildingStatus": null,
        "ftthSla": null,
        "hs": {
            "available": true,
            "availableFrom": {
                "day": 5,
                "fractionalSecond": 0.0,
                "hour": 0,
                "minute": 0,
                "month": 9,
                "second": 0,
                "timezone": 120,
                "year": 2000
            },
            "houseUpgradeNeeded": false,
            "packages": {
                "_package": [
                    "DHS_BSO",
                    "RHS_BDS06",
                    "RHS_BDS07",
                    "RHS_BDS08",
                    "RHS_BDS09",
                    "RHS_BDS10",
                    "RHS_BDS11",
                    "RHS_BDS12",
                    "RHS_BDS13",
                    "RHS_BDS14",
                    "RHS_BDS15",
                    "RHS_BDS16",
                    "RHS_BDS17",
                    "RHS_BDS18",
                    "RHS_BDS20",
                    "RHS_BDS21",
                    "RHS_HC256",
                    "RHS_HS02",
                    "RHS_HS05",
                    "RHS_HS06",
                    "RHS_HS08",
                    "RHS_HS09",
                    "RHS_HS11",
                    "RHS_HS12",
                    "RHS_HS13",
                    "RHS_HS14",
                    "RHS_HS15",
                    "RHS_HS16",
                    "RHS_HS17",
                    "RHS_HSED13",
                    "RHS_HSED21",
                    "RHS_HSED30",
                    "RHS_HSED32",
                    "RHS_NDH25",
                    "RHS_HSED10",
                    "RHS_HSED11",
                    "RHS_HSED12",
                    "RHS_HSED14",
                    "RHS_HSED15",
                    "RHS_HSED16",
                    "RHS_HSED17",
                    "RHS_HSED18",
                    "RHS_HSED19",
                    "RHS_HSED20",
                    "RHS_HSED22",
                    "RHS_HSED23",
                    "RHS_HSED24",
                    "RHS_HSED25",
                    "RHS_HSED26",
                    "RHS_HSED28",
                    "RHS_HSED29",
                    "RHS_WOO"
                ]
            },
            "partnerNetFlag": false
        },
        "idBuilding": 131767,
        "languageRegion": "DE",
        "longText": "An Ihrem Standort ist bereits alles vorbereitet. Melden Sie sich jetzt online an und schon in wenigen Tagen k\u00f6nnen Sie vom gew\u00fcnschten Produkt profitieren.",
        "mobile": {
            "available": true,
            "houseUpgradeNeeded": false,
            "packages": {
                "_package": [
                    "ALL"
                ]
            },
            "partnerNetFlag": false
        },
        "vod": {
            "available": true,
            "houseUpgradeNeeded": false,
            "packages": {
                "_package": [
                    "BM_VODKIT"
                ]
            },
            "partnerNetFlag": false
        }
    },
    "availabilityResultState": "availabilityFound"
}

(Lesbar gemacht mit Google Chrome unter die Haube schauen (und JSON lesbar ausgeben))

Einige Erkenntnisse:

  • Diese API rechnet Strassenanschriften ins Schweizer Koordinatensystem um (600:200, irgendjemand?).
  • Das JSON sagt auch, wann das Gebäude an das cablecom-Netz angeschlossen wurde (Internet am 5. September 2000, Fernsehen am 1. Januar 1999 (wahrscheinlich ein Dummy-Wert, oder aber cablecom hat zu dem Stichtag das Berner Kabelnetz übernommen?)).
  • Benötigt mein Gebäude ein Upgrade? Aus meiner Sicht ein möglicher Hinweis auf Probleme in der Hausverkabelung und somit auf mögliche Geschwindigkeitseinbussen.
  • Es gibt drei Produktekategorien: dtv steht für Digital TV, hs steht für Highspeed (Internet) und dp wohl für Digital Phone.
  • Für jede Produktkategorie wird fein säuberlich aufgelistet, welche Packages verfügbar sind. Leider ist es mir nicht möglich, die Abkürzungen dieser Packages zu entziffern. Bei Digital TV vermute ich, dass einzelne Sender aufgelistet werden. Bei Highspeed Internet könnten es die effektiv verfügbaren Geschwindigkeiten sein.
  • Im JSON sind auch der Activation Code und die Setup ID aufgeführt, die man auf der Horizon-Box oder dem TV-Gerät für die Kanalsuche eingeben muss.
  • Schlussendlich sieht man auch, ob ein Gebäude an das (upc?) Glasfasernetz angeschlossen ist.

Tags: , , , , , ,
Labels: IT, Schweiz, Shopping

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 10. Juli 2014

Mit Python URLs dekodieren und JSON schön ausgeben

Ausgehend von dieser haarsträubenden URL der Credit Suisse …

https://www.credit-suisse.com/who_we_are/de/office_locator.jsp#%7B%22fs%22%3A%7B%22cid%22%3Anull%2C%22prid%22%3Anull%2C%22plid%22%3Anull%2C%22sid%22%3Anull%2C%22d%22%3A%5B0%2C0%2C0%2C0%2C0%2C0%2C0%2C0%2C0%2C0%5D%7D%2C%22ms%22%3A%7B%22c%22%3A%7B%22lat%22%3A46.94739121310314%2C%22lng%22%3A7.44410902261734%7D%2C%22z%22%3A18%7D%2C%22mk%22%3A%7B%22id%22%3A4451%7D%2C%22is%22%3A%7B%22id%22%3A%22mapPanel%22%2C%22ps%22%3A%7B%22id%22%3A4451%2C%22sid%22%3A11613%2C%22segid%22%3Anull%2C%22d%22%3A%5B0%2C0%2C0%2C0%2C0%2C0%2C0%2C0%2C0%2C0%5D%7D%7D%7D

… nachfolgend zwei Python Code-Snippets, mit welchen ihr die URL menschenlesbar machen könnt:

URLs dekodieren

urlClean = urllib.unquote(urlRaw).decode('utf8')

JSON schön ausgeben

json.dumps(json.loads(strJson), sort_keys=True, indent=4, separators=(',', ': '))

Tags: , , ,
Labels: Programmierung

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 10. Juli 2014

Öffnungszeiten Credit Suisse Bern-Bundesplatz

Da das Standortverzeichnis meiner Hausbank seit Jahr und Tag ein Usability-Nightmare ist, lege ich hier den Link ab, der mich direkt zu den Öffnungszeiten der Credit Suisse Bern-Bundesplatz führt:

Credit Suisse AG, Bern, Bundesplatz 2, Schweiz – Privatkunden

Falls ein Webmaster der Grossbank bei diesem Artikel vorbeischauen sollte, hier einige Anregungen:

  • Bitte das Standortverzeichnis mit — aus eurer Sicht — exotischen Browsern wie Apple Safari testen.
  • Bei diesen Tests solltet ihr am Besten auf den Google Maps fokussieren: Habe ich mich mit Safari auf Bern reingezoomt und klicke Bern–Bundesplatz an, springt die Karte wieder auf die Weltansicht und das Zoomen kann von vorne beginnen …
  • Die Verzögerung von 1-2 Sekunden nach der Auswahl eines Drop-Down-Elements ist Web 0.1, nicht Web 2.0 (ich glaube ich muss einen unfocus-Event generieren)
  • Wieso muss ich mich überhaupt wie ein Idiot durch vier Drop-Downs durchhangeln? Ist das State of the Art-Usability von 2014?
  • Wieso gibt es kein Suchfeld mit Autovervollständigung, in welches ich bspw. „Bundesplatz“ eingeben kann?
  • Wieso wird die URL nicht aktualisiert und wird eindeutig, wenn ich mich durch die Drop-Downs durchgekämpft habe und eine Filiale ausgewählt habe? Eine URL, welche ich als Lesezeichen ablegen kann und welche mich beim nächsten Aufruf direkt zu dem gewünschten Standort bringt?

Stattdessen übermittelt ihr in der URL solches URL-encodiertes JSON-Gefrickel:

https://www.credit-suisse.com/who_we_are/de/office_locator.jsp#%7B%22fs%22%3A%7B%22cid%22%3Anull%2C%22prid%22%3Anull%2C%22plid%22%3Anull%2C%22sid%22%3Anull%2C%22d%22%3A%5B0%2C0%2C0%2C0%2C0%2C0%2C0%2C0%2C0%2C0%5D%7D%2C%22ms%22%3A%7B%22c%22%3A%7B%22lat%22%3A46.94739121310314%2C%22lng%22%3A7.44410902261734%7D%2C%22z%22%3A18%7D%2C%22mk%22%3A%7B%22id%22%3A4451%7D%2C%22is%22%3A%7B%22id%22%3A%22mapPanel%22%2C%22ps%22%3A%7B%22id%22%3A4451%2C%22sid%22%3A11613%2C%22segid%22%3Anull%2C%22d%22%3A%5B0%2C0%2C0%2C0%2C0%2C0%2C0%2C0%2C0%2C0%5D%7D%7D%7D

… was auf Gut Deutsch lautet:

{
    "fs": {
        "cid": null,
        "d": [
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
        ],
        "plid": null,
        "prid": null,
        "sid": null
    },
    "is": {
        "id": "mapPanel",
        "ps": {
            "d": [
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0
            ],
            "id": 4451,
            "segid": null,
            "sid": 11613
        }
    },
    "mk": {
        "id": 4451
    },
    "ms": {
        "c": {
            "lat": 46.94739121310314,
            "lng": 7.44410902261734
        },
        "z": 18
    }
}

Bravo, ihr habt gerade JSON-over-URL JoU erfunden!

Tags: , , , , , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 18. Dezember 2013

Den Netatmo PHP API-Client mit weniger strikten SSL-Anforderungen patchen

Vor einigen Tagen hörte mein Raspberry Pi-Dashboard auf, die Werte meiner Netatmo NWS01 Wetterstation für Apple iPhone und Android anzuzeigen.

Auf meinem lokalen Mac funktionierte das Dashboard hingegen problemlos; d.h. ich konnte mittels dem Netatmo PHP API-Client die JSON-Datei mit den aktuellen Messwerten wie Temperatur, Luftdruck und -feuchtigkeit abrufen.

Die genaue Ursache hinter dem Problem kenne ich bis heute nicht, doch ich vermute mit dem jetzigen Wissensstand, dass die Cyon-Ingenieure an der Konfiguration ihrer Server herumgewerkelt haben und dabei unter anderem das Root-Zertifikat entfernt haben, welches der Netatmo API-Client zur HTTPS-verschlüsselten Kommunikation mit den Netatmo-Servern verwendet.

Nachdem ich nämlich die Exception mittels vardump() genauer betrachtete, welche NACurlErrorType zurücklieferte, war der Fall schnell sonnenklar:

...
[message:protected] => SSL peer certificate or SSH remote key was not OK
...

Nun … gut! Was macht man da? Ich habe die Datei NAApiClient.php gepatcht, indem ich cURL mit der auf false gesetzten Option CURLOPT_SSL_VERIFYHOST sage, unverifizierte SSL-Zertifikate kommentarlos zu akzeptieren:

...
        else 
        {
            $opts[CURLOPT_HTTPHEADER] = array('Expect:');
        }
        
        $opts[CURLOPT_SSL_VERIFYHOST] = false;
        
        curl_setopt_array($ch, $opts);
...

Bei einer API wie Netatmo ist diese manuell herbeigeführte Schwachstelle zu verantworten. Ginge es um Mailverkehr oder Online-Banking, würde ich eine solche Option definitiv nicht aktivieren.

Tags: , , , , , , , ,
Labels: Programmierung

Keine Kommentare | neuen Kommentar verfassen

Freitag, 30. August 2013

Google Chrome unter die Haube schauen (und JSON lesbar ausgeben)

Hierzu haben die Google-Entwickler folgende URI erdacht:

chrome://net-internals/

Über diese Benutzeroberfläche lassen sich Daten auch im JSON-Format exportieren. Damit diese JSON-Daten auch für Menschen (einigermassen) lesbar werden, nimmt man Python zu Hilfe. Im nachfolgenden Beispiel gehen wir davon aus, dass der JSON-Dump in der Datei dump.json abgelegt ist:

python -mjson.tool < dump.json > dump-pretty.json

Tags: , , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen