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

Updates to facilitate production usage of webhooks and workout data from Concept2 #9

Open
wants to merge 45 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e2d321a
Update c2logbook.dart
pfredCL Mar 7, 2024
146463a
Merge pull request #1 from OpenRowingCommunity/main
pfredCL Mar 11, 2024
2f8c3b5
We need these
pfredCL Mar 11, 2024
76303b6
Biiiiig refactor
pfredCL Mar 11, 2024
13aa69e
Anotha one
pfredCL Mar 12, 2024
54e9bf8
Parsing support added for full c2 results
pfredCL Mar 12, 2024
3559304
Added rest time
pfredCL Mar 12, 2024
e31c402
Fixed some errors that occur on docker compose up in crewlab
pfredCL Mar 12, 2024
5c2b68f
Fixed some errors that occur on docker compose up in crewlab
pfredCL Mar 12, 2024
9da62a4
I swear I fixed this wtf
pfredCL Mar 12, 2024
6f0787b
More tweaking of models
pfredCL Mar 12, 2024
1594270
More tweaking of models
pfredCL Mar 12, 2024
f2ecf3c
More tweaking of models
pfredCL Mar 12, 2024
8177406
More tweaking of models
pfredCL Mar 12, 2024
4aa321c
Re-added json keys
pfredCL Mar 12, 2024
b9b4eba
More model alterations
pfredCL Mar 12, 2024
a26ca1a
Alright no more mr nice guy
pfredCL Mar 12, 2024
81f1731
Alright no more mr nice guy
pfredCL Mar 12, 2024
ea413e0
Alright no more mr nice guy
pfredCL Mar 12, 2024
9c93cb5
Alright no more mr nice guy
pfredCL Mar 12, 2024
6371c93
Alright no more mr nice guy
pfredCL Mar 12, 2024
a6a124a
Alright no more mr nice guy
pfredCL Mar 12, 2024
8c437a3
Alright no more mr nice guy
pfredCL Mar 12, 2024
847a587
Alright no more mr nice guy
pfredCL Mar 12, 2024
81820c0
Alright no more mr nice guy
pfredCL Mar 12, 2024
8acef32
Refactored and simplified file structure and added data models for in…
pfredCL Mar 18, 2024
5ac9574
run dart format
MoralCode Mar 25, 2024
db9876c
breaking change: date -> endDate to match the main branch
MoralCode Jun 15, 2024
1cadec9
update tests and freezed outputs for date -> endDate change
MoralCode Jun 22, 2024
5ed6f7f
fix multiple import with tests
MoralCode Jun 22, 2024
721edff
reintroduce JSON keys for c2 user
MoralCode Jun 22, 2024
c44b85f
update freezed types
MoralCode Jun 22, 2024
43594ce
dart format
MoralCode Jun 22, 2024
3aced67
adding source citations to tests
MoralCode Jun 22, 2024
72baa11
add testcase to parse concept2's result JSON
MoralCode Jun 22, 2024
b0400a8
move webhook parsing test into the parsing group
MoralCode Jun 22, 2024
3832974
date -> endDate for C2FullResults as well
MoralCode Jun 22, 2024
9b8223e
merge C2FullResults into C2Results
MoralCode Jun 22, 2024
c64b644
reintroduce deleted types with deprecation warning
MoralCode Jul 14, 2024
b53f67a
commit freezed types
MoralCode Jul 14, 2024
81e8a82
add the real data sample to the unit tests
MoralCode Jun 22, 2024
96de7ea
add some additional fields to handle items in the data sample
MoralCode Jun 22, 2024
d0dea7c
generate freezed data for additional fields added during testing
MoralCode Jul 14, 2024
df2b242
typo
MoralCode Jul 14, 2024
a636f1f
C2DetailedResult is not a webhook parser, it just grabs ['data'] like…
MoralCode Jul 14, 2024
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
14 changes: 14 additions & 0 deletions build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
targets:
$default:
builders:
json_serializable:
generate_for:
- "**/types/**.dart"
options:
explicit_to_json: true
freezed:
generate_for:
- "**/types/**.dart"
options:
maybe_when: false
maybe_map: false
50 changes: 41 additions & 9 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.0.2"
version: "0.0.5"
characters:
dependency: transitive
description:
Expand Down Expand Up @@ -122,6 +122,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.8.1"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
url: "https://pub.dev"
source: hosted
version: "10.0.0"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
url: "https://pub.dev"
source: hosted
version: "2.0.1"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
url: "https://pub.dev"
source: hosted
version: "2.0.1"
lints:
dependency: transitive
description:
Expand All @@ -134,26 +158,26 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.dev"
source: hosted
version: "0.12.16"
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
version: "0.8.0"
meta:
dependency: transitive
description:
name: meta
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
url: "https://pub.dev"
source: hosted
version: "1.10.0"
version: "1.11.0"
nested:
dependency: transitive
description:
Expand All @@ -174,10 +198,10 @@ packages:
dependency: transitive
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
version: "1.9.0"
provider:
dependency: "direct main"
description:
Expand Down Expand Up @@ -255,6 +279,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
url: "https://pub.dev"
source: hosted
version: "13.0.0"
web:
dependency: transitive
description:
Expand Down
5 changes: 1 addition & 4 deletions lib/c2logbook.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
library;

