623 lines
20 KiB
Go
623 lines
20 KiB
Go
|
|
// viewedContent provides functions to generate and retrieve the viewedContent list
|
|
// This list is used to view content on the View Content page
|
|
|
|
package viewedContent
|
|
|
|
import "seekia/internal/appMemory"
|
|
import "seekia/internal/badgerDatabase"
|
|
import "seekia/internal/encoding"
|
|
import "seekia/internal/helpers"
|
|
import "seekia/internal/moderation/contentControversy"
|
|
import "seekia/internal/moderation/reviewStorage"
|
|
import "seekia/internal/myDatastores/myList"
|
|
import "seekia/internal/myDatastores/myMap"
|
|
import "seekia/internal/mySettings"
|
|
|
|
import "slices"
|
|
import "sync"
|
|
import "errors"
|
|
|
|
//TODO: Add more sort by attributes
|
|
// Examples: Number of reviews, continuous approval period
|
|
|
|
// This mutex will be locked whenever we update the viewed content list
|
|
var updatingViewedContentMutex sync.Mutex
|
|
|
|
var viewedContentListDatastore *myList.MyList
|
|
|
|
var viewedContentFiltersMapDatastore *myMap.MyMap
|
|
|
|
// This function must be called whenever an app user signs in
|
|
func InitializeViewedContentDatastores()error{
|
|
|
|
updatingViewedContentMutex.Lock()
|
|
defer updatingViewedContentMutex.Unlock()
|
|
|
|
newViewedContentListDatastore, err := myList.CreateNewList("ViewedContent")
|
|
if (err != nil) { return err }
|
|
|
|
newViewedContentFiltersMapDatastore, err := myMap.CreateNewMap("ViewedContentFilters")
|
|
if (err != nil){ return err }
|
|
|
|
viewedContentListDatastore = newViewedContentListDatastore
|
|
|
|
viewedContentFiltersMapDatastore = newViewedContentFiltersMapDatastore
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetViewedContentSortByAttribute()(string, error){
|
|
|
|
exists, currentAttribute, err := mySettings.GetSetting("ViewedContentSortByAttribute")
|
|
if (err != nil) { return "", err }
|
|
if (exists == false){
|
|
return "Controversy", nil
|
|
}
|
|
|
|
return currentAttribute, nil
|
|
}
|
|
|
|
func GetViewedContentSortDirection()(string, error){
|
|
|
|
exists, sortDirection, err := mySettings.GetSetting("ViewedContentSortDirection")
|
|
if (err != nil) { return "", err }
|
|
if (exists == false){
|
|
return "Descending", nil
|
|
}
|
|
if (sortDirection != "Ascending" && sortDirection != "Descending"){
|
|
return "", errors.New("MySettings malformed: Contains invalid ViewedContentSortDirection: " + sortDirection)
|
|
}
|
|
|
|
return sortDirection, nil
|
|
}
|
|
|
|
func CheckIfViewedContentNeedsRefresh()(bool, error){
|
|
|
|
exists, needsRefresh, err := mySettings.GetSetting("ViewedContentNeedsRefreshYesNo")
|
|
if (err != nil) { return false, err }
|
|
if (exists == true && needsRefresh == "No") {
|
|
return false, nil
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
func GetViewedContentIsReadyStatus(networkType byte)(bool, error){
|
|
|
|
isValid := helpers.VerifyNetworkType(networkType)
|
|
if (isValid == false){
|
|
networkTypeString := helpers.ConvertByteToString(networkType)
|
|
return false, errors.New("GetViewedContentIsReadyStatus called with invalid networkType: " + networkTypeString)
|
|
}
|
|
|
|
exists, contentGeneratedStatus, err := mySettings.GetSetting("ViewedContentGeneratedStatus")
|
|
if (err != nil) { return false, err }
|
|
if (exists == false || contentGeneratedStatus != "Yes"){
|
|
return false, nil
|
|
}
|
|
|
|
exists, contentSortedStatus, err := mySettings.GetSetting("ViewedContentSortedStatus")
|
|
if (err != nil) { return false, err }
|
|
if (exists == false || contentSortedStatus != "Yes"){
|
|
return false, nil
|
|
}
|
|
|
|
exists, contentNetworkTypeString, err := mySettings.GetSetting("ViewedContentNetworkType")
|
|
if (err != nil) { return false, err }
|
|
if (exists == false){
|
|
// This should not happen, because ViewedContentNetworkType is created whenever content is generated
|
|
return false, errors.New("mySettings missing ViewedContentNetworkType when ViewedContentGeneratedStatus exists.")
|
|
}
|
|
|
|
contentNetworkType, err := helpers.ConvertNetworkTypeStringToByte(contentNetworkTypeString)
|
|
if (err != nil) {
|
|
return false, errors.New("mySettings contains invalid ViewedContentNetworkType: " + contentNetworkTypeString)
|
|
}
|
|
if (contentNetworkType != networkType){
|
|
// Content wes generated for a different networkType
|
|
// This should never happen, because we will always set ViewedContentGeneratedStatus to No when we switch network types,
|
|
// and we will always call the GetViewedContentIsReadyStatus function with the current appNetworkType
|
|
|
|
//TODO: Log this.
|
|
|
|
err := mySettings.SetSetting("ViewedContentGeneratedStatus", "No")
|
|
if (err != nil) { return false, err }
|
|
|
|
return false, nil
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
//Outputs:
|
|
// -bool: Viewed content map list is ready
|
|
// -[]string
|
|
// -error
|
|
func GetViewedContentList(networkType byte)(bool, []string, error){
|
|
|
|
isValid := helpers.VerifyNetworkType(networkType)
|
|
if (isValid == false){
|
|
networkTypeString := helpers.ConvertByteToString(networkType)
|
|
return false, nil, errors.New("GetViewedContentList called with invalid networkType: " + networkTypeString)
|
|
}
|
|
|
|
areReady, err := GetViewedContentIsReadyStatus(networkType)
|
|
if (err != nil) { return false, nil, err }
|
|
if (areReady == false){
|
|
return false, nil, nil
|
|
}
|
|
|
|
viewedContentList, err := viewedContentListDatastore.GetList()
|
|
if (err != nil) { return false, nil, err }
|
|
|
|
return true, viewedContentList, nil
|
|
}
|
|
|
|
// This function returns the number of viewed contents
|
|
// It can be called before the list is ready (after being generated, but before being sorted)
|
|
func GetNumberOfGeneratedViewedContents()(int, error){
|
|
|
|
currentViewedContentList, err := viewedContentListDatastore.GetList()
|
|
if (err != nil) { return 0, err }
|
|
|
|
lengthInt := len(currentViewedContentList)
|
|
|
|
return lengthInt, nil
|
|
}
|
|
|
|
//Outputs:
|
|
// -bool: Build encountered error
|
|
// -string: Error encountered
|
|
// -bool: Build is stopped (will be stopped if user went to different page)
|
|
// -bool: Viewed content is ready
|
|
// -float64: Percentage Progress (0 - 1)
|
|
// -error
|
|
func GetViewedContentBuildStatus(networkType byte)(bool, string, bool, bool, float64, error){
|
|
|
|
isValid := helpers.VerifyNetworkType(networkType)
|
|
if (isValid == false){
|
|
networkTypeString := helpers.ConvertByteToString(networkType)
|
|
return false, "", false, false, 0, errors.New("GetViewedContentBuildStatus called with invalid networkType: " + networkTypeString)
|
|
}
|
|
|
|
exists, encounteredError := appMemory.GetMemoryEntry("ViewedContentBuildEncounteredError")
|
|
if (exists == false){
|
|
// No build exists. A build has not been started since Seekia was started
|
|
return false, "", false, false, 0, nil
|
|
}
|
|
if (encounteredError == "Yes"){
|
|
exists, errorEncountered := appMemory.GetMemoryEntry("ViewedContentBuildError")
|
|
if (exists == false){
|
|
return false, "", false, false, 0, errors.New("Viewed Content build encountered error is yes, but no error exists.")
|
|
}
|
|
|
|
return true, errorEncountered, false, false, 0, nil
|
|
}
|
|
|
|
isStopped := CheckIfBuildViewedContentIsStopped()
|
|
if (isStopped == true){
|
|
return false, "", true, false, 0, nil
|
|
}
|
|
|
|
contentIsReadyBool, err := GetViewedContentIsReadyStatus(networkType)
|
|
if (err != nil) { return false, "", false, false, 0, err }
|
|
if (contentIsReadyBool == true){
|
|
|
|
return false, "", false, true, 1, nil
|
|
}
|
|
|
|
exists, currentPercentageString := appMemory.GetMemoryEntry("ViewedContentReadyProgressStatus")
|
|
if (exists == false){
|
|
// No build exists. A build has not been started since Seekia was started
|
|
return false, "", false, false, 0, nil
|
|
}
|
|
|
|
currentPercentageFloat, err := helpers.ConvertStringToFloat64(currentPercentageString)
|
|
if (err != nil){
|
|
return false, "", false, false, 0, errors.New("ViewedContentReadyProgressStatus is invalid: Not a float: " + currentPercentageString)
|
|
}
|
|
|
|
return false, "", false, false, currentPercentageFloat, nil
|
|
}
|
|
|
|
|
|
func CheckIfBuildViewedContentIsStopped()bool{
|
|
|
|
exists, buildStoppedStatus := appMemory.GetMemoryEntry("StopBuildViewedContentYesNo")
|
|
if (exists == false || buildStoppedStatus != "No") {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
|
|
// This function will cancel the current build (if one is running)
|
|
// It will then start updating our viewed content
|
|
func StartUpdatingViewedContent(networkType byte)error{
|
|
|
|
isValid := helpers.VerifyNetworkType(networkType)
|
|
if (isValid == false){
|
|
networkTypeString := helpers.ConvertByteToString(networkType)
|
|
return errors.New("StartUpdatingViewedContent called with invalid networkType: " + networkTypeString)
|
|
}
|
|
|
|
appMemory.SetMemoryEntry("StopBuildViewedContentYesNo", "Yes")
|
|
|
|
// We wait for any existing build to stop
|
|
updatingViewedContentMutex.Lock()
|
|
|
|
appMemory.SetMemoryEntry("ViewedContentBuildEncounteredError", "No")
|
|
appMemory.SetMemoryEntry("ViewedContentBuildError", "")
|
|
appMemory.SetMemoryEntry("ViewedContentReadyProgressStatus", "0")
|
|
|
|
appMemory.SetMemoryEntry("StopBuildViewedContentYesNo", "No")
|
|
|
|
updateViewedContent := func()error{
|
|
|
|
getViewedContentNeedsToBeGeneratedStatus := func()(bool, error){
|
|
|
|
exists, contentGeneratedStatus, err := mySettings.GetSetting("ViewedContentGeneratedStatus")
|
|
if (err != nil) { return false, err }
|
|
if (exists == false || contentGeneratedStatus != "Yes"){
|
|
return true, nil
|
|
}
|
|
|
|
exists, viewedContentNetworkTypeString, err := mySettings.GetSetting("ViewedContentNetworkType")
|
|
if (err != nil) { return false, err }
|
|
if (exists == false){
|
|
// This should not happen, because ViewedContentNetworkType is set to Yes whenever viewed content is generated
|
|
return false, errors.New("ViewedContentNetworkType missing when ViewedContentGeneratedStatus exists.")
|
|
}
|
|
|
|
viewedContentNetworkType, err := helpers.ConvertNetworkTypeStringToByte(viewedContentNetworkTypeString)
|
|
if (err != nil) {
|
|
return false, errors.New("mySettings contains invalid ViewedContentNetworkType: " + viewedContentNetworkTypeString)
|
|
}
|
|
if (viewedContentNetworkType != networkType){
|
|
// This should not happen, because ViewedContentGeneratedStatus should be set to No whenever app network type is changed,
|
|
// and StartUpdatingViewedContent should only be called with the current app network type.
|
|
return true, nil
|
|
}
|
|
|
|
return false, nil
|
|
}
|
|
|
|
viewedContentNeedsToBeGenerated, err := getViewedContentNeedsToBeGeneratedStatus()
|
|
if (err != nil) { return err }
|
|
if (viewedContentNeedsToBeGenerated == true){
|
|
|
|
err := mySettings.SetSetting("ViewedContentSortedStatus", "No")
|
|
if (err != nil) { return err }
|
|
|
|
//TODO: Check if content passes filters
|
|
//TODO: Omit disabled profiles
|
|
|
|
viewedContentList := make([]string, 0)
|
|
|
|
reportedMessageHashesList, err := badgerDatabase.GetAllReportedMessageHashes()
|
|
if (err != nil) { return err }
|
|
|
|
appMemory.SetMemoryEntry("ViewedContentReadyProgressStatus", "0.10")
|
|
|
|
reviewedMessageHashesList, err := badgerDatabase.GetAllReviewedMessageHashes()
|
|
if (err != nil) { return err }
|
|
|
|
appMemory.SetMemoryEntry("ViewedContentReadyProgressStatus", "0.15")
|
|
|
|
allMessageHashesList := helpers.CombineTwoListsAndAvoidDuplicates(reportedMessageHashesList, reviewedMessageHashesList)
|
|
|
|
appMemory.SetMemoryEntry("ViewedContentReadyProgressStatus", "0.20")
|
|
|
|
for _, messageHash := range allMessageHashesList{
|
|
|
|
messageHashString := encoding.EncodeBytesToHexString(messageHash[:])
|
|
|
|
viewedContentList = append(viewedContentList, messageHashString)
|
|
}
|
|
|
|
appMemory.SetMemoryEntry("ViewedContentReadyProgressStatus", "0.25")
|
|
|
|
mateProfileHashesList, err := badgerDatabase.GetAllProfileHashes("Mate")
|
|
if (err != nil) { return err }
|
|
|
|
for _, profileHash := range mateProfileHashesList{
|
|
|
|
profileHashString := encoding.EncodeBytesToHexString(profileHash[:])
|
|
|
|
viewedContentList = append(viewedContentList, profileHashString)
|
|
}
|
|
|
|
appMemory.SetMemoryEntry("ViewedContentReadyProgressStatus", "0.35")
|
|
|
|
hostProfileHashesList, err := badgerDatabase.GetAllProfileHashes("Host")
|
|
if (err != nil) { return err }
|
|
|
|
for _, profileHash := range hostProfileHashesList{
|
|
|
|
profileHashString := encoding.EncodeBytesToHexString(profileHash[:])
|
|
|
|
viewedContentList = append(viewedContentList, profileHashString)
|
|
}
|
|
|
|
appMemory.SetMemoryEntry("ViewedContentReadyProgressStatus", "0.45")
|
|
|
|
moderatorProfileHashesList, err := badgerDatabase.GetAllProfileHashes("Moderator")
|
|
if (err != nil) { return err }
|
|
|
|
for _, profileHash := range moderatorProfileHashesList{
|
|
|
|
profileHashString := encoding.EncodeBytesToHexString(profileHash[:])
|
|
|
|
viewedContentList = append(viewedContentList, profileHashString)
|
|
}
|
|
|
|
err = viewedContentListDatastore.OverwriteList(viewedContentList)
|
|
if (err != nil) { return err }
|
|
|
|
err = mySettings.SetSetting("ViewedContentGeneratedStatus", "Yes")
|
|
if (err != nil) { return err }
|
|
|
|
networkTypeString := helpers.ConvertByteToString(networkType)
|
|
|
|
err = mySettings.SetSetting("ViewedContentNetworkType", networkTypeString)
|
|
if (err != nil) { return err }
|
|
}
|
|
|
|
isStopped := CheckIfBuildViewedContentIsStopped()
|
|
if (isStopped == true){
|
|
return nil
|
|
}
|
|
|
|
appMemory.SetMemoryEntry("ViewedContentReadyProgressStatus", "0.50")
|
|
|
|
contentReadyStatus, err := GetViewedContentIsReadyStatus(networkType)
|
|
if (err != nil) { return err }
|
|
if (contentReadyStatus == false){
|
|
|
|
// Now we sort content.
|
|
|
|
currentSortByAttribute, err := GetViewedContentSortByAttribute()
|
|
if (err != nil) { return err }
|
|
currentSortDirection, err := GetViewedContentSortDirection()
|
|
if (err != nil) { return err }
|
|
|
|
currentContentsList, err := viewedContentListDatastore.GetList()
|
|
if (err != nil) { return err }
|
|
|
|
// We use this map to make sure there are no duplicate content hashes
|
|
// This should never happen, unless the user's stored list was edited or there is a bug
|
|
allContentHashesMap := make(map[string]struct{})
|
|
|
|
//Map Structure: Content Hash Hex -> Content attribute value
|
|
contentAttributeValuesMap := make(map[string]float64)
|
|
|
|
maximumIndex := len(currentContentsList) - 1
|
|
|
|
for index, contentHashHex := range currentContentsList{
|
|
|
|
contentHash, err := encoding.DecodeHexStringToBytes(contentHashHex)
|
|
if (err != nil){
|
|
return errors.New("viewedContentList contains invalid content hash during sort: " + contentHashHex)
|
|
}
|
|
|
|
_, exists := allContentHashesMap[string(contentHash)]
|
|
if (exists == true){
|
|
return errors.New("viewedContentList contains duplicate content hash.")
|
|
}
|
|
allContentHashesMap[string(contentHash)] = struct{}{}
|
|
|
|
// Outputs:
|
|
// -bool: Content attribute value is known
|
|
// -float64: Content attribute value
|
|
// -error
|
|
getContentAttributeValue := func()(bool, float64, error){
|
|
|
|
if (currentSortByAttribute == "Controversy"){
|
|
requiredDataExists, controversyRating, err := contentControversy.GetContentControversyRating(contentHash)
|
|
if (err != nil) { return false, 0, err }
|
|
if (requiredDataExists == false){
|
|
// We do not know the content controversy.
|
|
return false, 0, nil
|
|
}
|
|
|
|
return true, float64(controversyRating), nil
|
|
}
|
|
if (currentSortByAttribute == "NumberOfReviewers"){
|
|
|
|
contentType, err := helpers.GetContentTypeFromContentHash(contentHash)
|
|
if (err != nil) { return false, 0, err }
|
|
if (contentType == "Profile"){
|
|
|
|
if (len(contentHash) != 28){
|
|
return false, 0, errors.New("GetContentTypeFromContentHash returning Profile for different length contentHash: " + contentHashHex)
|
|
}
|
|
|
|
profileHash := [28]byte(contentHash)
|
|
|
|
profileMetadataIsKnown, downloadingRequiredData, numberOfReviewers, err := reviewStorage.GetNumberOfProfileReviewers(profileHash)
|
|
if (err != nil) { return false, 0, err }
|
|
if (profileMetadataIsKnown == false || downloadingRequiredData == false){
|
|
return false, 0, nil
|
|
}
|
|
|
|
return true, float64(numberOfReviewers), nil
|
|
|
|
} else if (contentType == "Message"){
|
|
|
|
if (len(contentHash) != 26){
|
|
return false, 0, errors.New("GetContentTypeFromContentHash returning Message for different length contentHash: " + contentHashHex)
|
|
}
|
|
|
|
messageHash := [26]byte(contentHash)
|
|
|
|
messageMetadataIsKnown, downloadingRequiredData, numberOfReviewers, err := reviewStorage.GetNumberOfMessageReviewers(messageHash)
|
|
if (err != nil) { return false, 0, err }
|
|
if (messageMetadataIsKnown == false || downloadingRequiredData == false){
|
|
return false, 0, nil
|
|
}
|
|
|
|
return true, float64(numberOfReviewers), nil
|
|
}
|
|
|
|
return false, 0, errors.New("Viewed content list contains invalid contentHash during sort: " + contentHashHex)
|
|
}
|
|
|
|
//TODO: Add more attributes
|
|
|
|
return false, 0, errors.New("GetViewedContentSortByAttribute returning unknown attribute: " + currentSortByAttribute)
|
|
}
|
|
|
|
contentAttributeValueIsKnown, contentAttributeValue, err := getContentAttributeValue()
|
|
if (err != nil) { return err }
|
|
if (contentAttributeValueIsKnown == true){
|
|
contentAttributeValuesMap[contentHashHex] = contentAttributeValue
|
|
}
|
|
|
|
isStopped := CheckIfBuildViewedContentIsStopped()
|
|
if (isStopped == true){
|
|
return nil
|
|
}
|
|
|
|
newScaledPercentageInt, err := helpers.ScaleIntProportionally(true, index, 0, maximumIndex, 50, 80)
|
|
if (err != nil) { return err }
|
|
|
|
newProgressFloat := float64(newScaledPercentageInt)/100
|
|
|
|
newProgressString := helpers.ConvertFloat64ToString(newProgressFloat)
|
|
|
|
appMemory.SetMemoryEntry("ViewedContentReadyProgressStatus", newProgressString)
|
|
}
|
|
|
|
compareContentsFunction := func(contentHashA string, contentHashB string)int{
|
|
|
|
if (contentHashA == contentHashB){
|
|
panic("Duplicate content hashes called to compare function during sort.")
|
|
}
|
|
|
|
attributeValueA, attributeValueAExists := contentAttributeValuesMap[contentHashA]
|
|
|
|
attributeValueB, attributeValueBExists := contentAttributeValuesMap[contentHashB]
|
|
|
|
if (attributeValueAExists == false && attributeValueBExists == false){
|
|
|
|
// We don't know the attribute value for either content
|
|
// We sort contents in unicode order
|
|
if (contentHashA < contentHashB){
|
|
return -1
|
|
}
|
|
return 1
|
|
|
|
} else if (attributeValueAExists == true && attributeValueBExists == false){
|
|
|
|
// We sort unknown attribute contents to the back of the list
|
|
|
|
return -1
|
|
|
|
} else if (attributeValueAExists == false && attributeValueBExists == true){
|
|
|
|
return 1
|
|
}
|
|
|
|
// Both attribute values exist
|
|
|
|
if (attributeValueA == attributeValueB){
|
|
|
|
// We sort content hashes in unicode order
|
|
if (contentHashA < contentHashB){
|
|
return -1
|
|
}
|
|
|
|
return 1
|
|
}
|
|
|
|
if (attributeValueA < attributeValueB){
|
|
|
|
if (currentSortDirection == "Ascending"){
|
|
return -1
|
|
}
|
|
return 1
|
|
}
|
|
if (currentSortDirection == "Ascending"){
|
|
return 1
|
|
}
|
|
|
|
return -1
|
|
}
|
|
|
|
slices.SortFunc(currentContentsList, compareContentsFunction)
|
|
|
|
err = viewedContentListDatastore.OverwriteList(currentContentsList)
|
|
if (err != nil) { return err }
|
|
|
|
err = mySettings.SetSetting("ViewedContentSortedStatus", "Yes")
|
|
if (err != nil) { return err }
|
|
}
|
|
|
|
appMemory.SetMemoryEntry("ViewedContentReadyProgressStatus", "1")
|
|
|
|
err = mySettings.SetSetting("ViewedContentNeedsRefreshYesNo", "No")
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
updateFunction := func(){
|
|
|
|
err := updateViewedContent()
|
|
if (err != nil){
|
|
appMemory.SetMemoryEntry("ViewedContentBuildEncounteredError", "Yes")
|
|
appMemory.SetMemoryEntry("ViewedContentBuildError", err.Error())
|
|
}
|
|
|
|
updatingViewedContentMutex.Unlock()
|
|
}
|
|
|
|
go updateFunction()
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetNumberOfActiveViewedContentFilters()(int, error){
|
|
|
|
numberOfActiveFilters := 0
|
|
|
|
//TODO
|
|
|
|
return numberOfActiveFilters, nil
|
|
}
|
|
|
|
|
|
func SetViewedContentFilterOnOffStatus(filterName string, newFilterStatus bool)error{
|
|
|
|
filterOnOffStatusString := helpers.ConvertBoolToYesOrNoString(newFilterStatus)
|
|
|
|
err := viewedContentFiltersMapDatastore.SetMapEntry(filterName, filterOnOffStatusString)
|
|
if (err != nil) { return err }
|
|
|
|
err = mySettings.SetSetting("ViewedContentGeneratedStatus", "No")
|
|
if (err != nil) { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetViewedContentFilterOnOffStatus(filterName string)(bool, error){
|
|
|
|
filterStatusExists, currentFilterStatus, err := viewedContentFiltersMapDatastore.GetMapEntry(filterName)
|
|
if (err != nil) { return false, err }
|
|
if (filterStatusExists == false){
|
|
return false, nil
|
|
}
|
|
|
|
filterOnOffStatusBool, err := helpers.ConvertYesOrNoStringToBool(currentFilterStatus)
|
|
if (err != nil) { return false, err }
|
|
|
|
return filterOnOffStatusBool, nil
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|