Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache leaderboards and provide leaderboard data with user #36

Merged
merged 40 commits into from
May 22, 2021
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
9ca897c
add materialized views for leaderboards
May 19, 2021
32c7010
remove blank line
May 19, 2021
07aea1a
Change contribution dates
May 19, 2021
eef1ef1
change queries for new leaderboard setup
May 19, 2021
b051282
add placements to users
May 19, 2021
670eaf8
fix syntax errors
May 19, 2021
f097a09
Add new leaderboard endpoints and user rankings
ThomasMG May 20, 2021
b4a307a
remove log in check on personal leaderboards
May 20, 2021
df4c312
Merge branch 'server-cache-leaderboards' of github.com:SEbbaDK/p8 int…
May 20, 2021
52e8aa5
fix errors in capitalisation and slash at end
ThomasMG May 20, 2021
293f21e
add path to placement and lowercase leaderboard type to_string
May 20, 2021
932d326
Merge branches 'server-cache-leaderboards' and 'server-cache-leaderbo…
May 20, 2021
dfdb711
add path to placement
ThomasMG May 20, 2021
f4e5068
mtapi&server: Up the version number
SEbbaDK May 20, 2021
868b1c8
mtapi: Add LeaderboardSummary to deserialisation
SEbbaDK May 20, 2021
e648f82
mtapi: Deprecate the reversed leaderboard function
SEbbaDK May 20, 2021
1f10cbb
extended LeaderboardType with stringify as a method and added fromString
May 21, 2021
73ee7e4
add support for new leaderboard endpoints and placements on users
May 21, 2021
66b318a
run dart format
May 21, 2021
3f28e91
Merge remote-tracking branch 'origin/master' into server-cache-leader…
SEbbaDK May 21, 2021
da901e0
Merge branch 'maptogetherapi-leaderboard-placements' into server-cach…
SEbbaDK May 21, 2021
bc3bde7
add coalesce to materialized views to replace null with 0
May 21, 2021
2479d97
add monthly and weekly scores to users
May 21, 2021
896e6b1
mtapi: Add leaderboardByPath and removed failed deprecation
SEbbaDK May 21, 2021
f5e5c3d
add all time, monthly and weekly score to user
May 21, 2021
d1b168e
build data.g.dart
May 21, 2021
8db1a8a
server: Fix references to non-existant variable
SEbbaDK May 21, 2021
fca0eaf
server: Update container to refresh materialized views
SEbbaDK May 21, 2021
dc6cc86
client: Use the newer leaderboard(type, name) mtapi function
SEbbaDK May 21, 2021
ea8c024
client: Split shown score into the three new values
SEbbaDK May 21, 2021
bd25819
add monthly and weekly score to mtapi test
May 21, 2021
e22d12d
fix parameters to queries
May 21, 2021
0d28035
client: Add text to the error shown to the user
SEbbaDK May 22, 2021
6903c03
server: Parametrise queries and add logging on user interactions
SEbbaDK May 22, 2021
7a898fb
mtapi: Disallow non-existant fields in user deserialisation
SEbbaDK May 22, 2021
1894a99
server: Make container ephemeral
SEbbaDK May 22, 2021
28d318a
server: Placement -> LeaderboardSummary
SEbbaDK May 22, 2021
1d50589
client: Format
SEbbaDK May 22, 2021
6ef82a7
server: Fix ugly sql indentation from autoformat
SEbbaDK May 22, 2021
35f789e
server: Fix container timer for refreshing leaderboards
SEbbaDK May 22, 2021
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
22 changes: 22 additions & 0 deletions api-server.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ let
databaseSetup = ./server/database/create-role-and-database.sql;
tableSetup = pkgs.writeText "setup.sql" ''
${builtins.readFile ./server/database/create-tables.sql}
${builtins.readFile ./server/database/create-materialized-views.sql}
${mockData}
'';
in
Expand Down Expand Up @@ -63,6 +64,27 @@ in
wantedBy = [ "default.target" ];
};

systemd.services.maptogether-refresh-views = {
description = "Refresh the MapTogether views";
serviceConfig = {
Type = "oneshot";
User = "maptogether";
Group = "maptogether";
ExecStart = "${pkgs.postgresql}/bin/psql -d maptogether -f ${./server/database/refresh-materialized-views.sql}";
};
requires = [ "maptogether-database-setup.service" "postgresql.service" ];
after = [ "maptogether-database-setup.service" "postgresql.service" ];
};

