Rearrange the github adapter
This commit is contained in:
parent
761717d0ab
commit
05ca125f87
4 changed files with 112 additions and 103 deletions
|
@ -15,7 +15,7 @@ class GitHubAdapter extends ChangeNotifier {
|
||||||
DateTime _lastSync;
|
DateTime _lastSync;
|
||||||
|
|
||||||
List<WarbandRoster> _rosters = [];
|
List<WarbandRoster> _rosters = [];
|
||||||
String _activePlayerName;
|
WarbandRoster _activeRoster;
|
||||||
|
|
||||||
String get repository => PrefService.getString('repository');
|
String get repository => PrefService.getString('repository');
|
||||||
String get path => PrefService.getString('path');
|
String get path => PrefService.getString('path');
|
||||||
|
@ -29,23 +29,13 @@ class GitHubAdapter extends ChangeNotifier {
|
||||||
UnmodifiableListView<WarbandRoster> get rosters =>
|
UnmodifiableListView<WarbandRoster> get rosters =>
|
||||||
UnmodifiableListView(_rosters);
|
UnmodifiableListView(_rosters);
|
||||||
|
|
||||||
WarbandRoster activeRoster() {
|
WarbandRoster get activeRoster => _activeRoster;
|
||||||
if (_activePlayerName == null || _rosters.length == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _rosters.firstWhere((roster) {
|
set activeRoster(WarbandRoster roster) {
|
||||||
return roster.playerName == _activePlayerName;
|
_activeRoster = roster;
|
||||||
}, orElse: () => null);
|
|
||||||
}
|
|
||||||
|
|
||||||
void changeActiveRoster(String playerName) {
|
|
||||||
_activePlayerName = playerName;
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add persistence layer here
|
|
||||||
|
|
||||||
/// Search for warband files in the GitHub repository
|
/// Search for warband files in the GitHub repository
|
||||||
///
|
///
|
||||||
/// This method will search for matching files and check their content in a
|
/// This method will search for matching files and check their content in a
|
||||||
|
@ -56,7 +46,7 @@ class GitHubAdapter extends ChangeNotifier {
|
||||||
_syncErrors.clear();
|
_syncErrors.clear();
|
||||||
_syncinProgress = true;
|
_syncinProgress = true;
|
||||||
|
|
||||||
Stream<Map<String, String>> rosterStream() async* {
|
Stream<String> warbandFileStream() async* {
|
||||||
// Get all files which could be potential warband files (end with
|
// Get all files which could be potential warband files (end with
|
||||||
// mordheim.yml and contain the word "heros").
|
// mordheim.yml and contain the word "heros").
|
||||||
http.Response response = await http.get(
|
http.Response response = await http.get(
|
||||||
|
@ -69,7 +59,7 @@ class GitHubAdapter extends ChangeNotifier {
|
||||||
// GitHub is not reachable
|
// GitHub is not reachable
|
||||||
if (response.statusCode != 200) {
|
if (response.statusCode != 200) {
|
||||||
_syncErrors.add('Could not find any warband roster files.');
|
_syncErrors.add('Could not find any warband roster files.');
|
||||||
yield {};
|
yield null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +69,7 @@ class GitHubAdapter extends ChangeNotifier {
|
||||||
searchResults = jsonDecode(response.body);
|
searchResults = jsonDecode(response.body);
|
||||||
} on FormatException catch (e) {
|
} on FormatException catch (e) {
|
||||||
_syncErrors.add('Could not parse GitHub response. ' + e.toString());
|
_syncErrors.add('Could not parse GitHub response. ' + e.toString());
|
||||||
yield {};
|
yield null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,96 +77,38 @@ class GitHubAdapter extends ChangeNotifier {
|
||||||
RegExp fileRegex = new RegExp(r"[a-zA-Z]+\.mordheim\.ya?ml");
|
RegExp fileRegex = new RegExp(r"[a-zA-Z]+\.mordheim\.ya?ml");
|
||||||
for (dynamic searchResult in searchResults['items']) {
|
for (dynamic searchResult in searchResults['items']) {
|
||||||
if (fileRegex.hasMatch(searchResult['name'])) {
|
if (fileRegex.hasMatch(searchResult['name'])) {
|
||||||
// We try to get the name of the player from the name of the folder
|
yield searchResult['path'].toString();
|
||||||
// in which the file resists
|
|
||||||
String completePath = searchResult['path'];
|
|
||||||
List<String> pathParts =
|
|
||||||
completePath.substring(path.length + 1).split('/');
|
|
||||||
|
|
||||||
String playerName;
|
|
||||||
if (pathParts.length >= 2) {
|
|
||||||
playerName = pathParts.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch last change and some metainformation of the file
|
|
||||||
http.Response response = await http.get(
|
|
||||||
"https://api.github.com/repos/" +
|
|
||||||
repository +
|
|
||||||
"/commits?path=" +
|
|
||||||
completePath);
|
|
||||||
|
|
||||||
if (response.statusCode != 200) {
|
|
||||||
_syncErrors.add('Could not load the warband metadata from GitHub.');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No valid response from GitHub
|
|
||||||
dynamic commits;
|
|
||||||
try {
|
|
||||||
commits = jsonDecode(response.body);
|
|
||||||
} on FormatException catch (e) {
|
|
||||||
_syncErrors.add('Could not parse GitHub response. ' + e.toString());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No commits available
|
|
||||||
if (commits.length == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic latestCommit = commits.first;
|
|
||||||
yield {
|
|
||||||
'filePath': completePath.toString(),
|
|
||||||
'shaHash': latestCommit['sha'],
|
|
||||||
'player': playerName.toString(),
|
|
||||||
'author': latestCommit['commit']['author']['name'],
|
|
||||||
'date': latestCommit['commit']['committer']['date'],
|
|
||||||
'message': latestCommit['commit']['message']
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
storage.clear();
|
||||||
_rosters.clear();
|
_rosters.clear();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
if (_syncErrors.length == 0) {
|
if (_syncErrors.length == 0) {
|
||||||
await for (Map<String, String> player in rosterStream()) {
|
await for (String filePath in warbandFileStream()) {
|
||||||
http.Response response;
|
WarbandRoster roster = await fetchWarband(filePath);
|
||||||
try {
|
Version latestVersion = await getLatestCommit(filePath);
|
||||||
response = await http.get("https://raw.githubusercontent.com/" +
|
|
||||||
repository +
|
|
||||||
'/master/' +
|
|
||||||
player['filePath']);
|
|
||||||
} catch (e) {
|
|
||||||
// TODO: Ignore this error, we catch it elsewhere.
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
roster.playerName = getPlayerNameFromFilePath(filePath);
|
||||||
if (response != null) {
|
roster.currentVersion = latestVersion;
|
||||||
YamlMap yamlObject = loadYaml(response.body);
|
|
||||||
WarbandRoster roster = WarbandRoster.fromJson(yamlObject);
|
|
||||||
if (player['player'] != '') {
|
|
||||||
roster.playerName = player['player'];
|
|
||||||
}
|
|
||||||
|
|
||||||
roster.currentVersion = new Version(player['shaHash'],
|
|
||||||
player['date'], player['author'], player['message']);
|
|
||||||
|
|
||||||
// On a search, we drop all previous information about the warbands,
|
// On a search, we drop all previous information about the warbands,
|
||||||
// Sp, lastSyncVersion is equal to the currentVersion.
|
// So, lastSyncVersion is equal to the currentVersion.
|
||||||
roster.lastSyncVersion = roster.currentVersion;
|
roster.lastSyncVersion = roster.currentVersion;
|
||||||
|
|
||||||
_rosters.add(roster);
|
_rosters.add(roster);
|
||||||
|
|
||||||
//https://github.com/lesnitsky/flutter_localstorage/blob/master/example/lib/main.dart
|
//https://github.com/lesnitsky/flutter_localstorage/blob/master/example/lib/main.dart
|
||||||
// FIXME: store it correctly
|
// FIXME: store it correctly
|
||||||
//storage.setItem(player['player'], roster);
|
//storage.setItem(player['player'] + '-warband-yaml', response.body);
|
||||||
|
//storage.setItem(
|
||||||
|
// player['player'] + '-current-version', roster.currentVersion);
|
||||||
|
//storage.setItem(
|
||||||
|
// player['player'] + '-last-sync-version', roster.lastSyncVersion);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
_syncErrors.add(e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort by CP
|
// Sort by CP
|
||||||
|
@ -184,7 +116,7 @@ class GitHubAdapter extends ChangeNotifier {
|
||||||
|
|
||||||
// Select first as active player if no active player is selected
|
// Select first as active player if no active player is selected
|
||||||
if (_rosters.length > 0) {
|
if (_rosters.length > 0) {
|
||||||
_activePlayerName = _rosters.first.playerName;
|
_activeRoster = _rosters.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastSync = DateTime.now();
|
_lastSync = DateTime.now();
|
||||||
|
@ -195,12 +127,86 @@ class GitHubAdapter extends ChangeNotifier {
|
||||||
|
|
||||||
void update() async {
|
void update() async {
|
||||||
_syncinProgress = true;
|
_syncinProgress = true;
|
||||||
// TODO: Search for warband yml files
|
|
||||||
// TODO: Check if it is in the right format
|
// TODO: Loop through the found warbands and update it.
|
||||||
// TODO: Store it into the database if valid
|
|
||||||
|
|
||||||
_lastSync = DateTime.now();
|
_lastSync = DateTime.now();
|
||||||
_syncinProgress = false;
|
_syncinProgress = false;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getPlayerNameFromFilePath(String filePath) {
|
||||||
|
// We try to get the name of the player from the name of the folder
|
||||||
|
// in which the file resists
|
||||||
|
List<String> pathParts = filePath.substring(path.length + 1).split('/');
|
||||||
|
|
||||||
|
String playerName = 'Lonely Recluse';
|
||||||
|
if (pathParts.length >= 2) {
|
||||||
|
playerName = pathParts.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
return playerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Version> getLatestCommit(String filePath) async {
|
||||||
|
// Fetch last change and some metainformation of the file
|
||||||
|
http.Response response = await http.get("https://api.github.com/repos/" +
|
||||||
|
repository +
|
||||||
|
"/commits?path=" +
|
||||||
|
filePath);
|
||||||
|
|
||||||
|
if (response.statusCode != 200) {
|
||||||
|
_syncErrors.add('Could not load the warband metadata from GitHub.');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No valid response from GitHub
|
||||||
|
dynamic commits;
|
||||||
|
try {
|
||||||
|
commits = jsonDecode(response.body);
|
||||||
|
} on FormatException catch (e) {
|
||||||
|
_syncErrors.add('Could not parse GitHub response. ' + e.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No commits available
|
||||||
|
if (commits.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic latestCommit = commits.first;
|
||||||
|
return new Version(
|
||||||
|
latestCommit['sha'],
|
||||||
|
latestCommit['commit']['committer']['date'],
|
||||||
|
latestCommit['commit']['author']['name'],
|
||||||
|
latestCommit['commit']['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<WarbandRoster> fetchWarband(String filePath) async {
|
||||||
|
http.Response response;
|
||||||
|
try {
|
||||||
|
response = await http.get("https://raw.githubusercontent.com/" +
|
||||||
|
repository +
|
||||||
|
'/master/' +
|
||||||
|
filePath);
|
||||||
|
} catch (e) {
|
||||||
|
// We ignore this error, because it will handle from the _syncErrors
|
||||||
|
// later (see below).
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (response != null) {
|
||||||
|
YamlMap yamlObject = loadYaml(response.body);
|
||||||
|
return WarbandRoster.fromJson(yamlObject);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
_syncErrors.add(e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void readWarband(WarbandRoster roster, String yamlContent) {
|
||||||
|
// TODO: Read the warband from the shared preferences
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,10 +204,13 @@ class WarbandRoster {
|
||||||
final List<HenchmenGroup> henchmenGroups;
|
final List<HenchmenGroup> henchmenGroups;
|
||||||
|
|
||||||
/// The players name is not defined in the yml file. This will be added later
|
/// The players name is not defined in the yml file. This will be added later
|
||||||
/// from the GitHubAdapter.
|
/// from the GitHubAdapter. Same goes for the lastSyncVersion and currentVersion.
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
String playerName = 'Lonely Recluse';
|
String playerName = 'Lonely Recluse';
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
String filePath;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
Version lastSyncVersion;
|
Version lastSyncVersion;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ class WarbandRosterScreen extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
GitHubAdapter github = Provider.of<GitHubAdapter>(context);
|
GitHubAdapter github = Provider.of<GitHubAdapter>(context);
|
||||||
WarbandRoster roster = github.activeRoster();
|
WarbandRoster roster = github.activeRoster;
|
||||||
|
|
||||||
if (roster == null) {
|
if (roster == null) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
|
|
@ -32,7 +32,7 @@ class WarbandDrawerWidget extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Never fetched any data
|
// Never fetched any data
|
||||||
if (github.activeRoster() == null) {
|
if (github.activeRoster == null) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(top: 100, left: 30, right: 30),
|
padding: const EdgeInsets.only(top: 100, left: 30, right: 30),
|
||||||
child: Column(children: <Widget>[
|
child: Column(children: <Widget>[
|
||||||
|
@ -56,7 +56,7 @@ class WarbandDrawerWidget extends StatelessWidget {
|
||||||
|
|
||||||
Widget buildRosterList(BuildContext context) {
|
Widget buildRosterList(BuildContext context) {
|
||||||
GitHubAdapter github = Provider.of<GitHubAdapter>(context);
|
GitHubAdapter github = Provider.of<GitHubAdapter>(context);
|
||||||
WarbandRoster activeroster = github.activeRoster();
|
WarbandRoster activeroster = github.activeRoster;
|
||||||
List<WarbandRoster> rosters = github.rosters;
|
List<WarbandRoster> rosters = github.rosters;
|
||||||
|
|
||||||
List<Widget> tiles = new List();
|
List<Widget> tiles = new List();
|
||||||
|
@ -96,7 +96,7 @@ class WarbandDrawerWidget extends StatelessWidget {
|
||||||
|
|
||||||
tiles.add(ListTile(
|
tiles.add(ListTile(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
github.changeActiveRoster(roster.playerName);
|
github.activeRoster = roster;
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
title: Text(roster.name + ' (' + roster.playerName + ')',
|
title: Text(roster.name + ' (' + roster.playerName + ')',
|
||||||
|
|
Loading…
Reference in a new issue