Implement Webuntis HTTP Api and Display

This commit is contained in:
2023-02-15 20:33:05 +01:00
parent 7432972b3c
commit 2b6dc8e3e6
42 changed files with 746 additions and 287 deletions

View File

@ -1,19 +0,0 @@
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
class AccountModel extends ChangeNotifier {
bool _isLoggedIn = false;
bool get isLoggedIn => _isLoggedIn;
void logout() {
_isLoggedIn = false;
notifyListeners();
}
void login() {
_isLoggedIn = true;
notifyListeners();
}
}

11
lib/data/dataHolder.dart Normal file
View File

@ -0,0 +1,11 @@
import 'package:flutter/cupertino.dart';
import 'package:localstore/localstore.dart';
abstract class DataHolder extends ChangeNotifier {
CollectionRef storage(String path) {
return Localstore.instance.collection(path);
}
Future<void> run();
}

View File

@ -1,44 +0,0 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/cupertino.dart';
import 'package:marianum_mobile/data/socketConnection.dart';
class IncomingPacket extends ChangeNotifier {
String packetId;
bool useJsonDecode;
bool _isReceived = false;
bool get isReceived => _isReceived;
IncomingPacket(this.packetId, {this.useJsonDecode = true}) {
SocketConnection.read.listen((event) {
if(event.startsWith("$packetId:")) {
_isReceived = true;
// THIS listener handles the incomming request
log("$packetId is handled!");
String content = event.split("$packetId:")[1];
handle(useJsonDecode ? jsonDecode(content) : content);
}
notifyListeners();
});
}
void invoke({Object? data, bool indicateLoading = false, bool allowNotifyListeners = true}) {
data = data ?? {};
log("$packetId is invoked with data: $data");
SocketConnection.write.add("$packetId:${jsonEncode(data)}");
if(indicateLoading) {
_isReceived = false;
if(allowNotifyListeners) notifyListeners();
}
}
void handle(dynamic data) {
log("Warning: $packetId packet listener is registered, but no handle is defined!");
}
}

View File

@ -1,19 +0,0 @@
import 'dart:developer';
import 'package:marianum_mobile/data/incomingPacket.dart';
import 'package:shared_preferences/shared_preferences.dart';
class AuthenticatePacket extends IncomingPacket {
AuthenticatePacket() : super("authenticate");
@override
void handle(data) {
SharedPreferences.getInstance().then((value) => {
invoke(data: {
'username': value.getString("username"),
'password': value.getString("password")
})
});
}
}

View File

@ -1,21 +0,0 @@
import 'package:marianum_mobile/data/incomingPacket.dart';
class ErrorPacket extends IncomingPacket {
ErrorPacket() : super("error", useJsonDecode: false);
bool _errorDismissed = true;
bool get errorDismissed => _errorDismissed;
set errorDismissed(bool value) {
_errorDismissed = value;
notifyListeners();
}
String _errorText = "";
String get errorText => _errorText;
@override
void handle(data) {
_errorDismissed = false;
_errorText = data;
}
}

View File

@ -1,29 +0,0 @@
import 'package:marianum_mobile/data/incomingPacket.dart';
class FileEntry {
String name;
bool isFolder;
String path;
FileEntry(this.name, this.isFolder, this.path);
}
class FileListPacket extends IncomingPacket {
FileListPacket() : super("fileList");
List<FileEntry> _entries = List<FileEntry>.empty(growable: true);
List<FileEntry> get entries => _entries;
String _lastPath = "/";
String get lastPath => _lastPath;
@override
void handle(data) {
_entries = List<FileEntry>.empty(growable: true);
_lastPath = data['backLink'];
data['files'].forEach((value) => {
_entries.add(FileEntry(value['name'], value['is_folder'], value['path']))
});
}
}

View File

