//import 'package:html'; import 'dart:convert'; import 'dart:developer'; import 'package:flutter/foundation.dart'; import 'package:intl/intl.dart'; class ApiLido4d { //static const url = "https://tar.lido.aero"; static const url = kIsWeb ? "https://proxy.fares.cyou" : "https://tar.lido.aero"; //static const url = "https://proxy.fares.cyou"; static const realurl = "https://tar.lido.aero"; ApiLido4d({this.username = "", this.password = ""}); bool get logged => cookieMap.isNotEmpty; String username; String password; String get cookie => "${cookieMap.keys.fold("", (t, e) => (t == "") ? "$e=${cookieMap[e]}" : "$t; $e=${cookieMap[e]}")};SameSite=None; Secure"; Map cookieMap = {}; Map get headers => { "Accept": "application/vnd.lsy.lido.lcb.v1.hal+json", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en", "Connection": "keep-alive", "Content-Type": "application/json;charset=UTF-8", //"Host": Uri.parse(realurl).host, "Origin": Uri.parse(realurl).host, //"sec-ch-ua":'" Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"', // "sec-ch-ua-mobile": "?0", // "sec-ch-ua-platform": "Windows", // "Sec-Fetch-Dest": "empty", // "Sec-Fetch-Mode": "cors", // "Sec-Fetch-Site": "same-origin", "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36', "X-lido-applicationId": "lido-lcb", "X-lido-clientId": "lido-lcb-web", "X-lido-customerId": "TAR", "X-lido-operatingAirline": "", "X-lido-timeStamp": DateTime.now().toUtc().toIso8601String(), "X-lido-traceId": "0c497133-2a92-45a0-8ffe-a03c77852201", "cookie": "SERVERID=docker2; ${cookie}", "X-lido-csrf": cookieMap["lido_csrf"] ?? "", }; Future logout() async { var response = await post(Uri.parse('${url}USR/actionLogout.jsp'), body: {"Cookie": cookie}); } Future login() async { try { var response = await get( Uri.parse( '$url/lido/las/login.jsp?DESMON_RESULT_PAGE=$realurl/briefing//'), ); cookieMap.addAll(_getcookies(response.headers["set-cookie"] ?? response.headers["_set-cookie"] ?? "")); //print(response.headers); response = await post( Uri.parse('$url/lido/las/dwr/call/plaincall/LoginBean.login.dwr'), body: { "callCount": "1", "windowName": "DWR-5F9BFD0ECADDCF42109A9C1099F4B49B", "c0-scriptName": "LoginBean", "c0-methodName": "login", "c0-id": "0", "c0-param0": "boolean:false", "c0-param1": "boolean:false", "c0-param2": "string:$username", "c0-param3": "string:$password", "c0-param4": "string:", "c0-param5": "string:LIDO", "c0-param6": "string:en", "batchId": "1", "page": "/lido/las/login.jsp?DESMON_RESULT_PAGE=$realurl/briefing&DESMON_CODE=LAS_002&DESMON_LANG=en", "httpSessionId": "", "scriptSessionId": "C63C650BEED5A9D544876B2756E3ECF0" }, headers: {}); cookieMap.addAll(_getcookies(response.headers["set-cookie"] ?? "")); //log("$username $password ${response.statusCode} ${response.body}"); final message = RegExp(r'(?<=errorMessage2:")(.+)(?=",)') .firstMatch(response.body) ?.group(0) ?? RegExp(r'(?<=errorMessage1:")(.+)(?=",)') .firstMatch(response.body) ?.group(0); final changepass = RegExp(r'(?<=forcePasswdChange:)(.+)(?=,)') .firstMatch(response.body) ?.group(0) == "true"; cookieMap = (message != null) ? {} : cookieMap; log("api lido 4d login $username $password ${response.statusCode} logged:$logged msg:${message}"); return { 'error': logged ? null : message, 'data': {"logged": logged}, 'meta': { "changepass": changepass, "user": username, "pass": password, "cookie": cookieMap } }; } catch (e) { return { 'error': e.toString(), 'data': {"logged": false}, 'meta': {"user": username, "pass": password, "cookie": null} }; } } Future list( {String date = "", String dep = "", String des = "", String al = "", String fnum = ""}) async { try { final startdate = (date == "") ? DateTime.now() .subtract(const Duration(hours: 36)) .toUtc() .millisecondsSinceEpoch : DateTime.parse(date).millisecondsSinceEpoch; final endate = startdate + (1000 * 60 * 60 * 36); var response = await get( Uri.parse( "$url/lido/lcb/ui/flights?page=0&size=100&startDateTime=1653148128544&endDateTime=1653191328544") .replace(queryParameters: { "page": "0", "size": "1000", "startDateTime": startdate.toString(), "endDateTime": endate.toString(), ...(al != "" ? {"commAirLine": al} : {}), ...(fnum != "" ? {"flightNumber": fnum} : {}), ...(dep != "" ? {"departure": dep} : {}), ...(des != "" ? {"destination": des} : {}), }), headers: {"X-lido-businessId": "SearchFlights", ...headers}); //log(response.headers.toString()); Map decodedresponse; // print("${response.body}"); try { decodedresponse = json.decode(response.body) ?? {}; } catch (e) { decodedresponse = { "body": response.body, "response": response.statusCode }; } String? message = decodedresponse["errorsAndWarnings"]?["warnings"]?[0] ?["message"] ?? decodedresponse["errorsAndWarnings"]?["errors"]?[0]?["message"] ?? ((response.statusCode == 200) ? null : "ERR"); /* print(((decodedresponse["totalElements"] ?? 0) > 0 ? decodedresponse["content"].fold([], (t, e) { t.add(e["leg"]); return t; }) : [])); */ return { 'error': message, 'data': (message == null) ? decodedresponse["content"] : null, 'meta': { "legs": (decodedresponse["totalElements"] ?? 0) > 0 ? decodedresponse["content"].fold([], (t, e) { t.add(e["leg"]["legidentifier"]); return t; }) : [], "user": username, "pass": password, "nb": decodedresponse["totalElements"] ?? 0, "cookie": cookieMap } }; } catch (e) { return {'error': e.toString(), 'data': {}, 'meta': {}}; } } Future ofp( {String al = "", String fnum = "", String date = "", String origin = "", String dep = '', String des = ''}) async { try { final dateoforigin = DateTime.parse("${(origin == "") ? date : origin}T00:00:00Z") .millisecondsSinceEpoch; String brieflink = ""; String legid = ""; if (origin == "") { final res = await list( date: date != "" ? date : origin, al: al, fnum: fnum, dep: dep, des: des); if (res["error"] != null) { return res; } else if (res["data"]?[0]?["_links"]?["self"]?["href"] != null) { //(res["data"]?[0]?["_links"]?["self"]?["href"] ?? "").toString()); brieflink = res["data"]?[0]?["_links"]?["self"]?["href"]; legid = res["data"]?[0]?["leg"]?["legidentifier"]; } else { // no link found return { 'error': "Can't find the requested OFP.", 'data': res["data"], 'meta': {"user": username, "pass": password, "cookie": cookieMap} }; } } else { legid = '$al.$fnum.${DateFormat("ddLLLy").format(DateTime.fromMillisecondsSinceEpoch(dateoforigin))}.$dep.$des.'; brieflink = "$url/lido/lcb/ui/$legid/briefing"; } var response = await put(Uri.parse(brieflink), headers: { "X-lido-businessId": 'SearchBP', ...headers, }, //body: json.encode(({"commercialAirline": al,"flightNumber": fnum,"operationalSuffix": "","date": dateoforigin.toString() body: json.encode(({ "categories": [ "APLI", "APTDXML", "SOFP", "CDA", "RADAR", "OFPDLK", "ATSXML", "REGWXXML", "WXSIGWX", "SIGWXROUTE", "VAATCA", "ASPDXML", "NOTAMXML", "OTS", "SFC", "WINDDATA", "RAIMXML", "ARPTWXXML", "SOFPINFO", "IWFRXML", "OFPNLXML", "VERTPROF", "SOFPSUM", "RAIM", "UAD", "DISMAP", "WXSATWX" ], }))); //log(response.body); Map decodedresponse; try { decodedresponse = (json.decode(response.body) ?? {}); } catch (e) { decodedresponse = {}; } String? message = decodedresponse["errorsAndWarnings"]?["warnings"]?[0] ?["message"] ?? decodedresponse["errorsAndWarnings"]?["errors"]?[0]?["message"] ?? ((response.statusCode == 201) ? null : "ERR"); return { 'error': (message == null) ? null : message, 'data': decodedresponse, 'meta': { "user": username, "pass": password, "cookie": cookieMap, "legid": legid } }; } catch (e) { return {'error': e.toString(), 'data': {}, 'meta': {}}; } } Future ofppdf( {String al = "", String fnum = "", String date = "", String origin = "", String dep = '', String des = ''}) async { try { final dateoforigin = DateTime.parse("${(origin == "") ? date : origin}T00:00:00Z") .millisecondsSinceEpoch; String legid = ""; if (origin == "") { final res = await list( date: date != "" ? date : origin, al: al, fnum: fnum, dep: dep, des: des); if (res["error"] != null) { log("lido4d: ofps listed, ${res["error"]}"); return res; } else if (res["data"]?[0]?["_links"]?["self"]?["href"] != null) { legid = res["data"]?[0]?["leg"]?["legidentifier"]; } else { log("lido4d: no link found"); // no link found return { 'error': "Can't find the requested OFP.", 'data': res["data"], 'meta': {"user": username, "pass": password, "cookie": cookieMap} }; } } else { legid = '$al.$fnum.${DateFormat("ddLLLy").format(DateTime.fromMillisecondsSinceEpoch(dateoforigin))}.$dep.$des.'; } var response = await put( Uri.parse("$url/lido/lcb/ui/briefing/multi/print?force=true"), headers: { "Accept": "application/vnd.lsy.lido.lcb.v1.hal+json,application/pdf", //"Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en", "Connection": "keep-alive", "Content-Type": "application/json;charset=UTF-8", "Cookie": cookie, //"host": Uri.parse(realurl).host, "Origin": Uri.parse(realurl).host, // "sec-ch-ua":'" Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"', "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36", "X-lido-applicationId": "lido-lcb", "X-lido-businessId": "printBP", "X-lido-clientId": "lido-lcb-web", "X-lido-csrf": cookieMap["lido_csrf"], "X-lido-customerId": "TAR", "X-lido-operatingAirline": "TU", "X-lido-timeStamp": "2022-05-25T06:29:56.659Z", "X-lido-traceId": "3cbab7e0-56ca-49ec-b158-8899c0d3bbbb", }, body: json.encode({ "legIdentifiers": [legid], "categories": [ "OFP", "ATS", "CREWINFO", "DISP", "IWFR", "NOTAM", "UAD", "WXSIGWX", "VERTPROF", "RAIM", "DMS", "WXNOTAM", "ABD", "SIGWXROUTE", //"WXSATWX" ], "merge": false, "quickprint": false, "weatherDataRequired": false, })); Map decodedresponse; try { //decodedresponse = (json.decode(response.body) ?? {}); decodedresponse = {}; } catch (e) { decodedresponse = {}; } String? message = decodedresponse["errorsAndWarnings"]?["warnings"]?[0] ?["message"] ?? decodedresponse["errorsAndWarnings"]?["errors"]?[0]?["message"] ?? ((response.statusCode == 201) ? null : "ERR"); //log("xx ${response.headers}"); //final id ="${DateFormat("yyyyMMdd").format(DateTime.fromMillisecondsSinceEpoch(dateoforigin))}_${dep}_${des}_$al$fnum"; final id = Lido4dService.filename( al: al, fnum: fnum, dep: dep, des: des, origin: origin, date: date); var filepdf = await Io.getFile(response, filename: "$id.pdf", folder: "ofps"); return { 'error': (message == null) ? null : message, 'data': (message == null) ? {"file": filepdf["location"], "bytes": filepdf["bytes"], "id": id} : null, 'meta': {"user": username, "pass": password, "cookie": cookieMap} }; } catch (e) { return {'error': e.toString(), 'data': {}, 'meta': {}}; } } Map _getcookies(String cookiesData, {List vars = const [ "lido_auth", "lido_csrf", "JSESSIONID", "SERVERID" ]}) { Map cookies = {}; for (var title in vars) { if (cookiesData.contains(title)) { List at = (RegExp(r'(' + title + ')(.*?)[^;]+').stringMatch(cookiesData) ?? "") .split('='); cookies[title] = at[1]; } } return cookies; } }