import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:http/http.dart' as http; import '../../model/endpoint_data.dart'; import '../apiParams.dart'; import '../apiRequest.dart'; import '../apiResponse.dart'; import '../errors/network_exception.dart'; import '../errors/parse_exception.dart'; import 'queries/authenticate/authenticate.dart'; import 'webuntisError.dart'; abstract class WebuntisApi extends ApiRequest { Uri endpoint = Uri.parse('https://${EndpointData().webuntis().full()}/WebUntis/jsonrpc.do?school=marianum-fulda'); String method; ApiParams? genericParam; http.Response? response; bool authenticatedResponse; WebuntisApi(this.method, this.genericParam, {this.authenticatedResponse = true}); Future query(WebuntisApi untis, {bool retry = false}) async { var query = '{"id":"ID","method":"$method","params":${untis._body()},"jsonrpc":"2.0"}'; var sessionId = '0'; if(authenticatedResponse) { sessionId = (await Authenticate.getSession()).sessionId; } var data = await post(query, {'Cookie': 'JSESSIONID=$sessionId'}); response = data; final dynamic jsonData; try { jsonData = jsonDecode(data.body); } on FormatException catch (e) { throw ParseException(technicalDetails: 'WebUntis JSON decode: ${e.message}'); } if(jsonData['error'] != null) { if(jsonData['error']['code'] == -8520) { if(retry) throw WebuntisError('Authentication was tried (probably session timeout), but was not successful!', -8520); await Authenticate.createSession(); return await this.query(untis, retry: true); } else { throw WebuntisError(jsonData['error']['message'], jsonData['error']['code']); } } return data.body; } dynamic finalize(dynamic response) { response.rawResponse = this.response!; return response; } Future run(); String _body() => genericParam == null ? '{}' : jsonEncode(genericParam); Future post(String data, Map? headers) async { try { return await http.post(endpoint, body: data, headers: headers).timeout( const Duration(seconds: 10), onTimeout: () => throw NetworkException.timeout(technicalDetails: 'WebUntis $method timed out after 10s'), ); } on SocketException catch (e) { throw NetworkException(technicalDetails: 'WebUntis $method: ${e.message}'); } on http.ClientException catch (e) { throw NetworkException(technicalDetails: 'WebUntis $method: ${e.message}'); } } }