export 'src/c2logbook_base.dart';
export 'src/types/c2_user.dart';
export 'src/types/c2_types.dart';
export 'src/types/c2_results.dart';
export 'src/types/c2_webhook_result.dart';
export 'src/types/index.dart';

// TODO: Export any libraries intended for clients of this package.
1 change: 1 addition & 0 deletions lib/src/c2logbook_base.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:convert';
import 'types/index.dart';

import 'package:oauth2/oauth2.dart' as oauth2;
import 'package:http/http.dart' as http;
Expand Down
13 changes: 13 additions & 0 deletions lib/src/types/c2_detailed_result.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
part of 'index.dart';

@Deprecated(
'This class will soon be removed. Please use methods on [C2Logbook] or manually pick out the `data` key from the Concept2 API response and feed it into [C2Results.fromJson] yourself')
class C2DetailedResult {
/// Parse the data from incoming webhooks from the Concept2 API.
///
/// Currently this only supports webhook data representing new workouts that have been added
static C2FullResults? parse(Map<String, dynamic> jsonBody) {
final Map<String, dynamic> jsonBodyData = jsonBody["data"];
return C2FullResults.fromJson(jsonBodyData);
}
}
41 changes: 41 additions & 0 deletions lib/src/types/c2_full_results.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// ignore_for_file: invalid_annotation_target

part of 'index.dart';

@Deprecated('This class will soon be removed in favor of [C2Results]')
@freezed
class C2FullResults with _$C2FullResults {
C2FullResults._();

factory C2FullResults({
@JsonKey(name: 'id') @Default(0) int id,
@JsonKey(name: 'user_id') @Default(0) int userId,
@JsonKey(name: 'date') @TimestampConverter() required DateTime date,
@JsonKey(name: 'timezone') String? timezone,
@JsonKey(name: 'date_utc') @TimestampOrNullConverter() DateTime? dateUtc,
@JsonKey(name: 'distance') @Default(0) int distance,
@JsonKey(name: 'type') @Default(C2ResultType.rower) C2ResultType type,
@JsonKey(name: 'time') @DecimalIntConverter.tenths() required double time,
@JsonKey(name: 'workout_type')
@Default(C2APIWorkoutType.JustRow)
C2APIWorkoutType workoutType,
@JsonKey(name: 'source') @Default("c2logbook dart") String source,
@JsonKey(name: 'weight_class')
@Default(C2WeightClass.heavyweight)
C2WeightClass weightClass,
@JsonKey(name: 'verified') @Default(false) bool verified,
@JsonKey(name: 'ranked') @Default(false) bool ranked,
@JsonKey(name: 'comments') String? comments,
@JsonKey(name: 'privacy')
@Default(C2PrivacyLevel.private)
C2PrivacyLevel privacy,
@JsonKey(name: 'rest_time') @DecimalIntConverter.tenths() double? restTime,
@JsonKey(name: 'stroke_rate') int? strokeRate,
@JsonKey(name: 'heart_rate') @Default(null) C2HeartRate? heartRate,
@JsonKey(name: 'workout') @Default(null) C2Workout? workout,
@JsonKey(name: 'rest_distance') @Default(0.0) double restDistance,
}) = _C2FullResults;

factory C2FullResults.fromJson(Map<dynamic, dynamic> json) =>
_$C2FullResultsFromJson(Map<String, dynamic>.from(json));
}
18 changes: 18 additions & 0 deletions lib/src/types/c2_heart_rate.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// ignore_for_file: invalid_annotation_target

part of 'index.dart';

@freezed
class C2HeartRate with _$C2HeartRate {
C2HeartRate._();

factory C2HeartRate(
{@JsonKey(name: 'min') @Default(0) int min,
@JsonKey(name: 'average') @Default(0) int average,
@JsonKey(name: 'max') @Default(0) int max,
@JsonKey(name: 'ending') @Default(0) int ending,
@JsonKey(name: 'rest') @Default(0) int rest}) = _C2HeartRate;

factory C2HeartRate.fromJson(Map<dynamic, dynamic> json) =>
_$C2HeartRateFromJson(Map<String, dynamic>.from(json));
}
24 changes: 24 additions & 0 deletions lib/src/types/c2_intervals.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// ignore_for_file: invalid_annotation_target

