1
1
package com.github.artemo24.dyrbok.analyzeusage
2
2
3
- import com.github.artemo24.dyrbok.backupandrestore.DyrBokBackupAndRestore
3
+ import com.github.artemo24.dyrbok.backupandrestore.main.DyrBokBackupAndRestore
4
+ import com.github.artemo24.dyrbok.backupandrestore.dataclasses.FirestoreObjects
5
+ import com.github.artemo24.dyrbok.backupandrestore.utilities.StorageUtilities
4
6
import java.io.FileInputStream
5
7
import java.util.Properties
6
8
7
9
8
10
fun main () {
9
- AnalyzeUsage ().analyzeUsage()
11
+ println ()
12
+
13
+ AnalyzeUsage ().analyzeAnimalsAndMediaItems()
14
+
15
+ // Disabled: AnalyzeUsage().analyzeUsageLogging()
10
16
}
11
17
12
18
13
19
class AnalyzeUsage {
14
- fun analyzeUsage () {
15
- println ()
20
+ fun analyzeAnimalsAndMediaItems () {
21
+ val firestoreObjects = readFirestoreObjects ()
16
22
17
- val backupProperties = Properties ()
18
- backupProperties.load(FileInputStream (" etc/dyrbok-backup.properties" ))
19
- // Later: val photoBucketUrl = backupProperties["photoBucketUrl"].toString()
20
- val jsonFilesDirectory = backupProperties[" outputDirectory" ].toString()
23
+ val animalsByAnimalSpecies = firestoreObjects.pets.groupBy { it.pet_type }
24
+
25
+ // Validation:
26
+ //
27
+ // - Each animal ID is unique.
28
+ // - todo: Each animal's unique name is unique.
29
+ // - todo: Each animal is only registered with one animal species.
30
+ // - The animal species (pet_type) should not be empty or equal to "unknown".
31
+ //
32
+ // - Each media item ID is unique.
33
+ // - Each media item URL is unique and can be downloaded.
34
+ // - Each media item is linked to exactly one animal.
21
35
22
- val backupAndRestore = DyrBokBackupAndRestore ()
23
- val firestoreObjects = backupAndRestore.readObjectsFromJsonFiles(inputDirectory = jsonFilesDirectory)
36
+ val animalIDsToAnimals = mutableMapOf<String , Any >()
37
+ val mediaItemIDsToMediaItems = mutableMapOf<String , Any >()
38
+ val mediaItemURLsToMediaItems = mutableMapOf<String , Any >()
39
+
40
+ animalsByAnimalSpecies.keys.sorted().forEach { animalSpecies ->
41
+ println (" === === === === === ===" )
42
+ println (animalSpecies)
43
+ animalsByAnimalSpecies[animalSpecies]
44
+ ?.sortedBy { it.getNameUnique() }
45
+ ?.forEach { animal ->
46
+ println (" - ${animal.getNameUnique()} (species: ${animal.pet_type} , ID: ${animal.pet_id} )" )
47
+
48
+ processUniqueField(animalIDsToAnimals, animal, animal.pet_id, objectDescription = " animal" , uniqueFieldDescription = " ID" )
49
+
50
+ if (animal.pet_type == " " ) {
51
+ println (" >>> Unexpected empty animal species for animal with ID '${animal.pet_id} '." )
52
+ }
53
+
54
+ firestoreObjects.mediaItems.filter { it.pet_id == animal.pet_id }.forEach { mediaItem ->
55
+ println (" + media item with URL '${StorageUtilities .getShortMediaItemUrl(mediaItem)} '." )
56
+
57
+ processUniqueField(
58
+ mediaItemIDsToMediaItems,
59
+ mediaItem,
60
+ mediaItem.media_item_id,
61
+ objectDescription = " media item" ,
62
+ uniqueFieldDescription = " ID"
63
+ )
64
+
65
+ val mediaItemUrl = mediaItem.photoUrl()
66
+ if (mediaItemUrl != null ) {
67
+ processUniqueField(
68
+ mediaItemURLsToMediaItems,
69
+ mediaItem,
70
+ mediaItemUrl,
71
+ objectDescription = " media item" ,
72
+ uniqueFieldDescription = " URL"
73
+ )
74
+
75
+ // todo: Check whether the media item can be downloaded.
76
+ } else {
77
+ println (" >>> Media item $mediaItem does not have a valid media item URL." )
78
+ }
79
+ }
80
+ }
81
+ println ()
82
+ }
83
+ }
84
+
85
+ private fun processUniqueField (
86
+ uniqueFieldsToObjects : MutableMap <String , Any >,
87
+ theObject : Any ,
88
+ uniqueField : String ,
89
+ objectDescription : String ,
90
+ uniqueFieldDescription : String
91
+ ) {
92
+ if (uniqueFieldsToObjects.contains(uniqueField)) {
93
+ println (" >>> Duplicate $objectDescription $uniqueFieldDescription '$uniqueField '." )
94
+ println (" >>> Previous $objectDescription : ${uniqueFieldsToObjects[uniqueField]} ." )
95
+ println (" >>> Current $objectDescription : ${theObject} ." )
96
+ } else {
97
+ uniqueFieldsToObjects[uniqueField] = theObject
98
+ }
99
+ }
100
+
101
+ @Suppress(" unused" )
102
+ fun analyzeUsageLogging () {
103
+ val firestoreObjects = readFirestoreObjects()
24
104
25
105
val animalMap = firestoreObjects.pets.associateBy { it.pet_id }
26
106
val usersMap = firestoreObjects.users.associateBy { it.user_id }
@@ -45,10 +125,22 @@ class AnalyzeUsage {
45
125
println (" ${logging.date_time} ${userAlias.padStart(length = 20 )} $sourceIndicator - $enhancedMessage " )
46
126
} else if (logging.message.contains(other = " quiz" )) {
47
127
println (" ${logging.date_time} ${userAlias.padStart(length = 20 )} - $message " )
48
- } // else: anonymize other types of messages.
128
+ } else {
129
+ // todo: Anonymize other types of messages. Search for all users names in each logging message.
130
+ println (" ${logging.date_time} ${userAlias.padStart(length = 20 )} - $message " )
131
+ }
49
132
}
50
133
51
134
println ()
52
- println (" (W): photo added from the website." )
135
+ println (" (W): media item added from the website." )
136
+ }
137
+
138
+ private fun readFirestoreObjects (): FirestoreObjects {
139
+ val backupProperties = Properties ()
140
+ backupProperties.load(FileInputStream (" etc/dyrbok-backup.properties" ))
141
+ val jsonFilesDirectory = backupProperties[" outputDirectory" ].toString()
142
+ // Later: val photoBucketUrl = backupProperties["photoBucketUrl"].toString()
143
+
144
+ return DyrBokBackupAndRestore ().readObjectsFromJsonFiles(inputDirectory = jsonFilesDirectory)
53
145
}
54
146
}
0 commit comments