@@ -12,6 +12,7 @@ use anyhow::{bail, ensure, Context as _, Result};
12
12
use async_channel:: { self as channel, Receiver , Sender } ;
13
13
use pgp:: types:: PublicKeyTrait ;
14
14
use ratelimit:: Ratelimit ;
15
+ use serde:: Serialize ;
15
16
use tokio:: sync:: { Mutex , Notify , RwLock } ;
16
17
17
18
use crate :: chat:: { get_chat_cnt, ChatId , ProtectionStatus } ;
@@ -1064,7 +1065,17 @@ impl Context {
1064
1065
}
1065
1066
1066
1067
async fn get_self_report ( & self ) -> Result < String > {
1067
- #[ derive( Default ) ]
1068
+ #[ derive( Serialize ) ]
1069
+ struct Statistics {
1070
+ core_version : String ,
1071
+ num_msgs : u32 ,
1072
+ num_chats : u32 ,
1073
+ db_size : u64 ,
1074
+ key_created : i64 ,
1075
+ chat_numbers : ChatNumbers ,
1076
+ self_reporting_id : String ,
1077
+ }
1078
+ #[ derive( Default , Serialize ) ]
1068
1079
struct ChatNumbers {
1069
1080
protected : u32 ,
1070
1081
protection_broken : u32 ,
@@ -1074,9 +1085,6 @@ impl Context {
1074
1085
unencrypted_mua : u32 ,
1075
1086
}
1076
1087
1077
- let mut res = String :: new ( ) ;
1078
- res += & format ! ( "core_version {}\n " , get_version_str( ) ) ;
1079
-
1080
1088
let num_msgs: u32 = self
1081
1089
. sql
1082
1090
. query_get_value (
@@ -1085,21 +1093,20 @@ impl Context {
1085
1093
)
1086
1094
. await ?
1087
1095
. unwrap_or_default ( ) ;
1088
- res += & format ! ( "num_msgs {num_msgs}\n " ) ;
1089
1096
1090
1097
let num_chats: u32 = self
1091
1098
. sql
1092
1099
. query_get_value ( "SELECT COUNT(*) FROM chats WHERE id>9 AND blocked!=1" , ( ) )
1093
1100
. await ?
1094
1101
. unwrap_or_default ( ) ;
1095
- res += & format ! ( "num_chats {num_chats}\n " ) ;
1096
1102
1097
1103
let db_size = tokio:: fs:: metadata ( & self . sql . dbfile ) . await ?. len ( ) ;
1098
- res += & format ! ( "db_size_bytes {db_size}\n " ) ;
1099
1104
1100
- let secret_key = & load_self_secret_key ( self ) . await ?. primary_key ;
1101
- let key_created = secret_key. public_key ( ) . created_at ( ) . timestamp ( ) ;
1102
- res += & format ! ( "key_created {key_created}\n " ) ;
1105
+ let key_created = load_self_secret_key ( self )
1106
+ . await ?
1107
+ . primary_key
1108
+ . created_at ( )
1109
+ . timestamp ( ) ;
1103
1110
1104
1111
// how many of the chats active in the last months are:
1105
1112
// - protected
@@ -1109,7 +1116,7 @@ impl Context {
1109
1116
// - unencrypted and the contact uses Delta Chat
1110
1117
// - unencrypted and the contact uses a classical MUA
1111
1118
let three_months_ago = time ( ) . saturating_sub ( 3600 * 24 * 30 * 3 ) ;
1112
- let chats = self
1119
+ let chat_numbers = self
1113
1120
. sql
1114
1121
. query_map (
1115
1122
"SELECT c.protected, m.param, m.msgrmsg
@@ -1164,12 +1171,6 @@ impl Context {
1164
1171
} ,
1165
1172
)
1166
1173
. await ?;
1167
- res += & format ! ( "chats_protected {}\n " , chats. protected) ;
1168
- res += & format ! ( "chats_protection_broken {}\n " , chats. protection_broken) ;
1169
- res += & format ! ( "chats_opportunistic_dc {}\n " , chats. opportunistic_dc) ;
1170
- res += & format ! ( "chats_opportunistic_mua {}\n " , chats. opportunistic_mua) ;
1171
- res += & format ! ( "chats_unencrypted_dc {}\n " , chats. unencrypted_dc) ;
1172
- res += & format ! ( "chats_unencrypted_mua {}\n " , chats. unencrypted_mua) ;
1173
1174
1174
1175
let self_reporting_id = match self . get_config ( Config :: SelfReportingId ) . await ? {
1175
1176
Some ( id) => id,
@@ -1180,9 +1181,17 @@ impl Context {
1180
1181
id
1181
1182
}
1182
1183
} ;
1183
- res += & format ! ( "self_reporting_id {self_reporting_id}" ) ;
1184
+ let statistics = Statistics {
1185
+ core_version : get_version_str ( ) . to_string ( ) ,
1186
+ num_msgs,
1187
+ num_chats,
1188
+ db_size,
1189
+ key_created,
1190
+ chat_numbers,
1191
+ self_reporting_id,
1192
+ } ;
1184
1193
1185
- Ok ( res )
1194
+ Ok ( serde_json :: to_string_pretty ( & statistics ) ? )
1186
1195
}
1187
1196
1188
1197
/// Drafts a message with statistics about the usage of Delta Chat.
0 commit comments