Skip to content

Feature: Cache scores list. #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 47 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
ea3d7cb
lazy loading for score page
Pairman Jun 11, 2024
0c1f0a3
Create build_for_android.yml
Pairman Jun 11, 2024
c979b48
Update build_for_android.yml
Pairman Jun 11, 2024
8da591e
Merge pull request #1 from Pairman/test
Pairman Jun 11, 2024
85319b8
Update build_for_android.yml
Pairman Jun 11, 2024
db3dcef
reimplement lazy loading
Pairman Jun 11, 2024
a314c79
load previous scores if already loaded
Pairman Jun 11, 2024
407a72a
fix data types
Pairman Jun 11, 2024
c20d4e5
fix var names
Pairman Jun 11, 2024
65273a4
Merge pull request #2 from Pairman/patch-1
Pairman Jun 11, 2024
92119a1
make ScoreWindowState public
Pairman Jun 11, 2024
58b903b
use public ScoreWindowState
Pairman Jun 11, 2024
d4d4f11
Merge pull request #3 from Pairman/patch-1
Pairman Jun 11, 2024
5305579
Update build_for_android.yml
Pairman Jun 11, 2024
d172a40
use cache
Pairman Jun 11, 2024
cdeb552
Update build_for_android.yml
Pairman Jun 11, 2024
0b5378a
cache android sdk
Pairman Jun 11, 2024
a21a532
Update build_for_android.yml
Pairman Jun 11, 2024
15fc1b3
Update build_for_android.yml
Pairman Jun 11, 2024
9118904
Update build_for_android.yml
Pairman Jun 11, 2024
e9a3b2e
Update build_for_android.yml
Pairman Jun 11, 2024
f8c3e15
add score serialization
Pairman Jun 11, 2024
ef3b513
Update score.dart
Pairman Jun 11, 2024
023c028
Update score.dart
Pairman Jun 11, 2024
0874f9c
Update score_card.dart
Pairman Jun 11, 2024
0d9e12f
Merge pull request #4 from Pairman/patch-1
Pairman Jun 11, 2024
19cd063
Create build_runner_build.yml
Pairman Jun 11, 2024
67df56e
Update build_runner_build.yml
Pairman Jun 11, 2024
bb66b89
Add files via upload
Pairman Jun 11, 2024
a3ad66e
Update score.dart
Pairman Jun 12, 2024
e1acc7b
Update build_for_android.yml
Pairman Jun 12, 2024
1b3a950
Merge pull request #5 from Pairman/patch-1
Pairman Jun 12, 2024
fcdea61
Update score.dart
Pairman Jun 12, 2024
5bc5e5e
Update score.dart
Pairman Jun 12, 2024
aaada24
Update score.dart
Pairman Jun 12, 2024
b3d36f4
Update score.dart
Pairman Jun 12, 2024
e23013a
Update score.dart
Pairman Jun 12, 2024
9d0737b
Update score.dart
Pairman Jun 12, 2024
15f033f
Update score.dart
Pairman Jun 12, 2024
17e84c3
move score caching logic to score session
Pairman Jun 12, 2024
cd04fdd
Update build_for_android.yml
Pairman Jun 12, 2024
7654bd3
display toast if using cached scores; cache expiration on 6h
Pairman Jun 12, 2024
42ec136
add dev on settings-about page
Pairman Jun 12, 2024
5db61d4
Delete .github/workflows/build_for_android.yml
Pairman Jun 12, 2024
0e385e1
Delete .github/workflows/build_runner_build.yml
Pairman Jun 12, 2024
0e708db
fix comment position
Pairman Jun 12, 2024
6ce2ff2
Merge pull request #6 from Pairman/main
Pairman Jun 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions lib/model/xidian_ids/score.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@

// ignore_for_file: non_constant_identifier_names

import 'package:json_annotation/json_annotation.dart';

part 'score.g.dart';

