Files
TPSchedule/mobile/lib/data/json_schedule_import.dart
T

60 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('课表文件格式无效');
}
}
}