283 lines
8.0 KiB
Dart
283 lines
8.0 KiB
Dart
|
|
import 'dart:convert';
|
|
|
|
import 'package:bus_infotainment/auth/api_constants.dart';
|
|
import 'package:bus_infotainment/backend/live_information.dart';
|
|
import 'package:bus_infotainment/tfl_datasets.dart';
|
|
import 'package:bus_infotainment/utils/audio%20wrapper.dart';
|
|
import 'package:bus_infotainment/utils/delegates.dart';
|
|
import 'package:appwrite/appwrite.dart' as appwrite;
|
|
import 'package:appwrite/models.dart' as models;
|
|
import 'package:uuid/uuid.dart';
|
|
|
|
import '../../auth/auth_api.dart';
|
|
import 'info_module.dart';
|
|
|
|
class CommandModule extends InfoModule {
|
|
|
|
final String sessionID;
|
|
late final String clientID;
|
|
|
|
List<CommandInfo> _commandHistory = [];
|
|
get commandHistory => _commandHistory;
|
|
EventDelegate<CommandInfo> onCommandReceived = EventDelegate();
|
|
|
|
CommandModule(this.sessionID){
|
|
// generate a random client ID
|
|
var uuid = Uuid();
|
|
|
|
clientID = uuid.v4();
|
|
|
|
if (liveInformation.auth.isAuthenticated()){
|
|
print("Auth is authenticated");
|
|
_setupListener();
|
|
} else {
|
|
print("Auth is not authenticated");
|
|
liveInformation.auth.onLogin.addListener((value) {
|
|
_setupListener();
|
|
});
|
|
}
|
|
}
|
|
|
|
// Will execute the command an event which is triggered when a response is received
|
|
Future<EventDelegate> executeCommand(String command) async {
|
|
EventDelegate<String> delegate = EventDelegate();
|
|
|
|
final client = liveInformation.auth.client;
|
|
|
|
final databases = appwrite.Databases(client);
|
|
|
|
if (true) {
|
|
try {
|
|
final response = await databases.listDocuments(
|
|
databaseId: "6633e85400036415ab0f",
|
|
collectionId: "6633e85d0020f52f3771",
|
|
queries: [
|
|
appwrite.Query.search("SessionID", liveInformation.roomCode!)
|
|
]
|
|
);
|
|
|
|
List<String> pastCommands = [];
|
|
|
|
response.documents.first.data["Commands"].forEach((element) {
|
|
pastCommands.add(element);
|
|
});
|
|
|
|
pastCommands.add(command);
|
|
|
|
final document = await databases.updateDocument(
|
|
databaseId: "6633e85400036415ab0f",
|
|
collectionId: "6633e85d0020f52f3771",
|
|
documentId: liveInformation.roomDocumentID!,
|
|
data: {
|
|
"Commands": pastCommands,
|
|
"LastUpdater": clientID,
|
|
}
|
|
);
|
|
} catch (e) {
|
|
print("Failed to send command");
|
|
|
|
}
|
|
}
|
|
|
|
_onCommandReceived(CommandInfo(command, clientID));
|
|
|
|
return delegate;
|
|
}
|
|
|
|
Future<void> _onCommandReceived(CommandInfo commandInfo) async {
|
|
|
|
commandHistory.add(commandInfo);
|
|
onCommandReceived.trigger(commandInfo);
|
|
|
|
print("Received command: ${commandInfo.command}");
|
|
|
|
List<String> commandParts = splitCommand(commandInfo.command);
|
|
String command = commandParts[0];
|
|
List<String> args = commandParts.sublist(1);
|
|
|
|
if (command == "Response:") {
|
|
|
|
}
|
|
else if (command == "initroom") {
|
|
// initroom <roomCode>
|
|
|
|
}
|
|
else if (command == "announce") {
|
|
|
|
final displayText = args[1];
|
|
|
|
if (args[0] == "manual") {
|
|
// announce manual <DisplayText> <AudioFileName>... <ScheduledTime>
|
|
|
|
|
|
List<String> audioFileNames = args.sublist(2);
|
|
try {
|
|
if (int.parse(audioFileNames.last) != null) {
|
|
audioFileNames.removeLast();
|
|
}
|
|
} catch (e) {}
|
|
|
|
DateTime scheduledTime = LiveInformation().syncedTimeModule.Now().add(Duration(seconds: 1));
|
|
try {
|
|
if (int.parse(args.last) != null) {
|
|
scheduledTime = DateTime.fromMillisecondsSinceEpoch(int.parse(args.last));
|
|
}
|
|
} catch (e) {}
|
|
|
|
liveInformation.announcementModule.queueAnnounceByAudioName(
|
|
displayText: displayText,
|
|
audioNames: audioFileNames,
|
|
scheduledTime: scheduledTime,
|
|
sendToServer: false
|
|
);
|
|
|
|
}
|
|
else if (args[0] == "info") {
|
|
|
|
int InfoIndex = int.parse(args[1]);
|
|
|
|
DateTime scheduledTime = LiveInformation().syncedTimeModule.Now();
|
|
try {
|
|
if (int.parse(args.last) != null) {
|
|
scheduledTime = DateTime.fromMillisecondsSinceEpoch(int.parse(args.last));
|
|
}
|
|
} catch (e) {}
|
|
|
|
liveInformation.announcementModule.queueAnnouncementByInfoIndex(
|
|
infoIndex: InfoIndex,
|
|
scheduledTime: scheduledTime,
|
|
sendToServer: false
|
|
);
|
|
}
|
|
else if (args[0].startsWith("dest")) {
|
|
// announce destination <RouteNumber> <RouteVariantIndex> <ScheduledTime>
|
|
|
|
print("Checkpoint 1");
|
|
|
|
String routeNumber = args[1];
|
|
int routeVariantIndex = int.parse(args[2]);
|
|
|
|
DateTime scheduledTime = LiveInformation().syncedTimeModule.Now();
|
|
try {
|
|
if (int.parse(args.last) != null) {
|
|
scheduledTime = DateTime.fromMillisecondsSinceEpoch(int.parse(args.last));
|
|
}
|
|
} catch (e) {}
|
|
|
|
print("Checkpoint 2");
|
|
BusRoute route = LiveInformation().busSequences.routes[routeNumber]!;
|
|
BusRouteVariant routeVariant = route.routeVariants.values.toList()[routeVariantIndex];
|
|
|
|
print("Checkpoint 3");
|
|
liveInformation.announcementModule.queueAnnouncementByRouteVariant(
|
|
routeVariant: routeVariant,
|
|
scheduledTime: scheduledTime,
|
|
sendToServer: false
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
else if (command == "setroute") {
|
|
// setroute <RouteNumber> <RouteVariantIndex>
|
|
|
|
LiveInformation liveInformation = LiveInformation();
|
|
|
|
String routeNumber = args[0];
|
|
int routeVariantIndex = int.parse(args[1]);
|
|
|
|
BusRoute route = liveInformation.busSequences.routes[routeNumber]!;
|
|
BusRouteVariant routeVariant = route.routeVariants.values.toList()[routeVariantIndex];
|
|
|
|
liveInformation.setRouteVariant(
|
|
routeVariant
|
|
);
|
|
|
|
|
|
// Update the server
|
|
if (liveInformation.isHost) {
|
|
print("Updating server");
|
|
final client = liveInformation.auth.client;
|
|
final databases = appwrite.Databases(client);
|
|
|
|
final response = await databases.listDocuments(
|
|
databaseId: "6633e85400036415ab0f",
|
|
collectionId: "6633e85d0020f52f3771",
|
|
queries: [
|
|
appwrite.Query.search("SessionID", liveInformation.roomCode!)
|
|
]
|
|
);
|
|
|
|
final document = await databases.updateDocument(
|
|
databaseId: "6633e85400036415ab0f",
|
|
collectionId: "6633e85d0020f52f3771",
|
|
documentId: response.documents.first.$id,
|
|
data: {
|
|
"CurrentRoute": routeNumber,
|
|
"CurrentRouteVariant": routeVariantIndex,
|
|
}
|
|
);
|
|
try {
|
|
|
|
print("Updated server");
|
|
} catch (e) {
|
|
print("Failed to update server");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
appwrite.RealtimeSubscription? _subscription;
|
|
Future<void> _setupListener() async {
|
|
if (_subscription != null) {
|
|
return;
|
|
}
|
|
|
|
// final realtime = appwrite.Realtime(LiveInformation().auth.client);
|
|
//
|
|
// _subscription = realtime.subscribe(
|
|
// ['databases.${ApiConstants.INFO_Q_DATABASE_ID}.collections.${ApiConstants.COMMANDS_COLLECTION_ID}.documents']
|
|
// );
|
|
// _subscription!.stream.listen((event) {
|
|
// print(jsonEncode(event.payload));
|
|
//
|
|
// // Only do something if the document was created or updated
|
|
// if (!(event.events.first.contains("create") || event.events.first.contains("update"))) {
|
|
// return;
|
|
// }
|
|
//
|
|
// final commandInfo = CommandInfo(event.payload['command'], event.payload['client_id']);
|
|
//
|
|
// if (commandInfo.clientID != clientID) {
|
|
// _onCommandReceived(commandInfo);
|
|
// }
|
|
//
|
|
// });
|
|
|
|
print("Listening for commands");
|
|
|
|
await Future.delayed(Duration(seconds: 90));
|
|
|
|
await _subscription!.close();
|
|
_subscription = null;
|
|
_setupListener();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
class CommandInfo {
|
|
final String command;
|
|
final String clientID;
|
|
|
|
CommandInfo(this.command, this.clientID);
|
|
}
|
|
|
|
List<String> splitCommand(String command) {
|
|
var regex = RegExp(r'([^\s"]+)|"([^"]*)"');
|
|
var matches = regex.allMatches(command);
|
|
return matches.map((match) => match.group(0)!.replaceAll('"', '')).toList();
|
|
} |