@JsonSerializable(explicitToJson: true)
class Score {
int mark; // 编号,用于某种计算,从 0 开始
String name; // 学科名称
Expand All @@ -17,6 +22,7 @@ class Score {
String? level; // 等级
String? isPassedStr; //是否及格,null 没出分,1 通过 0 没有
String? classID; // 教学班序列号

Score({
required this.mark,
required this.name,
Expand Down Expand Up @@ -107,8 +113,43 @@ class Score {
}
}
}

factory Score.fromJson(Map<String, dynamic> json) {
return Score(
mark: json['mark'],
name: json['name'],
score: (json['score'] as num?)?.toDouble(),
semesterCode: json['semesterCode'],
credit: (json['credit'] as num).toDouble(),
classStatus: json['classStatus'],
classType: json['classType'],
scoreStatus: json['scoreStatus'],
scoreTypeCode: json['scoreTypeCode'],
level: json['level'],
isPassedStr: json['isPassedStr'],
classID: json['classID'],
);
}

Map<String, dynamic> toJson() {
return {
'mark': mark,
'name': name,
'score': score,
'semesterCode': semesterCode,
'credit': credit,
'classStatus': classStatus,
'classType': classType,
'scoreStatus': scoreStatus,
'scoreTypeCode': scoreTypeCode,
'level': level,
'isPassedStr': isPassedStr,
'classID': classID,
};
}
}


class ComposeDetail {
String content;
String ratio;
Expand Down
37 changes: 37 additions & 0 deletions lib/model/xidian_ids/score.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions lib/page/score/score.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import 'package:flutter/material.dart';
import 'package:watermeter/model/xidian_ids/score.dart';
import 'package:watermeter/page/public_widget/public_widget.dart';
import 'package:watermeter/page/public_widget/toast.dart';
import 'package:watermeter/page/score/score_page.dart';
import 'package:watermeter/page/score/score_state.dart';
import 'package:watermeter/repository/xidian_ids/ehall_score_session.dart';
Expand All @@ -28,7 +29,16 @@ class _ScoreWindowState extends State<ScoreWindow> {
);
}

void dataInit() => scoreList = ScoreSession().getScore();
void dataInit() {
ScoreSession session = ScoreSession()
scoreList = session.getScore();
if (session.isScoreListCacheUsed) {
showToast(
context: context,
msg: "已显示缓存成绩信息",
);
}
}

@override
void initState() {
Expand Down Expand Up @@ -71,4 +81,4 @@ class _ScoreWindowState extends State<ScoreWindow> {
},
);
}
}
}
6 changes: 6 additions & 0 deletions lib/page/setting/about_page/about_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ class AboutPage extends StatelessWidget {
"开发:图书馆搜索功能",
"https://github.com/NanCunChild",
),
Developer(
"Pairman",
"https://avatars.githubusercontent.com/u/18365163",
"开发:成绩信息缓存功能",
"https://github.com/ZCWzy",
),
Developer(
"ReverierXu",
"https://blog.woooo.tech/img/avatar.png",
Expand Down
74 changes: 69 additions & 5 deletions lib/repository/xidian_ids/ehall_score_session.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@
// ignore_for_file: non_constant_identifier_names

import 'dart:convert';
import 'dart:io';

import 'package:watermeter/repository/preference.dart' as pref;
import 'package:watermeter/model/xidian_ids/score.dart';
import 'package:watermeter/repository/logger.dart';
import 'package:watermeter/repository/network_session.dart';
import 'package:watermeter/repository/xidian_ids/ehall_session.dart';

/// 考试成绩 4768574631264620
class ScoreSession extends EhallSession {
static const scoreListCacheName = "scores.json";
late File file = File("${supportPath.path}/${scoreListCacheName}");
bool isScoreListCacheUsed = false;

/// Must be called after [getScore]!
/// If bug, just return dummy data.
Future<List<ComposeDetail>> getDetail(
Expand Down Expand Up @@ -86,12 +93,61 @@ class ScoreSession extends EhallSession {
}
}

Future<List<Score>> loadScoreListCache() async {
log.i(
"[ScoreSession][loadScoreListCache] "
"Path at ${supportPath.path}/${scoreListCacheName}.",
);
if (file.existsSync()) {
final timeDiff = DateTime.now().difference(
file.lastModifiedSync()
).inHours;
if (timeDiff < 6) {
log.i(
"[ScoreSession][loadScoreListCache] "
"Cache file effective.",
);
List<dynamic> data = jsonDecode(file.readAsStringSync());
return data.map(
(s) => Score.fromJson(s as Map<String, dynamic>)
).toList();
}
}
log.i(
"[ScoreSession][loadScoreListCache] "
"Cache file non-existent or ineffective.",
);
return [];
}

void dumpScoreListCache(List<Score> scores) {
file.writeAsStringSync(
jsonEncode(scores.map((s) => s.toJson()).toList()),
);
log.i(
"[ScoreWindow][dumpScoreListCache] "
"Dumped scoreList to ${supportPath.path}/${scoreListCacheName}.",
);
}

Future<List<Score>> getScore() async {
List<Score> toReturn = [];
/// Try retrieving cached scores first.
isScoreListCacheUsed = false;
toReturn = await loadScoreListCache();
if (!toReturn.isEmpty) {
log.i(
"[ScoreSession][getScore] "
"Loaded scores from cache.",
);
isScoreListCacheUsed = true;
return toReturn;
}

/// Get all scores here.
/// Otherwise get fresh score data.
log.i(
"[ScoreSession] Start getting the score.",
"[ScoreSession][getScore] "
"Start getting score data.",
);
Map<String, dynamic> querySetting = {
'name': 'SFYX',
Expand All @@ -101,7 +157,8 @@ class ScoreSession extends EhallSession {
};

log.i(
"[ScoreSession] Ready to login the system.",
"[ScoreSession][getScore] "
"Ready to log into the system.",
);
var firstPost = await useApp("4768574631264620");
log.i(
Expand All @@ -110,7 +167,8 @@ class ScoreSession extends EhallSession {
await dioEhall.get(firstPost);

log.i(
"[ScoreSession] Getting the score data.",
"[ScoreSession][getScore] "
"Getting score data.",
);
var getData = await dioEhall.post(
"https://ehall.xidian.edu.cn/jwapp/sys/cjcx/modules/cjcx/xscjcx.do",
Expand All @@ -123,7 +181,8 @@ class ScoreSession extends EhallSession {
},
).then((value) => value.data);
log.i(
"[ScoreSession] Dealing the score data.",
"[ScoreSession][getScore] "
"Dealing with the score data.",
);
if (getData['datas']['xscjcx']["extParams"]["code"] != 1) {
throw GetScoreFailedException(
Expand All @@ -150,6 +209,11 @@ class ScoreSession extends EhallSession {
));
j++;
}
dumpScoreListCache(toReturn);
log.i(
"[ScoreSession][getScore] "
"Cached the score data.",
);
return toReturn;
}
}
Expand Down