Better semantics for MemberActivity (#1)
Co-authored-by: Smaug123 <patrick+github@patrickstevens.co.uk> Reviewed-on: #1
This commit is contained in:
@@ -5,24 +5,45 @@ open System
|
|||||||
open PureGym
|
open PureGym
|
||||||
|
|
||||||
type GetTokenArg =
|
type GetTokenArg =
|
||||||
| [<ExactlyOnce>] User_Email of string
|
| [<Unique ; EqualsAssignmentOrSpaced>] User_Email of string
|
||||||
| [<ExactlyOnce>] Pin of string
|
| [<Unique ; EqualsAssignmentOrSpaced>] Pin of string
|
||||||
|
| [<Unique>] StdIn
|
||||||
|
|
||||||
interface IArgParserTemplate with
|
interface IArgParserTemplate with
|
||||||
member s.Usage =
|
member s.Usage =
|
||||||
match s with
|
match s with
|
||||||
| GetTokenArg.Pin _ -> "Eight-digit PureGym user's PIN"
|
| GetTokenArg.Pin _ -> "Eight-digit PureGym user's PIN"
|
||||||
| GetTokenArg.User_Email _ -> "PureGym user's email address"
|
| GetTokenArg.User_Email _ -> "PureGym user's email address"
|
||||||
|
| GetTokenArg.StdIn _ -> "Read anything not specified on the command line from stdin"
|
||||||
|
|
||||||
static member Parse (args : ParseResults<GetTokenArg>) : Result<UsernamePin, ArguParseException> =
|
static member Parse (args : ParseResults<GetTokenArg>) : Result<UsernamePin, ArguParseException> =
|
||||||
try
|
let canUseStdin = args.TryGetResult(GetTokenArg.StdIn).IsSome
|
||||||
{
|
|
||||||
Username = args.GetResult GetTokenArg.User_Email
|
let username =
|
||||||
Pin = args.GetResult GetTokenArg.Pin
|
match args.TryGetResult GetTokenArg.User_Email, canUseStdin with
|
||||||
}
|
| None, true ->
|
||||||
|> Ok
|
Console.Error.Write "Enter username: "
|
||||||
with :? ArguParseException as e ->
|
Console.ReadLine ()
|
||||||
Error e
|
| None, false ->
|
||||||
|
// TODO: proper exception handling, this should be surfaced through the Error
|
||||||
|
failwith "You must supply --user-email or --stdin"
|
||||||
|
| Some s, _ -> s
|
||||||
|
|
||||||
|
let pin =
|
||||||
|
match args.TryGetResult GetTokenArg.Pin, canUseStdin with
|
||||||
|
| None, true ->
|
||||||
|
Console.Error.Write "Enter eight-digit PIN: "
|
||||||
|
Console.ReadLine ()
|
||||||
|
| None, false ->
|
||||||
|
// TODO: proper exception handling, this should be surfaced through the Error
|
||||||
|
failwith "You must supply --pin or --stdin"
|
||||||
|
| Some s, _ -> s
|
||||||
|
|
||||||
|
{
|
||||||
|
Username = username
|
||||||
|
Pin = pin
|
||||||
|
}
|
||||||
|
|> Ok
|
||||||
|
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module Authenticate =
|
module Authenticate =
|
||||||
|
@@ -4,9 +4,9 @@ open Argu
|
|||||||
open PureGym
|
open PureGym
|
||||||
|
|
||||||
type FullnessArgsFragment =
|
type FullnessArgsFragment =
|
||||||
| [<Unique>] Gym_Id of int
|
| [<Unique ; EqualsAssignmentOrSpaced>] Gym_Id of int
|
||||||
| [<Unique>] Gym_Name of string
|
| [<Unique ; EqualsAssignmentOrSpaced>] Gym_Name of string
|
||||||
| [<Unique>] Terse of bool
|
| [<Unique ; EqualsAssignmentOrSpaced>] Terse of bool
|
||||||
|
|
||||||
interface IArgParserTemplate with
|
interface IArgParserTemplate with
|
||||||
member s.Usage =
|
member s.Usage =
|
||||||
|
@@ -4,8 +4,8 @@ open Argu
|
|||||||
open PureGym
|
open PureGym
|
||||||
|
|
||||||
type LookupGymArgsFragment =
|
type LookupGymArgsFragment =
|
||||||
| [<Unique>] Gym_Id of int
|
| [<Unique ; EqualsAssignmentOrSpaced>] Gym_Id of int
|
||||||
| [<Unique>] Gym_Name of string
|
| [<Unique ; EqualsAssignmentOrSpaced>] Gym_Name of string
|
||||||
|
|
||||||
interface IArgParserTemplate with
|
interface IArgParserTemplate with
|
||||||
member s.Usage =
|
member s.Usage =
|
||||||
|
@@ -33,6 +33,7 @@ module MemberActivity =
|
|||||||
task {
|
task {
|
||||||
let! client = Api.make args.Creds
|
let! client = Api.make args.Creds
|
||||||
let! activity = client.GetMemberActivity ()
|
let! activity = client.GetMemberActivity ()
|
||||||
System.Console.WriteLine (string<MemberActivity> activity)
|
let activity = activity.ToMemberActivity ()
|
||||||
|
System.Console.WriteLine (string<MemberActivityThisMonth> activity)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@@ -168,6 +168,7 @@ type Member =
|
|||||||
/// Statistics for how many people are currently at a gym
|
/// Statistics for how many people are currently at a gym
|
||||||
type GymAttendance =
|
type GymAttendance =
|
||||||
{
|
{
|
||||||
|
/// This appears always to be just equal to TotalPeopleInGym, but a string.
|
||||||
[<JsonRequired>]
|
[<JsonRequired>]
|
||||||
Description : string
|
Description : string
|
||||||
/// How many people are in the gym as of this statistics snapshot
|
/// How many people are in the gym as of this statistics snapshot
|
||||||
@@ -207,25 +208,55 @@ type GymAttendance =
|
|||||||
$"\n%i{this.TotalPeopleInClasses} in classes"
|
$"\n%i{this.TotalPeopleInClasses} in classes"
|
||||||
|
|
||||||
$"""%i{this.TotalPeopleInGym} in gym%s{capacity} (is exact: %c{Char.emoji (not this.IsApproximate)})%s{classes}
|
$"""%i{this.TotalPeopleInGym} in gym%s{capacity} (is exact: %c{Char.emoji (not this.IsApproximate)})%s{classes}
|
||||||
Query made at %s{this.AttendanceTime.ToString ("s")}%s{this.AttendanceTime.ToString ("zzz")}
|
Query made at %s{this.AttendanceTime.ToString "s"}%s{this.AttendanceTime.ToString "zzz"}
|
||||||
Snapshot correct as of %s{this.LastRefreshed.ToString ("s")}%s{this.LastRefreshed.ToString ("zzz")}
|
Snapshot correct as of %s{this.LastRefreshed.ToString "s"}%s{this.LastRefreshed.ToString "zzz"}
|
||||||
Classes info correct as of %s{this.LastRefreshedPeopleInClasses.ToString ("s")}%s{this.LastRefreshedPeopleInClasses.ToString ("zzz")}"""
|
Classes info correct as of %s{this.LastRefreshedPeopleInClasses.ToString "s"}%s{this.LastRefreshedPeopleInClasses.ToString "zzz"}"""
|
||||||
|
|
||||||
/// The visit statistics for a particular human to a particular gym.
|
/// The visit statistics for a particular human to a particular gym.
|
||||||
/// The semantics of this class are basically unknown.
|
/// The semantics of this class are basically unknown.
|
||||||
type MemberActivity =
|
type MemberActivityThisMonth =
|
||||||
{
|
{
|
||||||
/// ??? semantics unknown; this was 2852 for me
|
/// How many minutes, including classes, have been logged so far this month
|
||||||
[<JsonPropertyName "totalDuration">]
|
|
||||||
TotalDurationMinutes : int
|
TotalDurationMinutes : int
|
||||||
[<JsonPropertyName "averageDuration">]
|
/// How long, in minutes, each visit has been on average this month
|
||||||
AverageDurationMinutes : int
|
AverageDurationMinutes : int
|
||||||
|
/// How many visits have been made this month, excluding classes
|
||||||
TotalVisits : int
|
TotalVisits : int
|
||||||
|
/// How many classes have been attended this month
|
||||||
TotalClasses : int
|
TotalClasses : int
|
||||||
|
/// Whether this block of statistics is estimated rather than exact
|
||||||
IsEstimated : bool
|
IsEstimated : bool
|
||||||
|
/// When this data was constructed
|
||||||
LastRefreshed : DateTime
|
LastRefreshed : DateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Don't use this type. It's public because System.Text.Json can't do private types.
|
||||||
|
type MemberActivityDto =
|
||||||
|
{
|
||||||
|
[<JsonRequired>]
|
||||||
|
TotalDuration : int
|
||||||
|
[<JsonRequired>]
|
||||||
|
AverageDuration : int
|
||||||
|
[<JsonRequired>]
|
||||||
|
TotalVisits : int
|
||||||
|
[<JsonRequired>]
|
||||||
|
TotalClasses : int
|
||||||
|
[<JsonRequired>]
|
||||||
|
IsEstimated : bool
|
||||||
|
[<JsonRequired>]
|
||||||
|
LastRefreshed : DateTime
|
||||||
|
}
|
||||||
|
|
||||||
|
member this.ToMemberActivity () =
|
||||||
|
{
|
||||||
|
TotalDurationMinutes = this.TotalDuration
|
||||||
|
AverageDurationMinutes = this.AverageDuration
|
||||||
|
TotalVisits = this.TotalVisits
|
||||||
|
TotalClasses = this.TotalClasses
|
||||||
|
IsEstimated = this.IsEstimated
|
||||||
|
LastRefreshed = this.LastRefreshed
|
||||||
|
}
|
||||||
|
|
||||||
/// The PureGym REST API. You probably want to instantiate one of these with `Api.make`.
|
/// The PureGym REST API. You probably want to instantiate one of these with `Api.make`.
|
||||||
[<Header("User-Agent", "PureGym/1523 CFNetwork/1312 Darwin/21.0.0")>]
|
[<Header("User-Agent", "PureGym/1523 CFNetwork/1312 Darwin/21.0.0")>]
|
||||||
type IPureGymApi =
|
type IPureGymApi =
|
||||||
@@ -247,7 +278,10 @@ type IPureGymApi =
|
|||||||
|
|
||||||
/// Get information about the activities logged against the currently authenticated PureGym human.
|
/// Get information about the activities logged against the currently authenticated PureGym human.
|
||||||
[<Get "v1/member/activity">]
|
[<Get "v1/member/activity">]
|
||||||
abstract GetMemberActivity : unit -> Task<MemberActivity>
|
abstract GetMemberActivity : unit -> Task<MemberActivityDto>
|
||||||
|
|
||||||
|
// [<Get "v1/member/activity/history">]
|
||||||
|
// abstract GetMemberActivityAll : unit -> Task<string>
|
||||||
|
|
||||||
/// Methods for interacting with the PureGym REST API.
|
/// Methods for interacting with the PureGym REST API.
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
|
@@ -143,7 +143,7 @@ PureGym.IPureGymApi.GetGym [method]: int -> PureGym.Gym System.Threading.Tasks.T
|
|||||||
PureGym.IPureGymApi.GetGymAttendance [method]: int -> PureGym.GymAttendance System.Threading.Tasks.Task
|
PureGym.IPureGymApi.GetGymAttendance [method]: int -> PureGym.GymAttendance System.Threading.Tasks.Task
|
||||||
PureGym.IPureGymApi.GetGyms [method]: unit -> PureGym.Gym list System.Threading.Tasks.Task
|
PureGym.IPureGymApi.GetGyms [method]: unit -> PureGym.Gym list System.Threading.Tasks.Task
|
||||||
PureGym.IPureGymApi.GetMember [method]: unit -> PureGym.Member System.Threading.Tasks.Task
|
PureGym.IPureGymApi.GetMember [method]: unit -> PureGym.Member System.Threading.Tasks.Task
|
||||||
PureGym.IPureGymApi.GetMemberActivity [method]: unit -> PureGym.MemberActivity System.Threading.Tasks.Task
|
PureGym.IPureGymApi.GetMemberActivity [method]: unit -> PureGym.MemberActivityDto System.Threading.Tasks.Task
|
||||||
PureGym.Member inherit obj, implements PureGym.Member System.IEquatable, System.Collections.IStructuralEquatable, PureGym.Member System.IComparable, System.IComparable, System.Collections.IStructuralComparable
|
PureGym.Member inherit obj, implements PureGym.Member System.IEquatable, System.Collections.IStructuralEquatable, PureGym.Member System.IComparable, System.IComparable, System.Collections.IStructuralComparable
|
||||||
PureGym.Member..ctor [constructor]: (int, string, string, string, int, string, string, string, System.DateOnly, string, string, string, int, int, int)
|
PureGym.Member..ctor [constructor]: (int, string, string, string, int, string, string, string, System.DateOnly, string, string, string, int, int, int)
|
||||||
PureGym.Member.CompoundMemberId [property]: [read-only] string
|
PureGym.Member.CompoundMemberId [property]: [read-only] string
|
||||||
@@ -176,20 +176,35 @@ PureGym.Member.MemberStatus [property]: [read-only] int
|
|||||||
PureGym.Member.MobileNumber [property]: [read-only] string
|
PureGym.Member.MobileNumber [property]: [read-only] string
|
||||||
PureGym.Member.Postcode [property]: [read-only] string
|
PureGym.Member.Postcode [property]: [read-only] string
|
||||||
PureGym.Member.SuspendedReason [property]: [read-only] int
|
PureGym.Member.SuspendedReason [property]: [read-only] int
|
||||||
PureGym.MemberActivity inherit obj, implements PureGym.MemberActivity System.IEquatable, System.Collections.IStructuralEquatable, PureGym.MemberActivity System.IComparable, System.IComparable, System.Collections.IStructuralComparable
|
PureGym.MemberActivityDto inherit obj, implements PureGym.MemberActivityDto System.IEquatable, System.Collections.IStructuralEquatable, PureGym.MemberActivityDto System.IComparable, System.IComparable, System.Collections.IStructuralComparable
|
||||||
PureGym.MemberActivity..ctor [constructor]: (int, int, int, int, bool, System.DateTime)
|
PureGym.MemberActivityDto..ctor [constructor]: (int, int, int, int, bool, System.DateTime)
|
||||||
PureGym.MemberActivity.AverageDurationMinutes [property]: [read-only] int
|
PureGym.MemberActivityDto.AverageDuration [property]: [read-only] int
|
||||||
PureGym.MemberActivity.get_AverageDurationMinutes [method]: unit -> int
|
PureGym.MemberActivityDto.get_AverageDuration [method]: unit -> int
|
||||||
PureGym.MemberActivity.get_IsEstimated [method]: unit -> bool
|
PureGym.MemberActivityDto.get_IsEstimated [method]: unit -> bool
|
||||||
PureGym.MemberActivity.get_LastRefreshed [method]: unit -> System.DateTime
|
PureGym.MemberActivityDto.get_LastRefreshed [method]: unit -> System.DateTime
|
||||||
PureGym.MemberActivity.get_TotalClasses [method]: unit -> int
|
PureGym.MemberActivityDto.get_TotalClasses [method]: unit -> int
|
||||||
PureGym.MemberActivity.get_TotalDurationMinutes [method]: unit -> int
|
PureGym.MemberActivityDto.get_TotalDuration [method]: unit -> int
|
||||||
PureGym.MemberActivity.get_TotalVisits [method]: unit -> int
|
PureGym.MemberActivityDto.get_TotalVisits [method]: unit -> int
|
||||||
PureGym.MemberActivity.IsEstimated [property]: [read-only] bool
|
PureGym.MemberActivityDto.IsEstimated [property]: [read-only] bool
|
||||||
PureGym.MemberActivity.LastRefreshed [property]: [read-only] System.DateTime
|
PureGym.MemberActivityDto.LastRefreshed [property]: [read-only] System.DateTime
|
||||||
PureGym.MemberActivity.TotalClasses [property]: [read-only] int
|
PureGym.MemberActivityDto.ToMemberActivity [method]: unit -> PureGym.MemberActivityThisMonth
|
||||||
PureGym.MemberActivity.TotalDurationMinutes [property]: [read-only] int
|
PureGym.MemberActivityDto.TotalClasses [property]: [read-only] int
|
||||||
PureGym.MemberActivity.TotalVisits [property]: [read-only] int
|
PureGym.MemberActivityDto.TotalDuration [property]: [read-only] int
|
||||||
|
PureGym.MemberActivityDto.TotalVisits [property]: [read-only] int
|
||||||
|
PureGym.MemberActivityThisMonth inherit obj, implements PureGym.MemberActivityThisMonth System.IEquatable, System.Collections.IStructuralEquatable, PureGym.MemberActivityThisMonth System.IComparable, System.IComparable, System.Collections.IStructuralComparable
|
||||||
|
PureGym.MemberActivityThisMonth..ctor [constructor]: (int, int, int, int, bool, System.DateTime)
|
||||||
|
PureGym.MemberActivityThisMonth.AverageDurationMinutes [property]: [read-only] int
|
||||||
|
PureGym.MemberActivityThisMonth.get_AverageDurationMinutes [method]: unit -> int
|
||||||
|
PureGym.MemberActivityThisMonth.get_IsEstimated [method]: unit -> bool
|
||||||
|
PureGym.MemberActivityThisMonth.get_LastRefreshed [method]: unit -> System.DateTime
|
||||||
|
PureGym.MemberActivityThisMonth.get_TotalClasses [method]: unit -> int
|
||||||
|
PureGym.MemberActivityThisMonth.get_TotalDurationMinutes [method]: unit -> int
|
||||||
|
PureGym.MemberActivityThisMonth.get_TotalVisits [method]: unit -> int
|
||||||
|
PureGym.MemberActivityThisMonth.IsEstimated [property]: [read-only] bool
|
||||||
|
PureGym.MemberActivityThisMonth.LastRefreshed [property]: [read-only] System.DateTime
|
||||||
|
PureGym.MemberActivityThisMonth.TotalClasses [property]: [read-only] int
|
||||||
|
PureGym.MemberActivityThisMonth.TotalDurationMinutes [property]: [read-only] int
|
||||||
|
PureGym.MemberActivityThisMonth.TotalVisits [property]: [read-only] int
|
||||||
PureGym.UsernamePin inherit obj, implements PureGym.UsernamePin System.IEquatable, System.Collections.IStructuralEquatable, PureGym.UsernamePin System.IComparable, System.IComparable, System.Collections.IStructuralComparable
|
PureGym.UsernamePin inherit obj, implements PureGym.UsernamePin System.IEquatable, System.Collections.IStructuralEquatable, PureGym.UsernamePin System.IComparable, System.IComparable, System.Collections.IStructuralComparable
|
||||||
PureGym.UsernamePin..ctor [constructor]: (string, string)
|
PureGym.UsernamePin..ctor [constructor]: (string, string)
|
||||||
PureGym.UsernamePin.get_Pin [method]: unit -> string
|
PureGym.UsernamePin.get_Pin [method]: unit -> string
|
||||||
|
Reference in New Issue
Block a user