import 'dart:collection'; import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:toolheim/warband_roaster.dart'; import 'package:yaml/yaml.dart'; enum SyncState { unknown, running, success, error, } class GitHubAdapter { // TODO: Store this in the SharedPreferences final String repository; final String path; static SyncState syncState = SyncState.unknown; List syncErrors = new List(); static DateTime lastSync; GitHubAdapter(this.repository, this.path); /// Search for warband files in the GitHub repository /// /// This method will search for matching files and check their content in a /// subfolder (see fields [repository] and [path]). If the file /// contain errors or can't read, a sync error message will be written into /// the [syncErrors] list. Future> search() async { syncErrors.clear(); Stream> roasterStream() 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( "https://api.github.com/search/code?q=heros+repo:" + repository + "+filename:mordheim.yml+path:\"" + path + "\""); RegExp fileRegex = new RegExp(r"[a-zA-Z]+\.mordheim\.ya?ml"); var resp = jsonDecode(response.body); for (var searchResult in resp['items']) { if (fileRegex.hasMatch(searchResult['name'])) { String completePath = searchResult['path']; String playerName = completePath.substring(path.length + 1).split('/').first; if (playerName == '') { playerName = 'Lonely Recluse'; } // Fetch last change and some metainformation of the file http.Response response = await http.get( "https://api.github.com/repos/" + repository + "/commits?path=" + completePath); var resp = jsonDecode(response.body); var lastCommit = resp.first; // TODO: Add some error handling yield { 'filePath': completePath.toString(), 'shaHash': lastCommit['sha'], 'player': playerName.toString(), 'author': lastCommit['commit']['author']['name'], 'date': lastCommit['commit']['committer']['date'], 'message': lastCommit['commit']['message'] }; } } } List roasters = new List(); // TODO: Read params from share preferences await for (Map player in roasterStream()) { http.Response response = await http.get( "https://raw.githubusercontent.com/" + repository + '/master/' + player['filePath']); try { YamlMap yamlObject = loadYaml(response.body); WarbandRoaster roaster = WarbandRoaster.fromJson(yamlObject); roaster.playerName = player['player']; roaster.author = player['author']; roaster.commitDate = player['date']; roaster.commitMessage = player['message']; roaster.commitHash = player['shaHash'] roasters.add(roaster); } catch (e) { syncErrors.add(e.toString()); } } return roasters; } Future update() async { // TODO: Search for warband yml files // TODO: Check if it is in the right format // TODO: Store it into the database if valid lastSync = DateTime.now(); return SyncState.success; } }