From 05ca125f87d47da23fc8211d790e21e06463a716 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Sat, 27 Jul 2019 00:09:51 +0200 Subject: [PATCH] Rearrange the github adapter --- mobile-app/lib/data/github_adapter.dart | 202 +++++++++--------- mobile-app/lib/data/warband_roster.dart | 5 +- .../lib/screens/warband_roster_screen.dart | 2 +- .../lib/widgets/warband_drawer_widget.dart | 6 +- 4 files changed, 112 insertions(+), 103 deletions(-) diff --git a/mobile-app/lib/data/github_adapter.dart b/mobile-app/lib/data/github_adapter.dart index 09ab6ad..70a558f 100644 --- a/mobile-app/lib/data/github_adapter.dart +++ b/mobile-app/lib/data/github_adapter.dart @@ -15,7 +15,7 @@ class GitHubAdapter extends ChangeNotifier { DateTime _lastSync; List _rosters = []; - String _activePlayerName; + WarbandRoster _activeRoster; String get repository => PrefService.getString('repository'); String get path => PrefService.getString('path'); @@ -29,23 +29,13 @@ class GitHubAdapter extends ChangeNotifier { UnmodifiableListView get rosters => UnmodifiableListView(_rosters); - WarbandRoster activeRoster() { - if (_activePlayerName == null || _rosters.length == 0) { - return null; - } + WarbandRoster get activeRoster => _activeRoster; - return _rosters.firstWhere((roster) { - return roster.playerName == _activePlayerName; - }, orElse: () => null); - } - - void changeActiveRoster(String playerName) { - _activePlayerName = playerName; + set activeRoster(WarbandRoster roster) { + _activeRoster = roster; notifyListeners(); } - // TODO: Add persistence layer here - /// Search for warband files in the GitHub repository /// /// This method will search for matching files and check their content in a @@ -56,7 +46,7 @@ class GitHubAdapter extends ChangeNotifier { _syncErrors.clear(); _syncinProgress = true; - Stream> rosterStream() async* { + Stream warbandFileStream() async* { // Get all files which could be potential warband files (end with // mordheim.yml and contain the word "heros"). http.Response response = await http.get( @@ -69,7 +59,7 @@ class GitHubAdapter extends ChangeNotifier { // GitHub is not reachable if (response.statusCode != 200) { _syncErrors.add('Could not find any warband roster files.'); - yield {}; + yield null; return; } @@ -79,7 +69,7 @@ class GitHubAdapter extends ChangeNotifier { searchResults = jsonDecode(response.body); } on FormatException catch (e) { _syncErrors.add('Could not parse GitHub response. ' + e.toString()); - yield {}; + yield null; return; } @@ -87,95 +77,37 @@ class GitHubAdapter extends ChangeNotifier { RegExp fileRegex = new RegExp(r"[a-zA-Z]+\.mordheim\.ya?ml"); for (dynamic searchResult in searchResults['items']) { if (fileRegex.hasMatch(searchResult['name'])) { - // We try to get the name of the player from the name of the folder - // in which the file resists - String completePath = searchResult['path']; - List 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'] - }; + yield searchResult['path'].toString(); } } } + storage.clear(); _rosters.clear(); notifyListeners(); if (_syncErrors.length == 0) { - await for (Map player in rosterStream()) { - http.Response response; - try { - response = await http.get("https://raw.githubusercontent.com/" + - repository + - '/master/' + - player['filePath']); - } catch (e) { - // TODO: Ignore this error, we catch it elsewhere. - } + await for (String filePath in warbandFileStream()) { + WarbandRoster roster = await fetchWarband(filePath); + Version latestVersion = await getLatestCommit(filePath); - try { - if (response != null) { - YamlMap yamlObject = loadYaml(response.body); - WarbandRoster roster = WarbandRoster.fromJson(yamlObject); - if (player['player'] != '') { - roster.playerName = player['player']; - } + roster.playerName = getPlayerNameFromFilePath(filePath); + roster.currentVersion = latestVersion; - roster.currentVersion = new Version(player['shaHash'], - player['date'], player['author'], player['message']); + // On a search, we drop all previous information about the warbands, + // So, lastSyncVersion is equal to the currentVersion. + roster.lastSyncVersion = roster.currentVersion; - // On a search, we drop all previous information about the warbands, - // Sp, lastSyncVersion is equal to the currentVersion. - roster.lastSyncVersion = roster.currentVersion; + _rosters.add(roster); - _rosters.add(roster); - //https://github.com/lesnitsky/flutter_localstorage/blob/master/example/lib/main.dart - // FIXME: store it correctly - //storage.setItem(player['player'], roster); - notifyListeners(); - } - } catch (e) { - _syncErrors.add(e.toString()); - } + //https://github.com/lesnitsky/flutter_localstorage/blob/master/example/lib/main.dart + // FIXME: store it correctly + //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(); } } @@ -184,7 +116,7 @@ class GitHubAdapter extends ChangeNotifier { // Select first as active player if no active player is selected if (_rosters.length > 0) { - _activePlayerName = _rosters.first.playerName; + _activeRoster = _rosters.first; } _lastSync = DateTime.now(); @@ -195,12 +127,86 @@ class GitHubAdapter extends ChangeNotifier { void update() async { _syncinProgress = true; - // TODO: Search for warband yml files - // TODO: Check if it is in the right format - // TODO: Store it into the database if valid + + // TODO: Loop through the found warbands and update it. _lastSync = DateTime.now(); _syncinProgress = false; 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 pathParts = filePath.substring(path.length + 1).split('/'); + + String playerName = 'Lonely Recluse'; + if (pathParts.length >= 2) { + playerName = pathParts.first; + } + + return playerName; + } + + Future 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 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 + } } diff --git a/mobile-app/lib/data/warband_roster.dart b/mobile-app/lib/data/warband_roster.dart index db199bb..faa6f60 100644 --- a/mobile-app/lib/data/warband_roster.dart +++ b/mobile-app/lib/data/warband_roster.dart @@ -204,10 +204,13 @@ class WarbandRoster { final List henchmenGroups; /// 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) String playerName = 'Lonely Recluse'; + @JsonKey(ignore: true) + String filePath; + @JsonKey(ignore: true) Version lastSyncVersion; diff --git a/mobile-app/lib/screens/warband_roster_screen.dart b/mobile-app/lib/screens/warband_roster_screen.dart index d2c8437..5fef49a 100644 --- a/mobile-app/lib/screens/warband_roster_screen.dart +++ b/mobile-app/lib/screens/warband_roster_screen.dart @@ -9,7 +9,7 @@ class WarbandRosterScreen extends StatelessWidget { @override Widget build(BuildContext context) { GitHubAdapter github = Provider.of(context); - WarbandRoster roster = github.activeRoster(); + WarbandRoster roster = github.activeRoster; if (roster == null) { return Scaffold( diff --git a/mobile-app/lib/widgets/warband_drawer_widget.dart b/mobile-app/lib/widgets/warband_drawer_widget.dart index d119b07..1f9c3d3 100644 --- a/mobile-app/lib/widgets/warband_drawer_widget.dart +++ b/mobile-app/lib/widgets/warband_drawer_widget.dart @@ -32,7 +32,7 @@ class WarbandDrawerWidget extends StatelessWidget { } // Never fetched any data - if (github.activeRoster() == null) { + if (github.activeRoster == null) { return Padding( padding: const EdgeInsets.only(top: 100, left: 30, right: 30), child: Column(children: [ @@ -56,7 +56,7 @@ class WarbandDrawerWidget extends StatelessWidget { Widget buildRosterList(BuildContext context) { GitHubAdapter github = Provider.of(context); - WarbandRoster activeroster = github.activeRoster(); + WarbandRoster activeroster = github.activeRoster; List rosters = github.rosters; List tiles = new List(); @@ -96,7 +96,7 @@ class WarbandDrawerWidget extends StatelessWidget { tiles.add(ListTile( onTap: () { - github.changeActiveRoster(roster.playerName); + github.activeRoster = roster; Navigator.of(context).pop(); }, title: Text(roster.name + ' (' + roster.playerName + ')',