331 lines
11 KiB
Go
331 lines
11 KiB
Go
|
|
// myDesireStatistics provides functions to calculate a user's mate desire statistics
|
|
// These are statistics about a user's mate desires.
|
|
// For each desire, we calculate:
|
|
// -The number/percentage of all downloaded profiles who pass the desire
|
|
// -The number/percentage of a user's matches who pass the desire (excluding the desire)
|
|
|
|
package myDesireStatistics
|
|
|
|
//TODO: Add desire statistics about how many users fulfill each desire
|
|
// This would enable users to view fulfillment statistics without requiring them to enable FilterAll and RequireResponse for each desire
|
|
|
|
import "seekia/internal/appMemory"
|
|
import "seekia/internal/badgerDatabase"
|
|
import "seekia/internal/desires/myMateDesires"
|
|
import "seekia/internal/helpers"
|
|
import "seekia/internal/myBlockedUsers"
|
|
import "seekia/internal/myIdentity"
|
|
import "seekia/internal/profiles/viewableProfiles"
|
|
|
|
import "errors"
|
|
|
|
//Outputs:
|
|
// -int64: Number of downloaded mate identities with a viewable profile
|
|
// -int64: Number of mate identities whose viewable profile passes desire
|
|
// -float64: Percentage of all mate identities whose viewable profile passes desire
|
|
// -int64: Number of matches (Excluding input desire)
|
|
// -int64: Number of matches
|
|
// -float64: Percentage of all matches (excluding input desire) that pass input desire
|
|
// -error
|
|
func GetMyDesireStatistics(desireName string, networkType byte)(int64, int64, float64, int64, int64, float64, error){
|
|
|
|
isValid := helpers.VerifyNetworkType(networkType)
|
|
if (isValid == false){
|
|
networkTypeString := helpers.ConvertByteToString(networkType)
|
|
return 0, 0, 0, 0, 0, 0, errors.New("GetMyDesireStatistics called with invalid networkType: " + networkTypeString)
|
|
}
|
|
|
|
myIdentityExists, myIdentityHash, err := myIdentity.GetMyIdentityHash("Mate")
|
|
if (err != nil) { return 0, 0, 0, 0, 0, 0, err }
|
|
|
|
mateIdentityHashesList, err := badgerDatabase.GetAllProfileIdentityHashes("Mate")
|
|
if (err != nil) { return 0, 0, 0, 0, 0, 0, err }
|
|
|
|
numberOfMateIdentities := int64(0)
|
|
numberOfMateIdentitiesWhoPassDesire := int64(0)
|
|
numberOfMatches := int64(0)
|
|
numberOfMatchesExcludingDesire := int64(0)
|
|
|
|
for _, peerIdentityHash := range mateIdentityHashesList{
|
|
|
|
if (myIdentityExists == true && peerIdentityHash == myIdentityHash){
|
|
continue
|
|
}
|
|
|
|
userIsBlocked, _, _, _, err := myBlockedUsers.CheckIfUserIsBlocked(peerIdentityHash)
|
|
if (err != nil) { return 0, 0, 0, 0, 0, 0, err }
|
|
if (userIsBlocked == true){
|
|
// We don't include blocked users in our statistics calculation
|
|
// This is because "Blocked" is not a desire, so it won't be shown on the Desire Statistics page
|
|
// We show the user how many users they have blocked on the Match Statistics page
|
|
continue
|
|
}
|
|
|
|
profileExists, _, getAnyProfileAttributeFunction, err := viewableProfiles.GetRetrieveAnyNewestViewableUserProfileAttributeFunction(peerIdentityHash, networkType, true, false, true)
|
|
if (err != nil) { return 0, 0, 0, 0, 0, 0, err }
|
|
if (profileExists == false) {
|
|
// Profile must have been deleted, or user's profile is not viewable
|
|
continue
|
|
}
|
|
|
|
exists, _, _, err := getAnyProfileAttributeFunction("Disabled")
|
|
if (err != nil) { return 0, 0, 0, 0, 0, 0, err }
|
|
if (exists == true){
|
|
// Profile is disabled
|
|
continue
|
|
}
|
|
|
|
numberOfMateIdentities += 1
|
|
|
|
userPassesMyDesire, err := myMateDesires.CheckIfMateProfilePassesMyDesire(desireName, getAnyProfileAttributeFunction)
|
|
if (err != nil) { return 0, 0, 0, 0, 0, 0, err }
|
|
if (userPassesMyDesire == true){
|
|
numberOfMateIdentitiesWhoPassDesire += 1
|
|
}
|
|
|
|
userIsAMatchExcludingDesire, err := myMateDesires.CheckIfMateProfilePassesAllMyDesires(true, desireName, getAnyProfileAttributeFunction)
|
|
if (err != nil) { return 0, 0, 0, 0, 0, 0, err }
|
|
if (userIsAMatchExcludingDesire == false){
|
|
continue
|
|
}
|
|
numberOfMatchesExcludingDesire += 1
|
|
|
|
if (userPassesMyDesire == true){
|
|
numberOfMatches += 1
|
|
}
|
|
}
|
|
|
|
getPercentageOfMateIdentitiesWhoPassDesire := func()float64{
|
|
if (numberOfMateIdentities == 0){
|
|
return 0
|
|
}
|
|
percentageOfMateIdentitiesWhoPassDesire := 100 * (float64(numberOfMateIdentitiesWhoPassDesire)/float64(numberOfMateIdentities))
|
|
|
|
return percentageOfMateIdentitiesWhoPassDesire
|
|
}
|
|
|
|
percentageOfMateIdentitiesWhoPassDesire := getPercentageOfMateIdentitiesWhoPassDesire()
|
|
|
|
getPercentageOfMatchesWhoPassDesire := func()float64{
|
|
if (numberOfMatchesExcludingDesire == 0){
|
|
return 0
|
|
}
|
|
percentageOfMatchesWhoPassDesire := 100 * (float64(numberOfMatches)/float64(numberOfMatchesExcludingDesire))
|
|
|
|
return percentageOfMatchesWhoPassDesire
|
|
}
|
|
|
|
percentageOfMatchesWhoPassDesire := getPercentageOfMatchesWhoPassDesire()
|
|
|
|
return numberOfMateIdentities, numberOfMateIdentitiesWhoPassDesire, percentageOfMateIdentitiesWhoPassDesire, numberOfMatchesExcludingDesire, numberOfMatches, percentageOfMatchesWhoPassDesire, nil
|
|
}
|
|
|
|
|
|
type DesireStatisticsItem struct{
|
|
|
|
// Example: "Age"
|
|
DesireName string
|
|
|
|
// This is the number of mate identities who pass the desire
|
|
// Their newest viewable profile is used to check if they pass the desire
|
|
NumberOfUsersWhoPassDesire int64
|
|
|
|
// This is the percentage of mate identities who pass the desire
|
|
// Blocked and disabled users are excluded from the denominator.
|
|
PercentageOfUsersWhoPassDesire float64
|
|
|
|
// This is the number of matches the user would have if this desire was excluded
|
|
NumberOfDesireExcludedMatches int64
|
|
|
|
// This is the percentage of desire-excluded matches who pass this desire
|
|
PercentageOfDesireExcludedMatchesWhoPassDesire float64
|
|
}
|
|
|
|
//Outputs:
|
|
// -int64: Number of mate identities
|
|
// -int64: Number of matches
|
|
// -[]DesireStatisticsItem
|
|
// -error
|
|
func GetAllMyDesireStatistics(progressIdentifier string, networkType byte)(int64, int64, []DesireStatisticsItem, error){
|
|
|
|
isValid := helpers.VerifyNetworkType(networkType)
|
|
if (isValid == false){
|
|
networkTypeString := helpers.ConvertByteToString(networkType)
|
|
return 0, 0, nil, errors.New("GetAllMyDesireStatistics called with invalid networkType: " + networkTypeString)
|
|
}
|
|
|
|
myIdentityExists, myIdentityHash, err := myIdentity.GetMyIdentityHash("Mate")
|
|
if (err != nil) { return 0, 0, nil, err }
|
|
|
|
mateIdentityHashesList, err := badgerDatabase.GetAllProfileIdentityHashes("Mate")
|
|
if (err != nil) { return 0, 0, nil, err }
|
|
|
|
numberOfPeerIdentitiesString := helpers.ConvertIntToString(len(mateIdentityHashesList))
|
|
|
|
numberOfMateIdentities := int64(0)
|
|
numberOfMatches := int64(0)
|
|
|
|
//Map Structure: Desire name -> Number of mate identities who pass desire
|
|
numberOfMateIdentitiesWhoPassDesireMap := make(map[string]int64)
|
|
|
|
//Map Structure: Desire name -> Number of matches the user would have excluding the desire
|
|
numberOfDesireExcludedMatchesMap := make(map[string]int64)
|
|
|
|
for index, peerIdentityHash := range mateIdentityHashesList{
|
|
|
|
progressIndex := helpers.ConvertIntToString(index + 1)
|
|
newProgressString := "Calculated " + progressIndex + "/" + numberOfPeerIdentitiesString + " Users"
|
|
appMemory.SetMemoryEntry(progressIdentifier, newProgressString)
|
|
|
|
if (myIdentityExists == true && peerIdentityHash == myIdentityHash){
|
|
continue
|
|
}
|
|
|
|
userIsBlocked, _, _, _, err := myBlockedUsers.CheckIfUserIsBlocked(peerIdentityHash)
|
|
if (err != nil) { return 0, 0, nil, err }
|
|
if (userIsBlocked == true){
|
|
// We don't include blocked users in our statistics calculation
|
|
// This is because "Blocked" is not a desire, so it won't be shown on the Desire Statistics page
|
|
// We show the user how many users they have blocked on the Match Statistics page
|
|
continue
|
|
}
|
|
|
|
profileExists, _, getAnyProfileAttributeFunction, err := viewableProfiles.GetRetrieveAnyNewestViewableUserProfileAttributeFunction(peerIdentityHash, networkType, true, false, true)
|
|
if (err != nil) { return 0, 0, nil, err }
|
|
if (profileExists == false) {
|
|
// Profile must have been deleted, or user's profile is not viewable
|
|
continue
|
|
}
|
|
|
|
exists, _, _, err := getAnyProfileAttributeFunction("Disabled")
|
|
if (err != nil) { return 0, 0, nil, err }
|
|
if (exists == true){
|
|
// Profile is disabled
|
|
continue
|
|
}
|
|
|
|
numberOfMateIdentities += 1
|
|
|
|
userPassesMyDesiresMap, err := myMateDesires.GetMateProfilePassesAllMyDesiresMap(getAnyProfileAttributeFunction)
|
|
if (err != nil) { return 0, 0, nil, err }
|
|
|
|
getUserIsAMatchBool := func()bool{
|
|
|
|
for _, userPassesDesire := range userPassesMyDesiresMap{
|
|
if (userPassesDesire == false){
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
userIsAMatch := getUserIsAMatchBool()
|
|
if (userIsAMatch == true){
|
|
numberOfMatches += 1
|
|
}
|
|
|
|
for desireName, userPassesDesire := range userPassesMyDesiresMap{
|
|
|
|
if (userPassesDesire == true){
|
|
|
|
numberOfMateIdentitiesWhoPassDesireMap[desireName] += 1
|
|
}
|
|
|
|
// Now we find out if user would be a match excluding the current desire
|
|
|
|
getUserIsAMatchExcludingCurrentDesireBool := func()bool{
|
|
|
|
if (userIsAMatch == true){
|
|
return true
|
|
}
|
|
|
|
for desireNameInner, userPassesDesireInner := range userPassesMyDesiresMap{
|
|
|
|
if (desireNameInner == desireName){
|
|
continue
|
|
}
|
|
if (userPassesDesireInner == false){
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
userIsAMatchExcludingCurrentDesire := getUserIsAMatchExcludingCurrentDesireBool()
|
|
if (userIsAMatchExcludingCurrentDesire == true){
|
|
numberOfDesireExcludedMatchesMap[desireName] += 1
|
|
}
|
|
}
|
|
}
|
|
|
|
allMyDesiresList := myMateDesires.GetAllMyDesiresList(false)
|
|
|
|
allMyDesireStatisticsItemsList := make([]DesireStatisticsItem, 0, len(allMyDesiresList))
|
|
|
|
for _, desireName := range allMyDesiresList{
|
|
|
|
getNumberOfMateIdentitiesWhoPassDesire := func()int64{
|
|
|
|
numberOfMateIdentitiesWhoPassDesire, exists := numberOfMateIdentitiesWhoPassDesireMap[desireName]
|
|
if (exists == false) {
|
|
return 0
|
|
}
|
|
|
|
return numberOfMateIdentitiesWhoPassDesire
|
|
}
|
|
|
|
numberOfMateIdentitiesWhoPassDesire := getNumberOfMateIdentitiesWhoPassDesire()
|
|
|
|
getNumberOfDesireExcludedMatches := func()int64{
|
|
|
|
numberOfDesireExcludedMatches, exists := numberOfDesireExcludedMatchesMap[desireName]
|
|
if (exists == false) {
|
|
return 0
|
|
}
|
|
return numberOfDesireExcludedMatches
|
|
}
|
|
|
|
numberOfDesireExcludedMatches := getNumberOfDesireExcludedMatches()
|
|
|
|
getPercentageOfMateIdentitiesWhoPassDesire := func()float64{
|
|
if (numberOfMateIdentities == 0){
|
|
return 0
|
|
}
|
|
|
|
percentageOfMateIdentitiesWhoPassDesire := 100 * (float64(numberOfMateIdentitiesWhoPassDesire)/float64(numberOfMateIdentities))
|
|
|
|
return percentageOfMateIdentitiesWhoPassDesire
|
|
}
|
|
|
|
percentageOfMateIdentitiesWhoPassDesire := getPercentageOfMateIdentitiesWhoPassDesire()
|
|
|
|
getPercentageOfDesireExcludedMatchesWhoPassDesire := func()float64{
|
|
if (numberOfDesireExcludedMatches == 0){
|
|
return 0
|
|
}
|
|
|
|
percentageOfDesireExcludedMatchesWhoPassDesire := 100 * (float64(numberOfMatches)/float64(numberOfDesireExcludedMatches))
|
|
|
|
return percentageOfDesireExcludedMatchesWhoPassDesire
|
|
}
|
|
|
|
percentageOfDesireExcludedMatchesWhoPassDesire := getPercentageOfDesireExcludedMatchesWhoPassDesire()
|
|
|
|
newDesireStatisticsItem := DesireStatisticsItem{
|
|
DesireName: desireName,
|
|
NumberOfUsersWhoPassDesire: numberOfMateIdentitiesWhoPassDesire,
|
|
PercentageOfUsersWhoPassDesire: percentageOfMateIdentitiesWhoPassDesire,
|
|
NumberOfDesireExcludedMatches: numberOfDesireExcludedMatches,
|
|
PercentageOfDesireExcludedMatchesWhoPassDesire: percentageOfDesireExcludedMatchesWhoPassDesire,
|
|
}
|
|
|
|
allMyDesireStatisticsItemsList = append(allMyDesireStatisticsItemsList, newDesireStatisticsItem)
|
|
}
|
|
|
|
return numberOfMateIdentities, numberOfMatches, allMyDesireStatisticsItemsList, nil
|
|
}
|
|
|
|
|
|
|
|
|