systemd.timers.maptogether-refresh-timer = {
description = "Timer to trigger refresh";
timerConfig = {
Unit = "maptogether-refresh-views";
OnCalendar = "*:*:0"; # once a minute
};
wantedBy = [ "default.target" ];
};

users.groups.maptogether.gid = 1005;
users.users.maptogether = {
isSystemUser = true;
Expand Down
14 changes: 10 additions & 4 deletions client/lib/widgets/error.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@ class Error extends StatelessWidget {

@override
build(BuildContext context) =>
Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Text(error.toString()),
]
);
}
2 changes: 1 addition & 1 deletion client/lib/widgets/social/overview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class Overview extends StatelessWidget {
builder: (context) => LeaderboardWidget(leaderboard: context
.watch<LoginHandler>()
.mtApi()
.leaderboard(name, type)),
.leaderboard(type, name)),
));
},
));
Expand Down
18 changes: 16 additions & 2 deletions client/lib/widgets/social/user_overview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,27 @@ class UserOverview extends StatelessWidget {
fontWeight: FontWeight.bold
)
),
Text("Score : ${user.score}",
Text("Score : ${user.scoreAllTime}",
style: TextStyle(fontFamily: 'RobotoMono',
fontSize: 18,
color: Colors.lightGreen,
fontWeight: FontWeight.bold
)
)
),
Text("Monthly Score : ${user.scoreMonthly}",
style: TextStyle(fontFamily: 'RobotoMono',
fontSize: 18,
color: Colors.lightGreen,
fontWeight: FontWeight.bold
)
),
Text("Weekly Score : ${user.scoreWeekly}",
style: TextStyle(fontFamily: 'RobotoMono',
fontSize: 18,
color: Colors.lightGreen,
fontWeight: FontWeight.bold
)
),
],
)
],
Expand Down
2 changes: 0 additions & 2 deletions maptogether_api/example/maptogether_api_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,4 @@ void main() {
api.leaderboard("global", LeaderboardType.all_time).then((l) {
print(l.entries[1].user.name);
});

}

42 changes: 12 additions & 30 deletions maptogether_api/lib/src/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,6 @@ import 'dart:convert';
import 'package:http/http.dart' as http;
import 'data.dart' as data;

enum LeaderboardType { weekly, monthly, all_time }
String stringify(LeaderboardType type) {
switch (type) {
case LeaderboardType.weekly:
return "weekly";
case LeaderboardType.monthly:
return "monthly";
case LeaderboardType.all_time:
return 'all_time';
}
throw 'Leaderboard type does not exsist';
}

