mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-09-01 13:04:08 +00:00
141 lines
5.2 KiB
Dart
141 lines
5.2 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:twonly/locator.dart';
|
|
import 'package:twonly/src/database/tables/contacts.table.dart';
|
|
import 'package:twonly/src/services/user.service.dart';
|
|
import 'package:twonly/src/utils/keyvalue.dart';
|
|
import 'package:twonly/src/utils/log.dart';
|
|
import 'package:twonly/src/utils/misc.dart';
|
|
|
|
const userStudySurveyKey = 'user_study_survey';
|
|
|
|
// PLEASE DO NOT SPAM OR TRY SENDING DIRECTLY TO THIS URL!
|
|
// You're just making my master's thesis more difficult and destroy scientific data. :/
|
|
const surveyUrlBase = 'https://survey.twonly.org/upload.php';
|
|
|
|
Future<void> handleUserStudyUpload() async {
|
|
try {
|
|
final token = userService.currentUser.userStudyParticipantsToken;
|
|
if (token == null) return;
|
|
|
|
// in case the survey was taken offline try again
|
|
final userStudySurvey = await KeyValueStore.get(userStudySurveyKey);
|
|
if (userStudySurvey != null) {
|
|
final response = await http.post(
|
|
Uri.parse('$surveyUrlBase/create/$token'),
|
|
body: jsonEncode(userStudySurvey),
|
|
headers: {'Content-Type': 'application/json'},
|
|
);
|
|
if (response.statusCode != 200) {
|
|
Log.warn(
|
|
'Got different status code for survey upload: ${response.statusCode}',
|
|
);
|
|
return;
|
|
}
|
|
await KeyValueStore.delete(userStudySurveyKey);
|
|
}
|
|
|
|
if (userService.currentUser.lastUserStudyDataUpload != null &&
|
|
isToday(userService.currentUser.lastUserStudyDataUpload!)) {
|
|
// Only send updates once a day.
|
|
// This enables to see if improvements to actually work.
|
|
return;
|
|
}
|
|
|
|
final contacts = await twonlyDB.contactsDao.getAllContacts();
|
|
final verifications = await twonlyDB.keyVerificationDao
|
|
.getFirstVerificationTypeByContacts();
|
|
final udVerifiedByContactsCount = await twonlyDB.keyVerificationDao
|
|
.getTransferredTrustVerificationsCount();
|
|
|
|
final totalContactsWithVerificationBadge = await twonlyDB.keyVerificationDao
|
|
.getCountOfContactsWithVerificationBadge();
|
|
|
|
final udFriendsShared = await twonlyDB.contactsDao
|
|
.getContactsAnnouncedViaUserDiscovery();
|
|
|
|
final udAllAnnouncedUsers = await twonlyDB.userDiscoveryDao
|
|
.getAllAnnouncedUsersWithRelations();
|
|
|
|
var udUnknownAnnouncedUsers = 0;
|
|
|
|
for (final udUser in udAllAnnouncedUsers.keys) {
|
|
if (!contacts.any((c) => c.userId == udUser.announcedUserId)) {
|
|
udUnknownAnnouncedUsers += 1;
|
|
}
|
|
}
|
|
|
|
final dataCollection = {
|
|
'total_contacts': contacts.length,
|
|
|
|
'user_discovery_enabled': userService.currentUser.isUserDiscoveryEnabled,
|
|
'user_discovery_required_send_images':
|
|
userService.currentUser.requiredSendImages,
|
|
'user_discovery_threshold':
|
|
userService.currentUser.userDiscoveryThreshold,
|
|
'user_discovery_requires_manual_approval':
|
|
userService.currentUser.userDiscoveryRequiresManualApproval,
|
|
'user_discovery_share_promotion':
|
|
userService.currentUser.userDiscoverySharePromotion,
|
|
|
|
'user_discovery_count_friends_shared': udFriendsShared.length,
|
|
|
|
'user_discovery_count_announced_users': udAllAnnouncedUsers.length,
|
|
'user_discovery_count_unknown_announced_users': udUnknownAnnouncedUsers,
|
|
|
|
'user_study_count_new_friends_via_suggestion':
|
|
userService.currentUser.userStudyCountNewFriendsViaSuggestion,
|
|
'user_discovery_count_verified_by_contacts': udVerifiedByContactsCount,
|
|
|
|
'accepted_contacts': contacts.where((c) => c.accepted).length,
|
|
'verified_contacts': verifications.length,
|
|
'total_contacts_with_verification_badge':
|
|
totalContactsWithVerificationBadge,
|
|
'verified_contacts_via_migrated_from_old_version': verifications.values
|
|
.where((c) => c == VerificationType.migratedFromOldVersion)
|
|
.length,
|
|
'verified_contacts_via_qr_scanned': verifications.values
|
|
.where((c) => c == VerificationType.qrScanned)
|
|
.length,
|
|
'verified_contacts_via_link': verifications.values
|
|
.where((c) => c == VerificationType.link)
|
|
.length,
|
|
'verified_contacts_via_secret_qr_token': verifications.values
|
|
.where((c) => c == VerificationType.secretQrToken)
|
|
.length,
|
|
'verified_contacts_via_contact_shared_by_verified': verifications.values
|
|
.where((c) => c == VerificationType.contactSharedByVerified)
|
|
.length,
|
|
};
|
|
|
|
final response = await http.post(
|
|
Uri.parse('$surveyUrlBase/push/$token'),
|
|
body: jsonEncode(dataCollection),
|
|
headers: {'Content-Type': 'application/json'},
|
|
);
|
|
if (response.statusCode == 200) {
|
|
await UserService.update((u) {
|
|
u.lastUserStudyDataUpload = DateTime.now();
|
|
});
|
|
}
|
|
if (response.statusCode == 404) {
|
|
// Token is unknown to the server...
|
|
await UserService.update((u) {
|
|
u
|
|
..lastUserStudyDataUpload = null
|
|
..userStudyParticipantsToken = null;
|
|
});
|
|
}
|
|
} catch (e) {
|
|
if (e is http.ClientException ||
|
|
e is SocketException ||
|
|
e is TimeoutException) {
|
|
Log.warn('Error uploading user study data: $e');
|
|
} else {
|
|
Log.error(e);
|
|
}
|
|
}
|
|
}
|