58 lines
1.7 KiB
Dart
58 lines
1.7 KiB
Dart
import '../domain/course.dart';
|
|
|
|
import 'dart:convert';
|
|
|
|
class ImportDraft {
|
|
const ImportDraft({
|
|
required this.courses,
|
|
required this.explicitlyEmpty,
|
|
required this.source,
|
|
required this.parserVersion,
|
|
});
|
|
final List<Course> courses;
|
|
final bool explicitlyEmpty;
|
|
final CourseSource source;
|
|
final String parserVersion;
|
|
}
|
|
|
|
class JsonScheduleImport {
|
|
static ImportDraft parse(String text) {
|
|
try {
|
|
if (utf8.encode(text).length > 2 * 1024 * 1024)
|
|
throw const FormatException('文件不能超过 2 MB');
|
|
final json = jsonDecode(text);
|
|
if (json is! Map ||
|
|
json['schemaVersion'] != 1 ||
|
|
json['courses'] is! List ||
|
|
(json['isDemo'] != null && json['isDemo'] is! bool) ||
|
|
(json['explicitlyEmpty'] != null &&
|
|
json['explicitlyEmpty'] is! bool)) {
|
|
throw const FormatException('请选择版本 1 的课表 JSON 文件');
|
|
}
|
|
final source = json['isDemo'] == true
|
|
? CourseSource.demo
|
|
: CourseSource.file;
|
|
final courses = (json['courses'] as List)
|
|
.map(
|
|
(c) => Course.fromJson(
|
|
Map<String, dynamic>.from(c as Map),
|
|
source: source,
|
|
),
|
|
)
|
|
.toList();
|
|
if (courses.map((c) => c.id).toSet().length != courses.length)
|
|
throw const FormatException('课程标识重复');
|
|
return ImportDraft(
|
|
courses: List.unmodifiable(courses),
|
|
explicitlyEmpty: json['explicitlyEmpty'] == true,
|
|
source: source,
|
|
parserVersion: 'json-v1',
|
|
);
|
|
} on FormatException {
|
|
rethrow;
|
|
} catch (_) {
|
|
throw const FormatException('课表文件格式无效');
|
|
}
|
|
}
|
|
}
|