appId | appKey | airport | year | month | day | hourOfDay |
Your appId | Your appKey | Svo | 2013 | 12 | 7 | ten |
{ } "appendix": { "airlines": {...} "airports": {...} "equipments": {...} "flightStatuses": {...} }
"airlines": [ { "fs": "SU", "iata": "SU", "icao": "AFL", "name": "Aeroflot", "active": true }, ...
"airports": [ { "fs": "BUD", "iata": "BUD", "icao": "LHBP", "name": "Liszt Ferenc International Airport", "city": "Budapest", "cityCode": "BUD", "countryCode": "HU", "countryName": "Hungary", "regionName": "Europe", "timeZoneRegionName": "Europe/Budapest", "localTime": "2013-12-06T20:51:56.974", "utcOffsetHours": 1, "latitude": 47.433037, "longitude": 19.261621, "elevationFeet": 495, "classification": 2, "active": true, "delayIndexUrl": "https://api.flightstats.com/flex/delayindex/rest/v1/json/airports/BUD?codeType=fs", "weatherUrl": "https://api.flightstats.com/flex/weather/rest/v1/json/all/BUD?codeType=fs" }, ...
"equipments": [ { "iata": "319", "name": "Airbus Industrie A319", "turboProp": false, "jet": true, "widebody": false, "regional": false }, ...
{ "flightId": 317846653, "carrierFsCode": "SU", "flightNumber": "2030", "departureAirportFsCode": "SVO", "arrivalAirportFsCode": "BUD", "departureDate": { "dateLocal": "2013-12-07T10:50:00.000", "dateUtc": "2013-12-07T06:50:00.000Z" }, "arrivalDate": { "dateLocal": "2013-12-07T10:35:00.000", "dateUtc": "2013-12-07T09:35:00.000Z" }, "status": "L", "schedule": { "flightType": "J", "serviceClasses": "RJY", "restrictions": "" }, "operationalTimes": { "publishedDeparture": { "dateLocal": "2013-12-07T10:50:00.000", "dateUtc": "2013-12-07T06:50:00.000Z" }, "publishedArrival": { "dateLocal": "2013-12-07T10:35:00.000", "dateUtc": "2013-12-07T09:35:00.000Z" }, "scheduledGateDeparture": { "dateLocal": "2013-12-07T10:50:00.000", "dateUtc": "2013-12-07T06:50:00.000Z" }, "estimatedGateDeparture": { "dateLocal": "2013-12-07T10:50:00.000", "dateUtc": "2013-12-07T06:50:00.000Z" }, "actualGateDeparture": { "dateLocal": "2013-12-07T11:27:00.000", "dateUtc": "2013-12-07T07:27:00.000Z" }, "scheduledGateArrival": { "dateLocal": "2013-12-07T10:35:00.000", "dateUtc": "2013-12-07T09:35:00.000Z" }, "estimatedGateArrival": { "dateLocal": "2013-12-07T11:12:00.000", "dateUtc": "2013-12-07T10:12:00.000Z" }, "actualGateArrival": { "dateLocal": "2013-12-07T10:43:00.000", "dateUtc": "2013-12-07T09:43:00.000Z" } }, "delays": { "departureGateDelayMinutes": 37, "arrivalGateDelayMinutes": 8 }, "flightDurations": { "scheduledBlockMinutes": 165, "blockMinutes": 136 }, "airportResources": { "departureTerminal": "D", "departureGate": "28", "arrivalTerminal": "2" }, "flightEquipment": { "scheduledEquipmentIataCode": "320", "actualEquipmentIataCode": "A320", "tailNumber": "VP-BWI" } }, ...
"status": "L", "schedule": { "flightType": "J", "serviceClasses": "RJY", "restrictions": "" },
Field | Description |
status | Current flight status A - Active C - Canceled D - Diverted - The destination was changed (for example, according to weather conditions) DN - Data source needed - Nowhere to get status information L - Landed NO - Not Operational R - Redirected S - Scheduled U - Unknown |
flightType | Flight type There are 23 of them in total. For example, J - Scheduled Passanger - Passenger Schedule M - Scheduled Cargo / Mail (MailOnly) - Freight, but only with letters. W - Military - Military |
serviceClasses | Service options provided on the flight according to IATA classification. Read more here - http://en.wikipedia.org/wiki/IATA_class_codes |
restrictions | Restrictions on the classification of IATA. Learn more - http://www.flyerguide.com/wiki/index.php/Traffic_Restriction_Codes ( ( AA) |
import urllib2 import simplejson appId = " appId " appKey = " appKey " # . flightstats, ICAO IATA requestedAirport = "SVO" # . arr - , dep - flightsType = "arr" # requestedDate = "2013/12/7" # , requestedHour = "15" # , requestedNumHours = "6"
# url = "https://api.flightstats.com/flex/flightstatus/rest/v2/json/" \ "airport/status/%s/%s/%s/%s?appId=%s&appKey=%s&utc=false&numHours=%s" # url = url %(requestedAirport, flightsType, requestedDate, requestedHour, appId, appKey, requestedNumHours) # JSON- req = urllib2.Request(url, None) opener = urllib2.build_opener() f = opener.open(req) response = simplejson.load(f)
# airports = response["appendix"]["airports"] # (dictionary) airportsDict = dict() # [ flightstats]:[] for airport in airports: airportsDict[airport["fs"]] = airport["name"] # ... equipments = response["appendix"]["equipments"] equipmentsDict = dict() for equipment in equipments: equipmentsDict[equipment["iata"]] = equipment["name"], equipment["iata"] #... airlines = response["appendix"]["airlines"] airlinesDict = dict() for airline in airlines: airlinesDict[airline["fs"]] = airline["name"]
Flight | Carrier | Equipment | Registration | From | Std | ATD | To | Sta | Std |
---|---|---|---|---|---|---|---|---|---|
XQ114 | SunExpress | Boeing 737-800 Passenger | D-ASXA | Antalya | 3:00 p.m. | --- | CGN | 17: 55: 00.000 | --- |
# webPage = "<html><body><table border=\"1\"> \ <tr><th>Flight</th><th>Carrier</th><th>Equipment</th><th>Registration</th><th>From</th><th>STD</th> \ <th>ATD</th><th>To</th><th>STA</th><th>ETA</th></tr>" # templateRow = "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td> \ <td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>" f = open("./list.html", "w")
carrierFsCode
, airport code, at zero depth. And in order to get time, the actual time of departure, you need to operationalTimes --> actualGateDeparture --> dateLocal"
down to the second depth: operationalTimes --> actualGateDeparture --> dateLocal"
. For this, you need the first auxiliary function. def getProperty(status, propertyNames): # try: # propertyNames for propertyName in propertyNames: # status = status[propertyName] # ! return status except # , return "---"
interestingCarriers = ["RU", # AirBridgeCargo "CU", # Cubana de Aviacion "ME", # China Eastern Airlines "KE", # Korean Air Lines ] interestingEquipments = ["SU9"] # Sukhoi Superjet 100 interestingTailNumbers = ["VP-BGB"] # Boeing 777-300ER
for flightStatus in flightStatuses: newRow = templateRow %(getProperty(flightStatus, ["carrierFsCode"]) + getProperty(flightStatus, ["flightNumber"]), airlinesDict[getProperty(flightStatus, ["carrierFsCode"])], getProperty(flightStatus, ["flightEquipment", "scheduledEquipmentIataCode"]), getProperty(flightStatus, ["flightEquipment", "tailNumber"]), str(airportsDict[getProperty(flightStatus, ["departureAirportFsCode"])]).replace("Airport", ""), str(getProperty(flightStatus, ["departureDate", "dateLocal"])).split("T")[-1], str(getProperty(flightStatus, ["operationalTimes", "actualGateDeparture", "dateLocal"])).split("T")[-1], str(airportsDict[getProperty(flightStatus, ["arrivalAirportFsCode"])]).replace("Airport", "") str(getProperty(flightStatus, ["arrivalDate", "dateLocal"])).split("T")[-1], str(getProperty(flightStatus, ["operationalTimes", "estimatedGateArrival", "dateLocal"])).split("T")[-1]) # if (getProperty(flightStatus, ["carrierFsCode"]) in interestingCarriers) or \ (getProperty(flightStatus, ["flightEquipment", "scheduledEquipmentIataCode"]) in interestingEquipments) or \ (getProperty(flightStatus, ["flightEquipment", "tailNumber"]) in interestingTailNumbers): newRow = newRow.replace("<tr>", "<tr bgcolor=\"#FF0000\">") # webPage += newRow
webPage = webPage + "</table></body></html>" f.write(webPage) f.close()
Flight | Carrier | Equipment | Registration | From | Std | ATD | To | Sta | ETA |
---|---|---|---|---|---|---|---|---|---|
SU155 | Aeroflot | 332 | VQ-BBE | Cancun international | 12: 30: 00.000 | 13: 17: 00.000 | Sheremetyevo International | 10: 30: 00.000 | 11: 03: 00.000 |
DL466 | Delta air lines | 76W | --- | John F. Kennedy International | 16: 15: 00.000 | 16: 14: 00.000 | Sheremetyevo International | 10:50 am | 10: 12: 00.000 |
SU111 | Aeroflot | 332 | VP-BLX | Miami international | 17: 35: 00.000 | 18: 35: 00.000 | Sheremetyevo International | 1:45 p.m. | 13: 46: 00.000 |
SU103 | Aeroflot | 333 | VP-BDE | John F. Kennedy International | 19: 05: 00.000 | --- | Sheremetyevo International | 13: 25: 00.000 | 13: 34: 00.000 |
UN576 | Transaero Airlines | 744 | EI-XLJ | Punta cana international | 19: 55: 00.000 | 21: 18: 00.000 | Sheremetyevo International | 14: 50: 00.000 | 15: 35: 00.000 |
RU566 | Airbridgecargo | 74Y | --- | Frankfurt am Main | 04: 45: 00.000 | --- | Sheremetyevo International | 11: 00: 00.000 | --- |
RU498 | Airbridgecargo | 74N | --- | Shanghai Pudong International | 05: 00: 00.000 | --- | Sheremetyevo International | 10:45: 00.000 | --- |
SU233 | Aeroflot | 332 | --- | Indira Gandhi International | 05: 05: 00.000 | 05: 26: 00.000 | Sheremetyevo International | 10: 10: 00.000 | 10: 13: 00.000 |
RU506 | Airbridgecargo | 74N | --- | Milano malpensa | 05: 30: 00.000 | --- | Sheremetyevo International | 12: 00: 00.000 | --- |
SU1827 | Aeroflot | 320 | VQ-BAZ | Simferopol | 06: 00: 00.000 | 06: 25: 00.000 | Sheremetyevo International | 10: 15: 00.000 | 10: 40: 00.000 |
SU2437 | Aeroflot | 320 | VP-BLH | Dusseldorf International | 06: 05: 00.000 | 06: 27: 00.000 | Sheremetyevo International | 12: 25: 00.000 | 12: 24: 00.000 |
RU440 | Airbridgecargo | 74N | VP-BIM | Hong Kong International | 06: 15: 00.000 | 06: 15: 00.000 | Sheremetyevo International | 12: 25: 00.000 | --- |
KE529 | Korean Air Lines | 74Y | HL7466 | Incheon International | 06: 25: 00.000 | 07: 07: 00.000 | Sheremetyevo International | 10: 40: 00.000 | --- |
JU650 | Jat airways | 733 | --- | Belgrad Nikola Tesla | 06: 45: 00.000 | 06: 45: 00.000 | Sheremetyevo International | 12: 35: 00.000 | 12: 39: 00.000 |
PS561 | UIA | 73N | UR-GAP | Kiev / Kyiv - Borispol | 07: 00: 00.000 | 07: 00: 00.000 | Sheremetyevo International | 10: 35: 00.000 | 10: 35: 00.000 |
SU1009 | Aeroflot | 321 | VQ-BED | Kaliningrad | 07: 10: 00.000 | 07: 36: 00.000 | Sheremetyevo International | 10: 00: 00.000 | 10: 26: 00.000 |
AF1644 | Air france | 319 | F-GRHL | Charles de Gaulle | 07: 15: 00.000 | 07: 13: 00.000 | Sheremetyevo International | 13: 55: 00.000 | 13: 52: 00.000 |
SU1867 | Aeroflot | 320 | VP-BQP | Zvartnots International | 08: 10: 00.000 | 08: 21: 00.000 | Sheremetyevo International | 11: 00: 00.000 | 11: 11: 00.000 |
5N502 | Nordavia Regional Airlines | 735 | --- | Syktyvkar | 08: 20: 00.000 | 08: 27: 00.000 | Sheremetyevo International | 10: 15: 00.000 | 10: 11: 00.000 |
KC893 | Air Astana | 320 | P4-KBC | Astana | 08: 40: 00.000 | 08: 36: 00.000 | Sheremetyevo International | 10: 20: 00.000 | 10: 49: 00.000 |
SU3 | Aeroflot | 321 | VP-BWO | Pulkovo | 08: 55: 00.000 | 09: 04: 00.000 | Sheremetyevo International | 10: 20: 00.000 | 10: 29: 00.000 |
SU1513 | Aeroflot | 319 | VP-BWA | Surgut | 09: 00: 00.000 | 08: 59: 00.000 | Sheremetyevo International | 10: 35: 00.000 | 10: 34: 00.000 |
SU1293 | Aeroflot | 320 | VQ-BIV | Kazan | 09: 00: 00.000 | 09: 27: 00.000 | Sheremetyevo International | 10: 30: 00.000 | 10:50 am |
SU1229 | Aeroflot | 320 | VP-BDK | Nizhniy Novgorod | 09: 05: 00.000 | 09: 21: 00.000 | Sheremetyevo International | 10: 25: 00.000 | 10: 41: 00.000 |
SU1309 | Aeroflot | 319 | VP-BDO | Samara | 09: 15: 00.000 | 09: 20: 00.000 | Sheremetyevo International | 10: 55: 00.000 | 11: 00: 00.000 |
AY153 | Finnair | 319 | OH-LVI | Helsinki-Vantaa | 09: 25: 00.000 | 09: 29: 00.000 | Sheremetyevo International | 13: 05: 00.000 | 12: 57: 00.000 |
OK892 | CSA | 319 | --- | Vaclav Havel Prague | 09: 30: 00.000 | 09: 31: 00.000 | Sheremetyevo International | 15: 10: 00.000 | 15: 05: 00.000 |
SU2005 | Aeroflot | 320 | VP-BWI | J. Paul II International Krakow-Balice | 09: 35: 00.000 | 09: 56: 00.000 | Sheremetyevo International | 14: 40: 00.000 | 14: 49: 00.000 |
SU1121 | Aeroflot | 320 | VP-BTI | Adler / Sochi | 09: 50: 00.000 | 09: 55: 00.000 | Sheremetyevo International | 12:20 pm | 12: 25: 00.000 |
SU2685 | Aeroflot | 320 | VQ-BCM | Schoenefeld | 09: 50: 00.000 | 10: 44: 00.000 | Sheremetyevo International | 15: 25: 00.000 | 16: 15: 00.000 |
SU5 | Aeroflot | 320 | VQ-BAX | Pulkovo | 09: 55: 00.000 | 10: 20: 00.000 | Sheremetyevo International | 11: 15: 00.000 | 11: 40: 00.000 |
SU1839 | Aeroflot | SU9 | RA-89010 | Kharkov | 09: 55: 00.000 | 10: 10: 00.000 | Sheremetyevo International | 13: 30: 00.000 | 13: 20: 00.000 |
SU2321 | Aeroflot | 320 | VQ-BHL | Franz Josef Strauss | 10: 00: 00.000 | 10: 16: 00.000 | Sheremetyevo International | 4:00 p.m. | 16: 16: 00.000 |
SU1001 | Aeroflot | 320 | VP-BLL | Kaliningrad | 10: 05: 00.000 | 10: 25: 00.000 | Sheremetyevo International | 12:55 pm | 13: 15: 00.000 |
R25807 | Orrenair | 738 | --- | Barnaul | 10: 10: 00.000 | 10: 15: 00.000 | Sheremetyevo International | 11: 30: 00.000 | 11: 35: 00.000 |
SU1307 | Aeroflot | 320 | VP-BKX | Tolmachevo | 10: 15: 00.000 | 10: 19: 00.000 | Sheremetyevo International | 11: 25: 00.000 | 11: 29: 00.000 |
SU1701 | Aeroflot | 333 | VQ-BNS | Vladivostok International | 10: 20: 00.000 | 10: 24: 00.000 | Sheremetyevo International | 12: 25: 00.000 | 12: 29: 00.000 |
SU1805 | Aeroflot | 321 | VP-BOE | Kiev / Kyiv - Borispol | 10: 20: 00.000 | 11: 00: 00.000 | Sheremetyevo International | 13: 50: 00.000 | 14: 30: 00.000 |
SU2137 | Aeroflot | 321 | VQ-BHK | Istanbul Ataturk | 10: 20: 00.000 | 11: 03: 00.000 | Sheremetyevo International | 15: 15: 00.000 | 15: 26: 00.000 |
SK734 | SAS | 320 | OY-KAP | Copenhagen | 10: 20: 00.000 | 10: 46: 00.000 | Sheremetyevo International | 15:45: 00.000 | 16: 02: 00.000 |
SU7 | Aeroflot | 320 | --- | Pulkovo | 10: 25: 00.000 | 10: 43: 00.000 | Sheremetyevo International | 11:45 am: 00.000 | 12: 03: 00.000 |
SU1813 | Aeroflot | 320 | VP-BRX | Donetsk | 10: 30: 00.000 | 10: 31: 00.000 | Sheremetyevo International | 14: 25: 00.000 | 14: 26: 00.000 |
SU1831 | Aeroflot | 320 | --- | Minsk International 2 | 10:50 am | 11: 40: 00.000 | Sheremetyevo International | 13: 15: 00.000 | 14: 05: 00.000 |
SU2107 | Aeroflot | 320 | VP-BZS | Tallinn | 10:50 am | 10: 54: 00.000 | Sheremetyevo International | 14: 30: 00.000 | 14: 18: 00.000 |
SU1479 | Aeroflot | 319 | VP-BDM | Abakan | 10: 55: 00.000 | 10: 55: 00.000 | Sheremetyevo International | 11:55 am | 11:55 am |
SU1483 | Aeroflot | 77W | VP-BGB | Krasnojarsk | 11: 00: 00.000 | 11: 13: 00.000 | Sheremetyevo International | 11: 35: 00.000 | 11: 48: 00.000 |
SU2683 | Aeroflot | 319 | VQ-BCO | Riga | 11: 00: 00.000 | 11: 24: 00.000 | Sheremetyevo International | 14: 35: 00.000 | 14: 44: 00.000 |
D95399 | Donavia | 319 | VP-BNN | Stavropol | 11: 15: 00.000 | 11: 17: 00.000 | Sheremetyevo International | 13: 30: 00.000 | 13: 32: 00.000 |
SU2035 | Aeroflot | SU9 | RA-89008 | Otopeni International | 11: 15: 00.000 | 11: 28: 00.000 | Sheremetyevo International | 15: 35: 00.000 | 15: 33: 00.000 |
SU11 | Aeroflot | 320 | --- | Pulkovo | 11: 30: 00.000 | 11: 49: 00.000 | Sheremetyevo International | 12:45 pm | 13: 04: 00.000 |
SU1139 | Aeroflot | 321 | VQ-BKU | Adler / Sochi | 11: 35: 00.000 | 11:55 am | Sheremetyevo International | 2:00 p.m. | 14: 20: 00.000 |
SU1211 | Aeroflot | 320 | VQ-BIT | Samara | 11: 40: 00.000 | 12: 13: 00.000 | Sheremetyevo International | 13: 25: 00.000 | 13: 42: 00.000 |
SU1759 | Aeroflot | SU9 | VP-BZQ | Volgograd | 11:45 am: 00.000 | 11: 53: 00.000 | Sheremetyevo International | 13: 35: 00.000 | 13: 43: 00.000 |
SU1255 | Aeroflot | 319 | VP-BDN | Begishevo | 11: 50: 00.000 | 12: 03: 00.000 | Sheremetyevo International | 13: 40: 00.000 | 13: 53: 00.000 |
SU1643 | Aeroflot | 320 | VQ-BIW | Astrakhan | 11: 50: 00.000 | 11:55 am | Sheremetyevo International | 14: 10: 00.000 | 14: 15: 00.000 |
SU1305 | Aeroflot | 320 | VP-BLP | Mineralnye vody | 11: 50: 00.000 | 12: 08: 00.000 | Sheremetyevo International | 14: 15: 00.000 | 14: 33: 00.000 |
SU1761 | Aeroflot | 738 | VP-BRH | Chita | 11:55 am | 12: 10: 00.000 | Sheremetyevo International | 12:45 pm | 1:00 p.m. |
SU1221 | Aeroflot | 320 | VP-BMF | Nizhniy Novgorod | 12: 05: 00.000 | 12: 12: 00.000 | Sheremetyevo International | 13: 10: 00.000 | 13: 17: 00.000 |
SU1743 | Aeroflot | 333 | VQ-BQX | Yuzhno-Sakhalinsk | 12: 10: 00.000 | 12:20 pm | Sheremetyevo International | 14: 05: 00.000 | 14: 15: 00.000 |
D95301 | Donavia | 734 | VQ-BCS | Rostov | 12: 15: 00.000 | 12: 28: 00.000 | Sheremetyevo International | 14: 15: 00.000 | 14: 28: 00.000 |
SU13 | Aeroflot | 319 | --- | Pulkovo | 12:20 pm | 12: 50: 00.000 | Sheremetyevo International | 13: 35: 00.000 | 14: 05: 00.000 |
5N117 | Nordavia Regional Airlines | 735 | --- | Arkhangelsk | 12:20 pm | 12: 25: 00.000 | Sheremetyevo International | 14: 05: 00.000 | 14: 10: 00.000 |
SU1191 | Aeroflot | 320 | VQ-BEA | Kazan | 12: 25: 00.000 | 13: 04: 00.000 | Sheremetyevo International | 13: 55: 00.000 | 14: 34: 00.000 |
SU1751 | Aeroflot | 738 | VP-BRF | Yakutsk | 12: 30: 00.000 | 12: 58: 00.000 | Sheremetyevo International | 13: 15: 00.000 | 13: 43: 00.000 |
SU1547 | Aeroflot | SU9 | --- | Anapa | 12: 30: 00.000 | 12: 50: 00.000 | Sheremetyevo International | 2:45 pm | 15: 05: 00.000 |
D95377 | Donavia | 319 | --- | Mineralnye vody | 12:45 pm | 13: 03: 00.000 | Sheremetyevo International | 15: 10: 00.000 | 15: 28: 00.000 |
D95363 | Donavia | 319 | VP-BQK | Rostov | 13: 05: 00.000 | 13: 20: 00.000 | Sheremetyevo International | 15: 05: 00.000 | 15: 20: 00.000 |
SU1411 | Aeroflot | 321 | VQ-BOI | Koltsovo International | 13: 15: 00.000 | 13: 43: 00.000 | Sheremetyevo International | 13: 40: 00.000 | 14: 08: 00.000 |
SU1731 | Aeroflot | 333 | VQ-BCQ | Petropavlovsk-Kamchatsky | 13: 30: 00.000 | 13: 44: 00.000 | Sheremetyevo International | 14: 30: 00.000 | 14: 44: 00.000 |
SU15 | Aeroflot | 320 | --- | Pulkovo | 13: 30: 00.000 | 13: 39: 00.000 | Sheremetyevo International | 2:45 pm | 14: 52: 00.000 |
SU1231 | Aeroflot | 320 | VP-BLR | Ufa | 13: 55: 00.000 | 14: 19: 00.000 | Sheremetyevo International | 2:00 p.m. | 14: 24: 00.000 |
SU1421 | Aeroflot | 320 | VP-BNL | Chelyabinsk | 13: 55: 00.000 | 13: 56: 00.000 | Sheremetyevo International | 14: 20: 00.000 | 14: 21: 00.000 |
R25803 | Orrenair | 738 | --- | Irkutsk | 14: 05: 00.000 | 14: 30: 00.000 | Sheremetyevo International | 14: 50: 00.000 | 15: 15: 00.000 |
SU1201 | Aeroflot | SU9 | --- | Perm | 14: 10: 00.000 | --- | Sheremetyevo International | 14: 25: 00.000 | 14: 25: 00.000 |
5N9134 | Nordavia Regional Airlines | --- | --- | Kazan | 14: 10: 00.000 | 15: 07: 00.000 | Sheremetyevo International | 15: 30: 00.000 | --- |
SU17 | Aeroflot | 320 | --- | Pulkovo | 14: 25: 00.000 | 14: 56: 00.000 | Sheremetyevo International | 15: 40: 00.000 | 16: 11: 00.000 |
Source: https://habr.com/ru/post/205210/
All Articles