part of 'index.dart';

@freezed
class C2Intervals with _$C2Intervals {
C2Intervals._();

factory C2Intervals({
@JsonKey(name: 'id') @Default("type") String? type,
@JsonKey(name: 'time') @DecimalIntConverter.tenths() required double time,
@JsonKey(name: 'rest_time')
@DecimalIntConverter.tenths()
required double restTime,
@JsonKey(name: 'distance') @Default(0.0) double distance,
@JsonKey(name: 'calories_total') @Default(0) int caloriesTotal,
@JsonKey(name: 'stroke_rate') @Default(0) int strokeRate,
@JsonKey(name: 'heart_rate') @Default(null) C2HeartRate? heartRate,
@JsonKey(name: 'rest_distance') @Default(null) int? restDistance,
}) = _C2Intervals;

factory C2Intervals.fromJson(Map<dynamic, dynamic> json) =>
_$C2IntervalsFromJson(Map<String, dynamic>.from(json));
}
51 changes: 28 additions & 23 deletions lib/src/types/c2_results.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
// ignore_for_file: invalid_annotation_target

import 'c2_types.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

import '../utils.dart';

part 'c2_results.freezed.dart';
part 'c2_results.g.dart';
part of 'index.dart';

@freezed
class C2Results with _$C2Results {
Expand All @@ -20,26 +14,37 @@ class C2Results with _$C2Results {
C2Results._();

factory C2Results({
@Default(0) int id,
@JsonKey(name: "user_id") @Default(0) int userId,
@JsonKey(name: "date") @TimestampConverter() required DateTime endDate,
@JsonKey(name: "date_utc") @TimestampOrNullConverter() DateTime? dateUtc,
String? timezone,
@Default(0) int distance,
@Default(C2ResultType.rower) C2ResultType type,
@DecimalIntConverter.tenths() required double time,
@JsonKey(name: "workout_type")
@JsonKey(name: 'id') @Default(0) int id,
@JsonKey(name: 'user_id') @Default(0) int userId,
@JsonKey(name: 'date') @TimestampConverter() required DateTime endDate,
@JsonKey(name: 'date_utc') @TimestampOrNullConverter() DateTime? dateUtc,
@JsonKey(name: 'timezone') String? timezone,
@JsonKey(name: 'distance') @Default(0) int distance,
@JsonKey(name: 'type') @Default(C2ResultType.rower) C2ResultType type,
@JsonKey(name: 'time') @DecimalIntConverter.tenths() required double time,
@JsonKey(name: 'workout_type')
@Default(C2APIWorkoutType.JustRow)
C2APIWorkoutType workoutType,
@Default("c2logbook dart") String source,
@JsonKey(name: "weight_class")
@JsonKey(name: 'source') @Default("c2logbook dart") String source,
@JsonKey(name: 'weight_class')
@Default(C2WeightClass.heavyweight)
C2WeightClass weightClass,
@JsonKey(name: "stroke_rate") int? strokeRate,
@Default(false) bool verified,
@Default(false) bool ranked,
String? comments,
@Default(C2PrivacyLevel.private) C2PrivacyLevel privacy,
@JsonKey(name: 'stroke_rate') @Default(null) int? strokeRate,
@JsonKey(name: 'heart_rate') @Default(null) C2HeartRate? heartRate,
@JsonKey(name: 'calories_total') @Default(0) int caloriesTotal,
@JsonKey(name: 'drag_factor') @Default(0) int dragFactor,
@JsonKey(name: 'stroke_count') @Default(0) int strokeCount,
@JsonKey(name: 'workout') @Default(null) C2Workout? workout,
// REQUIRED/FOR INTERVAL WORKOUTS ONLY
@JsonKey(name: 'rest_distance') @Default(0.0) double restDistance,
@JsonKey(name: 'rest_time') @DecimalIntConverter.tenths() double? restTime,
// END REQUIRED/FOR INTERVAL WORKOUTS ONLY
@JsonKey(name: 'verified') @Default(false) bool verified,
@JsonKey(name: 'ranked') @Default(false) bool ranked,
@JsonKey(name: 'comments') @Default(null) String? comments,
@JsonKey(name: 'privacy')
@Default(C2PrivacyLevel.private)
C2PrivacyLevel privacy,
}) = _C2Results;

factory C2Results.fromJson(Map<dynamic, dynamic> json) =>
Expand Down
Loading
Loading