class InvalidRegionException implements Exception {
final String _message;
InvalidRegionException(
Expand Down Expand Up @@ -62,31 +49,26 @@ class Api {
Future<data.User> user(int id) =>
_get('user/$id').then(_checkRequest('getting user')).then(_decodeUser);

Future<data.Leaderboard> leaderboard(String base, LeaderboardType type) =>
_get('leaderboard/$base/${stringify(type)}')
.then(_checkRequest('getting leaderboard'))
.then(_decodeLeaderboard);
leaderboardByPath(String path) => _get('leaderboard/$path')
.then(_checkRequest('getting leaderboard'))
.then(_decodeLeaderboard);

Future<data.Leaderboard> personalLeaderboard(LeaderboardType type) =>
leaderboard('personal', type);
Future<data.Leaderboard> leaderboard(
data.LeaderboardType type, String name) =>
leaderboardByPath('${type.stringify()}/$name');

Future<data.Leaderboard> globalLeaderboard(LeaderboardType type) =>
leaderboard('global', type);
Future<data.Leaderboard> personalLeaderboard(
data.LeaderboardType type, int id) =>
leaderboard(type, 'personal/${id}');

Future<data.Leaderboard> regionalLeaderboard(
String region, LeaderboardType type) {
if (region == 'personal' || region == 'global')
throw InvalidRegionException();
else
return leaderboard(region, type);
}
Future<data.Leaderboard> globalLeaderboard(data.LeaderboardType type) =>
leaderboard(type, 'global');

// Push Endpoints

Future<void> createUser(
int id, String secret, String clientToken, String clientSecret) =>
_put('user/$id',
auth: '$_access $secret $clientToken $clientSecret')
_put('user/$id', auth: '$_access $secret $clientToken $clientSecret')
.then(_checkRequest('creating user'));

Future<void> follow(int id, int other) =>
Expand Down
69 changes: 63 additions & 6 deletions maptogether_api/lib/src/data.dart
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:maptogether_api/src/api.dart';

part 'data.g.dart';

@JsonSerializable()
class User {
final int id, score;
final int id;
@JsonKey(name: "score_all_time")
final int scoreAllTime;
@JsonKey(name: "score_monthly")
final int scoreMonthly;
@JsonKey(name: "score_weekly")
final int scoreWeekly;
final String name;

@JsonKey(defaultValue: null)
final List<Achievement> achievements;
@JsonKey(defaultValue: null)
final List<SimpleUser> followers;
@JsonKey(defaultValue: null)
final List<SimpleUser> following;
final List<LeaderboardSummary> leaderboards;

User(
{required this.id,
required this.score,
required this.scoreAllTime,
required this.scoreMonthly,
required this.scoreWeekly,
required this.name,
required this.achievements,
required this.followers,
required this.following});
required this.following,
required this.leaderboards});

factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
Expand Down Expand Up @@ -96,3 +104,52 @@ class Leaderboard {
factory Leaderboard.fromJson(List<dynamic> json) => Leaderboard(
json.map((e) => LeaderboardEntry.fromJson(e)).toList(growable: false));
}

@JsonSerializable()
class LeaderboardSummary {
final String path, name;
final int rank, total;

@JsonKey(fromJson: LeaderboardTypeExtension.fromString)
final LeaderboardType type;

LeaderboardSummary(
{required this.path,
required this.name,
required this.rank,
required this.total,
required this.type});

factory LeaderboardSummary.fromJson(Map<String, dynamic> json) =>
_$LeaderboardSummaryFromJson(json);
Map<String, dynamic> toJson() => _$LeaderboardSummaryToJson(this);
}

enum LeaderboardType { weekly, monthly, all_time }

extension LeaderboardTypeExtension on LeaderboardType {
String stringify() {
switch (this) {
case LeaderboardType.weekly:
return "weekly";
case LeaderboardType.monthly:
return "monthly";
case LeaderboardType.all_time:
return 'all_time';
}
throw 'Leaderboard type does not exsist';
}

static LeaderboardType fromString(String type) {
switch (type) {
case "weekly":
return LeaderboardType.weekly;
case "monthly":
return LeaderboardType.monthly;
case "all_time":
return LeaderboardType.all_time;
default:
return LeaderboardType.all_time;
}
}
}
37 changes: 35 additions & 2 deletions maptogether_api/lib/src/data.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion maptogether_api/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: maptogether_api
description: A library for accessing the maptogether api
version: 0.2.0
version: 0.3.0
homepage: https://github.com/SEbbaDK/p8

environment:
Expand Down
2 changes: 1 addition & 1 deletion maptogether_api/test/api_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:test/test.dart';
import 'package:maptogether_api/src/api.dart' as mt;
import 'package:maptogether_api/maptogether_api.dart' as mt;

void main() {
group('Maptogether reads', () {
Expand Down
40 changes: 28 additions & 12 deletions maptogether_api/test/data_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,35 @@ import 'package:maptogether_api/src/data.dart' as data;

void main() {
group('User', () {
var user = data.User(id: 1, score: 12, name: 'Jens', achievements: [
data.Achievement(
name: 'fdf',
description: 'Stuff',
)
], followers: [
data.SimpleUser(
var user = data.User(
id: 1,
name: 'Hej',
)
], following: [
data.SimpleUser(id: 2, name: 'Med')
]);
scoreAllTime: 12,
scoreMonthly: 5,
scoreWeekly: 2,
name: 'Jens',
achievements: [
data.Achievement(
name: 'fdf',
description: 'Stuff',
)
],
followers: [
data.SimpleUser(
id: 1,
name: 'Hej',
)
],
following: [
data.SimpleUser(id: 2, name: 'Med')
],
leaderboards: [
data.LeaderboardSummary(
path: "/leaderboard/all_time/global",
name: "Global",
rank: 1,
total: 20,
type: data.LeaderboardType.all_time)
]);

test('have', () => expect(user.followers.length, 1));
});
Expand Down
1 change: 1 addition & 0 deletions server.nix
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ in
containers.api = {
config = import ./api-server.nix { port = apiPort; inherit pkgs; };
autoStart = true;
ephemeral = true;
};
}
Loading