Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ void main() async {

var searchBoardGamesResult = await bgg.searchBoardGames('catan');
print(searchBoardGamesResult.length);

}
2 changes: 2 additions & 0 deletions lib/bgg_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export 'src/api/query_parameters.dart';
export 'src/api/search_parameters.dart';
export 'src/api/thing_parameters.dart';
export 'src/api/thing_type.dart';
export 'src/model/generic_ref.dart';
export 'src/model/poll.dart';
export 'src/model/board_game.dart' show BoardGame;
export 'src/model/board_game_ref.dart' show BoardGameRef;
export 'src/model/item_ref.dart' show ItemRef;
Expand Down
6 changes: 5 additions & 1 deletion lib/src/api/search_parameters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ class SearchParameters extends QueryParameters {
/// Limit results to items that match the SEARCH_QUERY exactly
final bool exact;

SearchParameters({required this.query, this.type = const [], this.exact = false});
SearchParameters({
required this.query,
this.type = const [],
this.exact = false,
});

@override
Map<String, dynamic> toMap() {
Expand Down
9 changes: 8 additions & 1 deletion lib/src/api/thing_type.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
enum ThingType { boardgame, boardgameexpansion, boardgameaccessory, videogame, rpgitem, rpgissue }
enum ThingType {
boardgame,
boardgameexpansion,
boardgameaccessory,
videogame,
rpgitem,
rpgissue
}

extension ThingTypeName on ThingType {
String name() {
Expand Down
128 changes: 97 additions & 31 deletions lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,65 +30,131 @@ class Bgg {
Bgg({BggHttp? http}) : _http = http ?? BggHttp();

/// Retrieve information about a particular board game by [gameId].
Future<BoardGame?> getBoardGame(int gameId) async {
return _getFirstElement(['thing'], const BoardGameDecoder(),
ThingParameters(id: [gameId], type: [ThingType.boardgame, ThingType.boardgameexpansion]));
}
Future<BoardGame?> getBoardGame(int gameId) async => _getFirstElement(
['thing'],
const BoardGameDecoder(),
ThingParameters(
id: [gameId],
type: [ThingType.boardgame, ThingType.boardgameexpansion],
),
);

/// Retrieve information about a particular thing.
Future<BoardGame?> getThing(ThingParameters parameters) async {
return _getFirstElement(['thing'], const BoardGameDecoder(), parameters);
}
Future<BoardGame?> getThing(ThingParameters parameters) async =>
_getFirstElement(['thing'], const BoardGameDecoder(), parameters);

/// Retrieve information about things.
Future<List<BoardGame>> getThings(ThingParameters parameters) async {
return _getAllElements(['thing'], const BoardGameDecoder(), parameters);
}
Future<List<BoardGame>> getThings(
ThingParameters parameters, {
int limit = 30,
int offset = 0,
}) async =>
_getAllElements(
['thing'],
const BoardGameDecoder(),
parameters,
limit: limit,
offset: offset,
);

/// Retrieve information about things.
Future<Forum> getForum(ForumParameters parameters) async {
return _getRoot(['forum'], const ForumDecoder(), parameters);
}
Future<Forum> getForum(ForumParameters parameters) async =>
_getRoot(['forum'], const ForumDecoder(), parameters);

/// Retrieve information about things.
Future<List<Forum>> getForumList(ForumListParameters parameters) async {
return _getAllElements(['forumlist'], const ForumDecoder(), parameters);
}
Future<List<Forum>> getForumList(
ForumListParameters parameters, {
int limit = 30,
int offset = 0,
}) async =>
_getAllElements(
['forumlist'],
const ForumDecoder(),
parameters,
limit: limit,
offset: offset,
);

/// Retrieves a list of board games (only) matching [query].
Future<List<BoardGameRef>> searchBoardGames(String query) async {
return _getAllElements(
['search'], const BoardGameRefDecoder(), SearchParameters(query: query, type: [ThingType.boardgame]));
}
Future<List<BoardGameRef>> searchBoardGames(
String query, {
bool exact = false,
int limit = 30,
int offset = 0,
}) async =>
_getAllElements(
['search'],
const BoardGameRefDecoder(),
SearchParameters(
query: query,
type: [ThingType.boardgame],
exact: exact,
),
limit: limit,
offset: offset,
);

/// Retrieves a list of all things matching [query].
Future<List<Family>> getFamilyItems(FamilyParameters parameters) async {
return _getAllElements(['family'], const FamilyDecoder(), parameters);
}
Future<List<Family>> getFamilyItems(
FamilyParameters parameters, {
int limit = 30,
int offset = 0,
}) async =>
_getAllElements(
['family'],
const FamilyDecoder(),
parameters,
limit: limit,
offset: offset,
);

/// Retrieves a list of all things matching [query].
Future<List<ItemRef>> searchThings(SearchParameters parameters) async {
return _getAllElements(['search'], const ItemRefDecoder(), parameters);
}
Future<List<ItemRef>> searchThings(
SearchParameters parameters, {
int limit = 30,
int offset = 0,
}) async =>
_getAllElements(
['search'],
const ItemRefDecoder(),
parameters,
limit: limit,
offset: offset,
);

Future<T> _getRoot<T>(List<String> path, XmlDecoder<T> decoder, QueryParameters parameters) async {
final xml = (await _http.get(path, queryParameters: parameters.toMap())).rootElement;
Future<T> _getRoot<T>(
List<String> path,
XmlDecoder<T> decoder,
QueryParameters parameters,
) async {
final xml = (await _http.get(path, queryParameters: parameters.toMap()))
.rootElement;
return decoder.decode(xml);
}

Future<T?> _getFirstElement<T>(List<String> path, XmlDecoder<T> decoder, QueryParameters parameters) async {
Future<T?> _getFirstElement<T>(
List<String> path,
XmlDecoder<T> decoder,
QueryParameters parameters,
) async {
final xml = (await _http.get(path, queryParameters: parameters.toMap()))
.rootElement
.children
.firstWhereOrNull((e) => e.nodeType == XmlNodeType.ELEMENT);
return xml != null ? decoder.decode(xml) : null;
}

Future<List<T>> _getAllElements<T>(List<String> path, XmlDecoder<T> decoder, QueryParameters parameters) async {
Future<List<T>> _getAllElements<T>(
List<String> path,
XmlDecoder<T> decoder,
QueryParameters parameters, {
int limit = 30,
int offset = 0,
}) async {
final xml = (await _http.get(path, queryParameters: parameters.toMap()))
.rootElement
.children
.where((e) => e.nodeType == XmlNodeType.ELEMENT);
return xml.map((e) => decoder.decode(e)).toList();
return xml.map((e) => decoder.decode(e)).skip(offset).take(limit).toList();
}
}
9 changes: 6 additions & 3 deletions lib/src/http.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import 'package:xml/xml.dart';
///
/// Most users should directly use the high-level `Bgg` class.
class BggHttp {
static final Uri _defaultBaseUri = Uri(scheme: 'https', host: 'www.boardgamegeek.com', path: 'xmlapi2');
static final Uri _defaultBaseUri =
Uri(scheme: 'https', host: 'www.boardgamegeek.com', path: 'xmlapi2');

final Client _http;
final Uri _baseUri;
Expand All @@ -16,9 +17,11 @@ class BggHttp {
: _http = http ?? Client(),
_baseUri = baseUri ?? _defaultBaseUri;

Future<XmlDocument> get(Iterable<String> pathSegments, {Map<String, dynamic>? queryParameters}) async {
Future<XmlDocument> get(Iterable<String> pathSegments,
{Map<String, dynamic>? queryParameters}) async {
var response = await _http.get(_baseUri.replace(
pathSegments: _baseUri.pathSegments.toList()..addAll(pathSegments), queryParameters: queryParameters));
pathSegments: _baseUri.pathSegments.toList()..addAll(pathSegments),
queryParameters: queryParameters));
return XmlDocument.parse(response.body);
}

Expand Down
31 changes: 30 additions & 1 deletion lib/src/model/board_game.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import 'package:bgg_api/src/model/generic_ref.dart';
import 'package:bgg_api/src/model/poll.dart';

import 'video.dart';

class BoardGame {
Expand All @@ -15,6 +18,20 @@ class BoardGame {
final Uri? image;
final List<Video> videos;
final List<String> names;
final List<Generic> boardGameCategory;
final List<Generic> boardGameMechanic;
final List<Generic> boardGameFamily;
final List<Generic> boardGameExpansion;
final List<Generic> boardGameAccessory;
final List<Generic> boardGameImplementation;
final List<Generic> boardGameDesigner;
final List<Generic> boardGameArtist;
final List<Generic> boardGamePublisher;
final Poll? pollSuggestedNumPlayers;
final Poll? pollSuggestedPlayerAge;
final Poll? pollLanguageDependence;

// final suggestedPlayerAge

BoardGame({
required this.id,
Expand All @@ -29,12 +46,24 @@ class BoardGame {
required this.minAge,
required this.thumbnail,
required this.image,
this.boardGameCategory = const [],
this.boardGameMechanic = const [],
this.boardGameFamily = const [],
this.boardGameExpansion = const [],
this.boardGameAccessory = const [],
this.boardGameImplementation = const [],
this.boardGameDesigner = const [],
this.boardGameArtist = const [],
this.boardGamePublisher = const [],
this.videos = const [],
this.pollSuggestedNumPlayers,
this.pollSuggestedPlayerAge,
this.pollLanguageDependence,
this.names = const [],
});

@override
String toString() {
return 'BoardGame{id: $id, name: $name, description: $description, yearPublished: $yearPublished, minPlayers: $minPlayers, maxPlayers: $maxPlayers, playingTime: $playingTime, minPlayTime: $minPlayTime, maxPlayTime: $maxPlayTime, minAge: $minAge, thumbnail: $thumbnail, image: $image, videos: $videos}';
return 'BoardGame{id: $id, name: $name, description: $description, yearPublished: $yearPublished, minPlayers: $minPlayers, maxPlayers: $maxPlayers, playingTime: $playingTime, minPlayTime: $minPlayTime, maxPlayTime: $maxPlayTime, minAge: $minAge, thumbnail: $thumbnail, image: $image, videos: $videos, pollSuggestedNumPlayers: \$pollSuggestedNumPlayers, pollSuggestedPlayerAge: $pollSuggestedPlayerAge, pollLanguageDependence: $pollLanguageDependence}';
}
}
23 changes: 12 additions & 11 deletions lib/src/model/collection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ class CollectionItem {
final Uri? thumbnail;
final int? numPlays;

CollectionItem(
{this.objectType,
this.objectId,
this.subtype,
this.collId,
this.name,
this.originalName,
this.yearPublished,
this.image,
this.thumbnail,
this.numPlays});
CollectionItem({
this.objectType,
this.objectId,
this.subtype,
this.collId,
this.name,
this.originalName,
this.yearPublished,
this.image,
this.thumbnail,
this.numPlays,
});
}
19 changes: 10 additions & 9 deletions lib/src/model/forum.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ class Forum {
final String? lastPostDate;
final List<Thread> threads;

Forum(
{this.id,
this.groupId,
this.title,
this.description,
this.numThreads,
this.numPosts,
this.lastPostDate,
this.threads = const []});
Forum({
this.id,
this.groupId,
this.title,
this.description,
this.numThreads,
this.numPosts,
this.lastPostDate,
this.threads = const [],
});

@override
String toString() {
Expand Down
5 changes: 4 additions & 1 deletion lib/src/model/forum_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ class ForumList {
final int id;
final List<Forum> forums;

ForumList({required this.id, this.forums = const []});
ForumList({
required this.id,
this.forums = const [],
});
}
16 changes: 16 additions & 0 deletions lib/src/model/generic_ref.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Generic {
final int? id;
final String? value;
final String? type;

Generic({
this.id,
this.value,
this.type,
});

@override
String toString() {
return 'Generic{id: $id, name: $value, type: $type}';
}
}
5 changes: 4 additions & 1 deletion lib/src/model/item_ref.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ class ItemRef {
final int? id;
final String? name;

ItemRef({this.id, this.name});
ItemRef({
this.id,
this.name,
});

@override
String toString() {
Expand Down
20 changes: 20 additions & 0 deletions lib/src/model/poll.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:bgg_api/src/model/poll_result.dart';

class Poll {
String name;
String title;
int totalVotes;
List<PollResult> results;

Poll({
required this.name,
required this.title,
required this.totalVotes,
required this.results,
});

@override
String toString() {
return 'name:$name,title:$title,totalVotes:$totalVotes,results:${results.join(',\n')}\n\n\n';
}
}
Loading