creating first structure of cinema backend server

Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
2025-11-16 00:01:14 +01:00
parent 92da4423b2
commit a5d9372806
15 changed files with 362 additions and 58 deletions

View File

@@ -0,0 +1,16 @@
enum PosterOrientation {
horizontal,
vertical,
}
enum PosterFormat {
png,
jpeg,
bmp,
}
enum PosterOutput {
image,
lvgl,
lvglBinary,
}

View File

@@ -0,0 +1,30 @@
import 'package:cinema/feature/poster/models/poster.enums.dart';
import 'package:zard/zard.dart';
final _orientations = PosterOrientation.values.map((e) => e.name);
final _formats = PosterFormat.values.map((e) => e.name);
final _outputs = PosterOutput.values.map((e) => e.name);
final posterSchema = z.map({
'width': z.int().min(1, message: "'width' must be at least 1").max(4000, message: "'width' must be at most 4000"),
'height': z.int().min(1, message: "'height' must be at least 1").max(4000, message: "'height' must be a most 4000"),
'count': z.int().min(1, message: "'count' must be at least 1").max(20, message: "'count' must be at most 20"),
'orientation': z.string().refine(
(value) => _orientations.contains(value),
message: "'orientation' must be either ${_orientations.join(', ')}",
),
'shuffle': z.bool(message: "'shuffle' must be a boolean value"),
'language': z.string(message: "'language' must be a string").transform((value) => value.trim()),
'backgroundColor': z.string().regex(
RegExp(r'^#([a-fA-F0-9]{3}|[a-fA-F0-9]{6})$'),
message: "The 'backgroundColor' must be a valid hexadecimal color code (e.g., #000 or #FF0000)",
),
'format': z.string().refine(
(value) => _formats.contains(value),
message: "'format' must be either ${_formats.join(', ')}",
),
'output': z.string().refine(
(value) => _outputs.contains(value),
message: "'output' must be either ${_outputs.join(', ')}",
),
});

View File

@@ -0,0 +1,37 @@
import 'dart:convert';
import 'package:cinema/feature/poster/models/poster_request.schema.dart';
import 'package:injectable/injectable.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf_router/shelf_router.dart';
part 'poster.service.g.dart';
@injectable
class PosterService {
@Route.get('/')
Future<Response> listPosters(Request request) async {
return Response.ok('deprecated poster endpoint. use POST /poster instead');
}
@Route.post('/')
Future<Response> createPoster(Request request) async {
final payload = await request.readAsString();
final body = jsonDecode(payload);
final params = posterSchema.safeParse(body);
if (!params.success) {
return Response(
400,
body: jsonEncode({
'error': 'Invalid request',
'details': params.error?.messages,
}),
headers: {'Content-Type': 'application/json'},
);
}
return Response.ok(jsonEncode(params.data), headers: {'Content-Type': 'application/json'});
}
// Create router using the generate function defined in 'poster.g.dart'.
Router get router => _$PosterServiceRouter(this);
}

View File

@@ -0,0 +1,14 @@
import 'package:injectable/injectable.dart';
@injectable
class Version {
const Version();
String get appVersion => const String.fromEnvironment('APP_VERSION');
void printVersion() {
if (appVersion.isNotEmpty) {
print('App Version: $appVersion');
}
}
}

View File

@@ -0,0 +1,28 @@
import 'package:injectable/injectable.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf_web_socket/shelf_web_socket.dart';
@LazySingleton()
class WebSocketService {
final List<dynamic> _clients = [];
Handler get handler => webSocketHandler((webSocket, _) {
_clients.add(webSocket);
print('Client connected, total: ${_clients.length}');
webSocket.stream.listen(
(message) {
webSocket.sink.add('echo $message');
},
onDone: () {
_clients.remove(webSocket);
print('Client disconnected, total: ${_clients.length}');
},
onError: (error) {
_clients.remove(webSocket);
print('Client error: $error');
},
cancelOnError: true,
);
});
}

View File

@@ -0,0 +1,9 @@
import 'package:get_it/get_it.dart';
import 'package:injectable/injectable.dart';
import 'injectable.config.dart';
final getIt = GetIt.instance;
@InjectableInit()
void configureDependencies() => getIt.init();