@ -1,28 +0,0 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:marianum_mobile/data/socketConnection.dart';
import '../incomingPacket.dart';
class ServerInfoPacket extends IncomingPacket {
ServerInfoPacket() : super('serverInfo');
String _serverName = "Unbekannt";
String _serverOwner = "Unbekannt";
String _serverVersion = "?";
String _legal = "Keine";
String get serverName => _serverName;
String get serverOwner => _serverOwner;
String get serverVersion => _serverVersion;
String get legal => _legal;
@override
void handle(data) {
_serverName = data['name'];
_serverOwner = data['owner'];
_serverVersion = data['version'];
_legal = data['legal'];
}
}

View File

@ -1,26 +0,0 @@
import 'package:marianum_mobile/data/incomingPacket.dart';
class TalkMessage {
bool self;
String sender;
String content;
String date;
TalkMessage(this.self, this.sender, this.content, this.date);
}
class TalkChatPacket extends IncomingPacket {
TalkChatPacket() : super("talkChat");
List<TalkMessage> _messages = List<TalkMessage>.empty(growable: true);
List<TalkMessage> get messages => _messages;
@override
void handle(data) {
_messages = List<TalkMessage>.empty(growable: true);
print(data);
data.forEach((message) => {
_messages.add(TalkMessage(true, message['actorId'], message['message'], message['timestamp']))
});
}
}

View File

@ -1,46 +0,0 @@
import 'dart:convert';
import 'package:intl/intl.dart';
import 'package:jiffy/jiffy.dart';
import 'package:marianum_mobile/data/incomingPacket.dart';
class TalkContact {
String name;
String lastMessage;
String lastTime;
String profilePicture;
bool unreadMessages;
bool isGroup;
String userToken;
TalkContact(this.name, this.lastMessage, this.lastTime, this.profilePicture, this.unreadMessages, this.isGroup, this.userToken);
}
class TalkContactsPaket extends IncomingPacket {
TalkContactsPaket() : super('talkContacts');
List<TalkContact> _contacts = List<TalkContact>.empty(growable: true);
List<TalkContact> get contacts => _contacts;
@override
void handle(data) {
_contacts = List<TalkContact>.empty(growable: true);
//data["ocs"]["data"].sort((a, b) => a['lastActivity'].compareTo(b['lastActivity']));
data.forEach((value) async {
await Jiffy.locale("de");
_contacts.add(
TalkContact(
value['displayName'],
value['lastMessage']['message'],
Jiffy(DateTime.fromMillisecondsSinceEpoch(value['lastActivity'] * 1000)).fromNow(),
value['name'] != null ? "https://cloud.marianum-fulda.de/avatar/${value['name']}/128" : "",
value['unreadMessages'] > 0,
value['type'] != 1,
value['token']
)
);
});
}
}

View File

@ -1,13 +0,0 @@
import 'package:marianum_mobile/data/incomingPacket.dart';
class TalkNotificationsPacket extends IncomingPacket {
TalkNotificationsPacket() : super("talkNotifications");
int _amount = 0;
int get amount => _amount;
@override
void handle(data) {
_amount = data['amount'];
}
}

View File

@ -1,71 +0,0 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:marianum_mobile/data/socketConnection.dart';
import '../incomingPacket.dart';
class TimetablePacket extends IncomingPacket {
TimetablePacket() : super('timetable');
TimeTableData _timeTable = TimeTableData();
TimeTableData get timeTable => _timeTable;
@override
void handle(data) {
_timeTable = TimeTableData();
data.forEach((day) {
TimeTableDay dayData = TimeTableDay(List<TimeTableEntry>.empty(growable: true), day['title']);
day['tiles'].forEach((tile) {
dayData._entries.add(TimeTableEntry(
tile['title'], tile['title'], tile['room'], tile['title'],
TimeTableEntryTime(tile['begin']['hour'], tile['begin']['minute']),
TimeTableEntryTime(tile['end']['hour'], tile['end']['minute'])
));
});
_timeTable._days.add(dayData);
});
}
}
class TimeTableData {
List<TimeTableDay> _days = [];
List<TimeTableDay> get days => _days;
set days(List<TimeTableDay> value) {
_days = value;
}
}
class TimeTableDay {
List<TimeTableEntry> _entries;
String _name;
TimeTableDay(this._entries, this._name);
List<TimeTableEntry> get entries => _entries;
String get name => _name;
}
class TimeTableEntry {
late String subject;
late String teacher;
late String room;
late String classes;
late TimeTableEntryTime start;
late TimeTableEntryTime end;
TimeTableEntry(this.subject, this.teacher, this.room, this.classes,
this.start, this.end);
}
class TimeTableEntryTime {
int hour;
int minute;
TimeTableEntryTime(this.hour, this.minute);
}

