128 lines
3.5 KiB
Dart
128 lines
3.5 KiB
Dart
import 'package:gamer_updater/db.dart';
|
|
import 'package:gamer_updater/utils.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'dart:typed_data';
|
|
|
|
class Game {
|
|
final String name;
|
|
final String versionRegex;
|
|
final RegExp _internalVersionRegex;
|
|
final String lastPlayed;
|
|
String actualVersion;
|
|
String lastUpdated;
|
|
final String rssFeedUrl;
|
|
final Uint8List? imageData;
|
|
|
|
Game({
|
|
required this.name,
|
|
required this.versionRegex,
|
|
required this.lastPlayed,
|
|
this.actualVersion = '',
|
|
required this.rssFeedUrl,
|
|
this.lastUpdated = '',
|
|
this.imageData,
|
|
}) : _internalVersionRegex = RegExp(versionRegex);
|
|
|
|
factory Game.fromMap(Map<String, dynamic> map) {
|
|
return Game(
|
|
name: map['name'],
|
|
versionRegex: map['version_regex'],
|
|
lastPlayed: map['last_played'],
|
|
rssFeedUrl: map['rss_feed_url'],
|
|
actualVersion: map['actual_version'],
|
|
lastUpdated: map['last_updated'],
|
|
imageData: map['image_data'],
|
|
);
|
|
}
|
|
|
|
Future<void> updateActualVersion() async {
|
|
if (rssFeedUrl.isEmpty) {
|
|
throw Exception('No rss feed url for $name');
|
|
}
|
|
final response = await http.get(Uri.parse(rssFeedUrl));
|
|
if (response.statusCode != 200) {
|
|
throw Exception(
|
|
'Failed to update actual version for $name, rss responded with ${response.statusCode}',
|
|
);
|
|
}
|
|
final body = response.body;
|
|
final match = _internalVersionRegex.firstMatch(body);
|
|
if (match == null || match.groupCount == 0) {
|
|
throw Exception('No version found for $name');
|
|
}
|
|
final version = match.group(1);
|
|
if (version == null) {
|
|
throw Exception('No version found for $name');
|
|
}
|
|
actualVersion = version;
|
|
lastUpdated =
|
|
parseRfc822Date(
|
|
response.headers['last-modified'] ?? '',
|
|
).toIso8601String();
|
|
}
|
|
}
|
|
|
|
class GameRepository {
|
|
static Future<Game> upsert(Game game) async {
|
|
final db = DB.db;
|
|
await db.rawInsert(
|
|
'''
|
|
INSERT INTO games
|
|
(name, actual_version, last_played, rss_feed_url, version_regex, last_updated)
|
|
VALUES
|
|
(?, ?, ?, ?, ?, ?)
|
|
ON CONFLICT(name) DO UPDATE SET
|
|
actual_version = excluded.actual_version,
|
|
last_played = excluded.last_played,
|
|
rss_feed_url = excluded.rss_feed_url,
|
|
version_regex = excluded.version_regex,
|
|
last_updated = excluded.last_updated
|
|
''',
|
|
[
|
|
game.name,
|
|
game.actualVersion,
|
|
game.lastPlayed,
|
|
game.rssFeedUrl,
|
|
game.versionRegex,
|
|
game.lastUpdated,
|
|
],
|
|
);
|
|
return game;
|
|
}
|
|
|
|
static Future<Game> updateImage(Game game) async {
|
|
final db = DB.db;
|
|
await db.rawUpdate('UPDATE games SET image_data = ? WHERE name = ?', [
|
|
game.imageData,
|
|
game.name,
|
|
]);
|
|
return game;
|
|
}
|
|
|
|
static Future<Map<String, Game>> getAll() async {
|
|
final db = DB.db;
|
|
final games = await db.rawQuery(
|
|
'SELECT name, actual_version, last_played, rss_feed_url, version_regex, last_updated, image_data FROM games',
|
|
);
|
|
return games
|
|
.map((e) => Game.fromMap(e))
|
|
.fold<Map<String, Game>>({}, (map, game) => {...map, game.name: game});
|
|
}
|
|
|
|
static Future<void> delete(Game game) async {
|
|
final db = DB.db;
|
|
await db.rawDelete('DELETE FROM games WHERE name = ?', [game.name]);
|
|
}
|
|
}
|
|
|
|
//CREATE TABLE IF NOT EXISTS games (
|
|
// id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
// name TEXT NOT NULL,
|
|
// actual_version TEXT NOT NULL,
|
|
// last_played TEXT NOT NULL,
|
|
// rss_feed_url TEXT NOT NULL,
|
|
// version_regex TEXT NOT NULL,
|
|
// last_updated TEXT NOT NULL
|
|
//);
|
|
//CREATE INDEX IF NOT EXISTS idx_games_name ON games (name);
|