@ -66,15 +66,23 @@ enum MockDataGenerator {
}
}
// MARK: - G e n e r a t i o n
static var printProgress : Bool = false
static var hasStartedGenerationThisRun : Bool = false
static func generateMockData ( ) {
// D o n ' t r e - g e n e r a t e t h e m o c k d a t a i f i t a l r e a d y e x i s t s
var existingMockDataThread : TSContactThread ?
Storage . read { transaction in
existingMockDataThread = TSContactThread . getWithContactSessionID ( " MockDatabaseThread " , transaction : transaction )
}
guard existingMockDataThread = = nil else { return }
guard ! hasStartedGenerationThisRun && existingMockDataThread = = nil else {
hasStartedGenerationThisRun = true
return
}
// / T h e m o c k d a t a g e n e r a t i o n i s q u i t e s l o w , t h e r e a r e 3 p a r t s w h i c h t a k e a d e c e n t a m o u n t o f t i m e ( d e l e t i n g t h e a c c o u n t a f t e r w a r d s w i l l a l s o t a k e a l o n g t i m e ) :
// / G e n e r a t i n g t h e t h r e a d s & c o n t e n t - ~ 3 s p e r 1 0 0
@ -83,33 +91,48 @@ enum MockDataGenerator {
let dmThreadCount : Int = 100
let closedGroupThreadCount : Int = 0
let openGroupThreadCount : Int = 0
let m axMessagesPerThread: Int = 50
let m essageRangePerThread: [ ClosedRange < Int > ] = [ ( 0. . . 50 ) ]
let dmRandomSeed : Int = 1111
let cgRandomSeed : Int = 2222
let ogRandomSeed : Int = 3333
let openGroupBaseUrl : String = " https://chat.lokinet.dev "
let logProgress : ( String , String ) -> ( ) = { title , event in
guard printProgress else { return }
print ( " [MockDataGenerator] ( \( Date ( ) . timeIntervalSince1970 ) ) \( title ) - \( event ) " )
}
hasStartedGenerationThisRun = true
// FIXME: M a k e s u r e t h i s d a t a d o e s n ' t g o o f f d e v i c e s o m e h o w ?
Storage . shared . write { anyTransaction in
guard let transaction : YapDatabaseReadWriteTransaction = anyTransaction as ? YapDatabaseReadWriteTransaction else { return }
guard let transaction : YapDatabaseReadWriteTransaction = anyTransaction as ? YapDatabaseReadWriteTransaction else {
return
}
// F i r s t c r e a t e t h e t h r e a d u s e d t o i n d i c a t e t h a t t h e m o c k d a t a h a s b e e n g e n e r a t e d
logProgress ( " " , " Start " )
_ = TSContactThread . getOrCreateThread ( withContactSessionID : " MockDatabaseThread " , transaction : transaction )
// M u l t i p l e s p a c e s t o m a k e i t l o o k m o r e l i k e w o r d s
let stringContent : [ String ] = " abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 " . map { String ( $0 ) }
let wordContent : [ String ] = [ " alias " , " consequatur " , " aut " , " perferendis " , " sit " , " voluptatem " , " accusantium " , " doloremque " , " aperiam " , " eaque " , " ipsa " , " quae " , " ab " , " illo " , " inventore " , " veritatis " , " et " , " quasi " , " architecto " , " beatae " , " vitae " , " dicta " , " sunt " , " explicabo " , " aspernatur " , " aut " , " odit " , " aut " , " fugit " , " sed " , " quia " , " consequuntur " , " magni " , " dolores " , " eos " , " qui " , " ratione " , " voluptatem " , " sequi " , " nesciunt " , " neque " , " dolorem " , " ipsum " , " quia " , " dolor " , " sit " , " amet " , " consectetur " , " adipisci " , " velit " , " sed " , " quia " , " non " , " numquam " , " eius " , " modi " , " tempora " , " incidunt " , " ut " , " labore " , " et " , " dolore " , " magnam " , " aliquam " , " quaerat " , " voluptatem " , " ut " , " enim " , " ad " , " minima " , " veniam " , " quis " , " nostrum " , " exercitationem " , " ullam " , " corporis " , " nemo " , " enim " , " ipsam " , " voluptatem " , " quia " , " voluptas " , " sit " , " suscipit " , " laboriosam " , " nisi " , " ut " , " aliquid " , " ex " , " ea " , " commodi " , " consequatur " , " quis " , " autem " , " vel " , " eum " , " iure " , " reprehenderit " , " qui " , " in " , " ea " , " voluptate " , " velit " , " esse " , " quam " , " nihil " , " molestiae " , " et " , " iusto " , " odio " , " dignissimos " , " ducimus " , " qui " , " blanditiis " , " praesentium " , " laudantium " , " totam " , " rem " , " voluptatum " , " deleniti " , " atque " , " corrupti " , " quos " , " dolores " , " et " , " quas " , " molestias " , " excepturi " , " sint " , " occaecati " , " cupiditate " , " non " , " provident " , " sed " , " ut " , " perspiciatis " , " unde " , " omnis " , " iste " , " natus " , " error " , " similique " , " sunt " , " in " , " culpa " , " qui " , " officia " , " deserunt " , " mollitia " , " animi " , " id " , " est " , " laborum " , " et " , " dolorum " , " fuga " , " et " , " harum " , " quidem " , " rerum " , " facilis " , " est " , " et " , " expedita " , " distinctio " , " nam " , " libero " , " tempore " , " cum " , " soluta " , " nobis " , " est " , " eligendi " , " optio " , " cumque " , " nihil " , " impedit " , " quo " , " porro " , " quisquam " , " est " , " qui " , " minus " , " id " , " quod " , " maxime " , " placeat " , " facere " , " possimus " , " omnis " , " voluptas " , " assumenda " , " est " , " omnis " , " dolor " , " repellendus " , " temporibus " , " autem " , " quibusdam " , " et " , " aut " , " consequatur " , " vel " , " illum " , " qui " , " dolorem " , " eum " , " fugiat " , " quo " , " voluptas " , " nulla " , " pariatur " , " at " , " vero " , " eos " , " et " , " accusamus " , " officiis " , " debitis " , " aut " , " rerum " , " necessitatibus " , " saepe " , " eveniet " , " ut " , " et " , " voluptates " , " repudiandae " , " sint " , " et " , " molestiae " , " non " , " recusandae " , " itaque " , " earum " , " rerum " , " hic " , " tenetur " , " a " , " sapiente " , " delectus " , " ut " , " aut " , " reiciendis " , " voluptatibus " , " maiores " , " doloribus " , " asperiores " , " repellat " ]
let timestampNow : TimeInterval = Date ( ) . timeIntervalSince1970
let userSessionId : String = getUserHexEncodedPublicKey ( )
// MARK: - - - D M T h r e a d
var dmThreadRandomGenerator : ARC4RandomNumberGenerator = ARC4RandomNumberGenerator ( seed : dmRandomSeed )
logProgress ( " DM Threads " , " Start Generating \( dmThreadCount ) threads " )
( 0. . < dmThreadCount ) . forEach { threadIndex in
let data = Data ( ( 0. . < 16 ) . map { _ in UInt8 . random ( in : ( UInt8 . min . . . UInt8 . max ) , using : & dmThreadRandomGenerator ) } )
logProgress ( " DM Thread \( threadIndex ) " , " Start " )
let data = Data ( ( 0. . < 16 ) . map { _ in UInt8 . random ( in : ( UInt8 . min . . . UInt8 . max ) , using : & dmThreadRandomGenerator ) } )
let randomSessionId : String = KeyPairUtilities . generate ( from : data ) . x25519KeyPair . hexEncodedPublicKey
let isMessageRequest : Bool = Bool . random ( using : & dmThreadRandomGenerator )
let contactNameLength : Int = ( ( 5. . < 20 ) . randomElement ( using : & dmThreadRandomGenerator ) ? ? 0 )
let numMessages : Int = ( ( 0. . < maxMessagesPerThread ) . randomElement ( using : & dmThreadRandomGenerator ) ? ? 0 )
let numMessages : Int = ( messageRangePerThread [ threadIndex % messageRangePerThread . count ]
. randomElement ( using : & dmThreadRandomGenerator ) ? ? 0 )
// G e n e r a t e t h e t h r e a d
let thread : TSContactThread = TSContactThread . getOrCreateThread ( withContactSessionID : randomSessionId , transaction : transaction )
@ -121,23 +144,27 @@ enum MockDataGenerator {
. compactMap { _ in stringContent . randomElement ( using : & dmThreadRandomGenerator ) }
. joined ( )
contact . isApproved = ( ! isMessageRequest || Bool . random ( using : & dmThreadRandomGenerator ) )
contact . didApproveMe = ( ! isMessageRequest && Bool . random ( using : & dmThreadRandomGenerator ) )
contact . didApproveMe = (
! isMessageRequest &&
( ( ( 0. . < 10 ) . randomElement ( using : & dmThreadRandomGenerator ) ? ? 0 ) < 8 ) // 8 0 % a p p r o v e d t h e c u r r e n t u s e r
)
Storage . shared . setContact ( contact , using : transaction )
// G e n e r a t e t h e m e s s a g e h i s t o r y ( N o t e : U n a p p r o v e d m e s s a g e r e q u e s t s w i l l o n l y i n c l u d e i n c o m i n g m e s s a g e s )
logProgress ( " DM Thread \( threadIndex ) " , " Generate \( numMessages ) Messages " )
( 0. . < numMessages ) . forEach { index in
let isIncoming : Bool = (
Bool . random ( using : & dmThreadRandomGenerator ) &&
( ! isMessageRequest || contact . isApproved )
)
let message Length: Int = ( ( 3. . < 4 0) . randomElement ( using : & dmThreadRandomGenerator ) ? ? 0 )
let message Words: Int = ( ( 1. . < 2 0) . randomElement ( using : & dmThreadRandomGenerator ) ? ? 0 )
let message : VisibleMessage = VisibleMessage ( )
message . sender = ( isIncoming ? randomSessionId : userSessionId )
message . sentTimestamp = UInt64 ( floor ( timestampNow - Double ( index * 5 ) ) )
message . text = ( 0. . < message Length )
. compactMap { _ in string Content. randomElement ( using : & dmThreadRandomGenerator ) }
. joined ( )
message . sentTimestamp = UInt64 ( floor ( timestampNow - Double ( index * 5 ) ) * 1000 )
message . text = ( 0. . < message Words )
. compactMap { _ in word Content. randomElement ( using : & dmThreadRandomGenerator ) }
. joined ( separator : " " )
if isIncoming {
let tsMessage : TSOutgoingMessage = TSOutgoingMessage . from ( message , associatedWith : thread , using : transaction )
@ -151,23 +178,30 @@ enum MockDataGenerator {
// S a v e t h e t h r e a d
thread . save ( with : transaction )
logProgress ( " DM Thread \( threadIndex ) " , " Done " )
}
logProgress ( " DM Threads " , " Done " )
// MARK: - - - C l o s e d G r o u p
var cgThreadRandomGenerator : ARC4RandomNumberGenerator = ARC4RandomNumberGenerator ( seed : cgRandomSeed )
logProgress ( " Closed Group Threads " , " Start Generating \( closedGroupThreadCount ) threads " )
( 0. . < closedGroupThreadCount ) . forEach { threadIndex in
logProgress ( " Closed Group Thread \( threadIndex ) " , " Start " )
let data = Data ( ( 0. . < 16 ) . map { _ in UInt8 . random ( in : ( UInt8 . min . . . UInt8 . max ) , using : & cgThreadRandomGenerator ) } )
let randomGroupPublicKey : String = KeyPairUtilities . generate ( from : data ) . x25519KeyPair . hexEncodedPublicKey
let groupNameLength : Int = ( ( 5. . < 20 ) . randomElement ( using : & cgThreadRandomGenerator ) ? ? 0 )
let groupName : String = ( 0. . < groupNameLength )
. compactMap { _ in stringContent . randomElement ( using : & cgThreadRandomGenerator ) }
. joined ( )
let numGroupMembers : Int = ( ( 0. . < 5 ) . randomElement ( using : & cgThreadRandomGenerator ) ? ? 0 )
let numMessages : Int = ( ( 0. . < maxMessagesPerThread ) . randomElement ( using : & cgThreadRandomGenerator ) ? ? 0 )
let numGroupMembers : Int = ( ( 0. . < 10 ) . randomElement ( using : & cgThreadRandomGenerator ) ? ? 0 )
let numMessages : Int = ( messageRangePerThread [ threadIndex % messageRangePerThread . count ]
. randomElement ( using : & cgThreadRandomGenerator ) ? ? 0 )
// G e n e r a t e t h e C o n t a c t s i n t h e g r o u p
var members : [ String ] = [ userSessionId ]
logProgress ( " Closed Group Thread \( threadIndex ) " , " Generate \( numGroupMembers ) Contacts " )
( 0. . < numGroupMembers ) . forEach { _ in
let contactData = Data ( ( 0. . < 16 ) . map { _ in UInt8 . random ( in : ( UInt8 . min . . . UInt8 . max ) , using : & cgThreadRandomGenerator ) } )
@ -202,14 +236,16 @@ enum MockDataGenerator {
Storage . shared . addClosedGroupEncryptionKeyPair ( encryptionKeyPair , for : randomGroupPublicKey , using : transaction )
// G e n e r a t e t h e m e s s a g e h i s t o r y ( N o t e : U n a p p r o v e d m e s s a g e r e q u e s t s w i l l o n l y i n c l u d e i n c o m i n g m e s s a g e s )
logProgress ( " Closed Group Thread \( threadIndex ) " , " Generate \( numMessages ) Messages " )
( 0. . < numMessages ) . forEach { index in
let messageLength : Int = ( ( 3. . < 40 ) . randomElement ( using : & dmThreadRandomGenerator ) ? ? 0 )
let message Words: Int = ( ( 1. . < 20 ) . randomElement ( using : & cg ThreadRandomGenerator) ? ? 0 )
let message : VisibleMessage = VisibleMessage ( )
message . sender = ( members . randomElement ( using : & cgThreadRandomGenerator ) ? ? userSessionId )
message . sentTimestamp = UInt64 ( floor ( timestampNow - Double ( index * 5 ) ) )
message . text = ( 0. . < message Length )
. compactMap { _ in stringContent. randomElement ( using : & dm ThreadRandomGenerator) }
. joined ( )
message . sentTimestamp = UInt64 ( floor ( timestampNow - Double ( index * 5 ) ) * 1000 )
message . text = ( 0. . < message Words )
. compactMap { _ in wordContent. randomElement ( using : & cg ThreadRandomGenerator) }
. joined ( separator : " " )
if message . sender != userSessionId {
let tsMessage : TSOutgoingMessage = TSOutgoingMessage . from ( message , associatedWith : thread , using : transaction )
@ -223,14 +259,18 @@ enum MockDataGenerator {
// S a v e t h e t h r e a d
thread . save ( with : transaction )
logProgress ( " Closed Group Thread \( threadIndex ) " , " Done " )
}
logProgress ( " Closed Group Threads " , " Done " )
// MARK: - - - O p e n G r o u p
var ogThreadRandomGenerator : ARC4RandomNumberGenerator = ARC4RandomNumberGenerator ( seed : ogRandomSeed )
logProgress ( " Open Group Threads " , " Start Generating \( openGroupThreadCount ) threads " )
( 0. . < openGroupThreadCount ) . forEach { threadIndex in
let data = Data ( ( 0. . < 16 ) . map { _ in UInt8 . random ( in : ( UInt8 . min . . . UInt8 . max ) , using : & ogThreadRandomGenerator ) } )
let randomGroupPublicKey : String = KeyPairUtilities . generate ( from : data ) . x25519KeyPair . hexEncodedPublicKey
logProgress ( " Open Group Thread \( threadIndex ) " , " Start " )
let randomGroupPublicKey : String = ( ( 0. . < 32 ) . map { _ in UInt8 . random ( in : UInt8 . min . . . UInt8 . max , using : & dmThreadRandomGenerator ) } ) . toHexString ( )
let serverNameLength : Int = ( ( 5. . < 20 ) . randomElement ( using : & ogThreadRandomGenerator ) ? ? 0 )
let roomNameLength : Int = ( ( 5. . < 20 ) . randomElement ( using : & ogThreadRandomGenerator ) ? ? 0 )
let groupDescriptionLength : Int = ( ( 10. . < 50 ) . randomElement ( using : & ogThreadRandomGenerator ) ? ? 0 )
@ -243,11 +283,31 @@ enum MockDataGenerator {
let groupDescription : String = ( 0. . < groupDescriptionLength )
. compactMap { _ in stringContent . randomElement ( using : & ogThreadRandomGenerator ) }
. joined ( )
let numGroupMembers : Int = ( ( 0. . < 250 ) . randomElement ( using : & ogThreadRandomGenerator ) ? ? 0 )
let numMessages : Int = ( messageRangePerThread [ threadIndex % messageRangePerThread . count ]
. randomElement ( using : & ogThreadRandomGenerator ) ? ? 0 )
// G e n e r a t e t h e C o n t a c t s i n t h e g r o u p
var members : [ String ] = [ userSessionId ]
logProgress ( " Open Group Thread \( threadIndex ) " , " Generate \( numGroupMembers ) Contacts " )
( 0. . < numGroupMembers ) . forEach { _ in
let contactData = Data ( ( 0. . < 16 ) . map { _ in UInt8 . random ( in : ( UInt8 . min . . . UInt8 . max ) , using : & ogThreadRandomGenerator ) } )
let randomSessionId : String = KeyPairUtilities . generate ( from : contactData ) . x25519KeyPair . hexEncodedPublicKey
let contactNameLength : Int = ( ( 5. . < 20 ) . randomElement ( using : & ogThreadRandomGenerator ) ? ? 0 )
let contact = Contact ( sessionID : randomSessionId )
contact . name = ( 0. . < contactNameLength )
. compactMap { _ in stringContent . randomElement ( using : & ogThreadRandomGenerator ) }
. joined ( )
Storage . shared . setContact ( contact , using : transaction )
members . append ( randomSessionId )
}
// C r e a t e t h e o p e n g r o u p m o d e l a n d t h e t h r e a d
let openGroup : OpenGroup = OpenGroup (
server : serverName ,
room : roomName ,
server : openGroupBaseUrl ,
room : " MockData_ \( roomName ) " ,
publicKey : randomGroupPublicKey ,
name : roomName ,
groupDescription : groupDescription ,
@ -255,7 +315,7 @@ enum MockDataGenerator {
infoUpdates : 0
)
let groupId : Data = LKGroupUtilities . getEncodedOpenGroupIDAsData ( openGroup . id )
let model = TSGroupModel ( title : openGroup . name , memberIds : [ userSessionId ] , image : nil , groupId : groupId , groupType : . openGroup , adminIds : [ ] , moderatorIds : [ ] )
let model = TSGroupModel ( title : openGroup . name , memberIds : members , image : nil , groupId : groupId , groupType : . openGroup , adminIds : [ ] , moderatorIds : [ ] )
let thread = TSGroupThread . getOrCreateThread ( with : model , transaction : transaction )
thread . shouldBeVisible = true
@ -276,7 +336,34 @@ enum MockDataGenerator {
)
Storage . shared . setOpenGroupServer ( server , using : transaction )
// G e n e r a t e t h e m e s s a g e h i s t o r y ( N o t e : U n a p p r o v e d m e s s a g e r e q u e s t s w i l l o n l y i n c l u d e i n c o m i n g m e s s a g e s )
logProgress ( " Open Group Thread \( threadIndex ) " , " Generate \( numMessages ) Messages " )
( 0. . < numMessages ) . forEach { index in
let messageWords : Int = ( ( 1. . < 20 ) . randomElement ( using : & ogThreadRandomGenerator ) ? ? 0 )
let message : VisibleMessage = VisibleMessage ( )
message . sender = ( members . randomElement ( using : & ogThreadRandomGenerator ) ? ? userSessionId )
message . sentTimestamp = UInt64 ( floor ( timestampNow - Double ( index * 5 ) ) * 1000 )
message . text = ( 0. . < messageWords )
. compactMap { _ in wordContent . randomElement ( using : & ogThreadRandomGenerator ) }
. joined ( separator : " " )
if message . sender != userSessionId {
let tsMessage : TSOutgoingMessage = TSOutgoingMessage . from ( message , associatedWith : thread , using : transaction )
tsMessage . save ( with : transaction )
}
else {
let tsMessage : TSIncomingMessage = TSIncomingMessage . from ( message , quotedMessage : nil , linkPreview : nil , associatedWith : thread )
tsMessage . save ( with : transaction )
}
}
logProgress ( " Open Group Thread \( threadIndex ) " , " Done " )
}
logProgress ( " Open Group Threads " , " Done " )
logProgress ( " " , " Complete " )
}
}
}