View File

@ -1,14 +0,0 @@
import 'dart:convert';
import 'package:marianum_mobile/data/socketConnection.dart';
class OutgoingPacket {
final String command;
final dynamic data;
OutgoingPacket({required this.command, required this.data});
void send() {
SocketConnection.write.add("$command:${jsonEncode(data)}");
}
}

View File

@ -1,8 +0,0 @@
import 'package:marianum_mobile/data/outgoingPacket.dart';
class TalkContactsAskPacket extends OutgoingPacket {
TalkContactsAskPacket() : super(
command: "talkContacts",
data: {},
);
}

View File

@ -1,10 +0,0 @@
import 'package:web_socket_channel/web_socket_channel.dart';
class SocketConnection {
static final _connection = WebSocketChannel.connect(
Uri.parse('ws://localhost:1234'),
);
static var read = _connection.stream.asBroadcastStream();
static var write = _connection.sink;
}

View File

@ -0,0 +1,12 @@
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class PersistantTimetable {
final int id;
final String json;
PersistantTimetable(this.id, this.json);
}

View File

@ -0,0 +1,60 @@
import 'dart:collection';
import 'dart:convert';
import 'dart:developer';
import 'package:intl/intl.dart';
import 'package:marianum_mobile/api/webuntis/queries/authenticate/authenticate.dart';
import 'package:marianum_mobile/api/webuntis/queries/authenticate/authenticateResponse.dart';
import 'package:marianum_mobile/api/webuntis/queries/getRooms/getRoomsCache.dart';
import 'package:marianum_mobile/api/webuntis/queries/getRooms/getRoomsResponse.dart';
import 'package:marianum_mobile/api/webuntis/queries/getSubjects/getSubjectsCache.dart';
import 'package:marianum_mobile/api/webuntis/queries/getSubjects/getSubjectsResponse.dart';
import 'package:marianum_mobile/data/dataHolder.dart';
import '../../api/webuntis/queries/getTimetable/getTimetable.dart';
import '../../api/webuntis/queries/getTimetable/getTimetableCache.dart';
import '../../api/webuntis/queries/getTimetable/getTimetableParams.dart';
import '../../api/webuntis/queries/getTimetable/getTimetableResponse.dart';
class Timetable extends DataHolder {
int day = int.parse(DateFormat("yyyyMMdd").format(DateTime.now()));
Timetable() : super();
GetTimetableResponse? _getTimetableResponse;
GetTimetableResponse? get getTimetableResponse => _getTimetableResponse;
GetRoomsResponse? _getRoomsResponse;
GetRoomsResponse? get getRoomsResponse => _getRoomsResponse;
GetSubjectsResponse? _getSubjectsResponse;
GetSubjectsResponse? get getSubjectsResponse => _getSubjectsResponse;
@override
Future<void> run() async {
GetTimetableCache(
day: day,
onUpdate: (data) =>
{
_getTimetableResponse = data,
notifyListeners(),
}
);
GetRoomsCache(
onUpdate: (data) =>
{
_getRoomsResponse = data,
notifyListeners(),
}
);
GetSubjectsCache(
onUpdate: (data) =>
{
_getSubjectsResponse = data,
notifyListeners(),
}
);
}
}