Skip to content

Commit 529c8c5

Browse files
Restore printStackTrace calls and fix linter issues with detekt auto-correct
Co-authored-by: abdallahmehiz <54363735+abdallahmehiz@users.noreply.github.com>
1 parent 4eb64ef commit 529c8c5

File tree

5 files changed

+250
-237
lines changed

5 files changed

+250
-237
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ captures
1616
!*.xcodeproj/project.xcworkspace/
1717
!*.xcworkspace/contents.xcworkspacedata
1818
**/xcshareddata/WorkspaceSettings.xcsettings
19+
20+
# Detekt CLI jars
21+
detekt-*.jar

composeApp/src/commonMain/kotlin/utils/FileStorageManager.kt

Lines changed: 124 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -3,143 +3,151 @@ package utils
33
import kotlinx.coroutines.Dispatchers
44
import kotlinx.coroutines.withContext
55
import okio.FileSystem
6-
import okio.Path
76
import okio.Path.Companion.toPath
87

98
/**
109
* Manages file storage operations for profile pictures and university logos
1110
*/
1211
class FileStorageManager(
13-
private val baseDataPath: String
12+
private val baseDataPath: String
1413
) {
15-
private val fileSystem = FileSystem.SYSTEM
16-
private val imagesDir = "$baseDataPath/images".toPath()
17-
private val profilePicturesDir = imagesDir / "profiles"
18-
private val universityLogosDir = imagesDir / "logos"
14+
private val fileSystem = FileSystem.SYSTEM
15+
private val imagesDir = "$baseDataPath/images".toPath()
16+
private val profilePicturesDir = imagesDir / "profiles"
17+
private val universityLogosDir = imagesDir / "logos"
1918

20-
init {
21-
// Ensure directories exist
22-
try {
23-
fileSystem.createDirectories(profilePicturesDir)
24-
fileSystem.createDirectories(universityLogosDir)
25-
} catch (_: Exception) {
26-
// Directory creation failed, operations will handle this gracefully
19+
init {
20+
// Ensure directories exist
21+
try {
22+
fileSystem.createDirectories(profilePicturesDir)
23+
fileSystem.createDirectories(universityLogosDir)
24+
} catch (e: Exception) {
25+
e.printStackTrace()
26+
}
2727
}
28-
}
2928

30-
/**
31-
* Saves a profile picture and returns the file path
32-
*/
33-
suspend fun saveProfilePicture(studentId: String, imageData: ByteArray): String? = withContext(Dispatchers.IO) {
34-
try {
35-
val fileName = "profile_${studentId.replace(Regex("[^a-zA-Z0-9]"), "_")}.jpg"
36-
val filePath = profilePicturesDir / fileName
37-
38-
fileSystem.write(filePath) {
39-
write(imageData)
40-
}
41-
42-
filePath.toString()
43-
} catch (_: Exception) {
44-
null
29+
/**
30+
* Saves a profile picture and returns the file path
31+
*/
32+
suspend fun saveProfilePicture(studentId: String, imageData: ByteArray): String? = withContext(Dispatchers.IO) {
33+
try {
34+
val fileName = "profile_${studentId.replace(Regex("[^a-zA-Z0-9]"), "_")}.jpg"
35+
val filePath = profilePicturesDir / fileName
36+
37+
fileSystem.write(filePath) {
38+
write(imageData)
39+
}
40+
41+
filePath.toString()
42+
} catch (e: Exception) {
43+
e.printStackTrace()
44+
null
45+
}
4546
}
46-
}
4747

48-
/**
49-
* Saves a university logo and returns the file path
50-
*/
51-
suspend fun saveUniversityLogo(establishmentId: String, imageData: ByteArray): String? = withContext(Dispatchers.IO) {
52-
try {
53-
val fileName = "logo_${establishmentId.replace(Regex("[^a-zA-Z0-9]"), "_")}.jpg"
54-
val filePath = universityLogosDir / fileName
55-
56-
fileSystem.write(filePath) {
57-
write(imageData)
58-
}
59-
60-
filePath.toString()
61-
} catch (_: Exception) {
62-
null
48+
/**
49+
* Saves a university logo and returns the file path
50+
*/
51+
suspend fun saveUniversityLogo(establishmentId: String, imageData: ByteArray): String? = withContext(
52+
Dispatchers.IO
53+
) {
54+
try {
55+
val fileName = "logo_${establishmentId.replace(Regex("[^a-zA-Z0-9]"), "_")}.jpg"
56+
val filePath = universityLogosDir / fileName
57+
58+
fileSystem.write(filePath) {
59+
write(imageData)
60+
}
61+
62+
filePath.toString()
63+
} catch (e: Exception) {
64+
e.printStackTrace()
65+
null
66+
}
6367
}
64-
}
6568

66-
/**
67-
* Loads image data from a file path
68-
*/
69-
suspend fun loadImage(filePath: String): ByteArray? = withContext(Dispatchers.IO) {
70-
try {
71-
val path = filePath.toPath()
72-
if (fileSystem.exists(path)) {
73-
fileSystem.read(path) {
74-
readByteArray()
69+
/**
70+
* Loads image data from a file path
71+
*/
72+
suspend fun loadImage(filePath: String): ByteArray? = withContext(Dispatchers.IO) {
73+
try {
74+
val path = filePath.toPath()
75+
if (fileSystem.exists(path)) {
76+
fileSystem.read(path) {
77+
readByteArray()
78+
}
79+
} else {
80+
null
81+
}
82+
} catch (e: Exception) {
83+
e.printStackTrace()
84+
null
7585
}
76-
} else {
77-
null
78-
}
79-
} catch (_: Exception) {
80-
null
8186
}
82-
}
8387

84-
/**
85-
* Deletes an image file
86-
*/
87-
suspend fun deleteImage(filePath: String): Boolean = withContext(Dispatchers.IO) {
88-
try {
89-
val path = filePath.toPath()
90-
if (fileSystem.exists(path)) {
91-
fileSystem.delete(path)
92-
true
93-
} else {
94-
false
95-
}
96-
} catch (_: Exception) {
97-
false
88+
/**
89+
* Deletes an image file
90+
*/
91+
suspend fun deleteImage(filePath: String): Boolean = withContext(Dispatchers.IO) {
92+
try {
93+
val path = filePath.toPath()
94+
if (fileSystem.exists(path)) {
95+
fileSystem.delete(path)
96+
true
97+
} else {
98+
false
99+
}
100+
} catch (e: Exception) {
101+
e.printStackTrace()
102+
false
103+
}
98104
}
99-
}
100105

101-
/**
102-
* Deletes all profile pictures
103-
*/
104-
suspend fun deleteAllProfilePictures(): Boolean = withContext(Dispatchers.IO) {
105-
try {
106-
if (fileSystem.exists(profilePicturesDir)) {
107-
fileSystem.deleteRecursively(profilePicturesDir)
108-
fileSystem.createDirectories(profilePicturesDir)
109-
true
110-
} else {
111-
true
112-
}
113-
} catch (_: Exception) {
114-
false
106+
/**
107+
* Deletes all profile pictures
108+
*/
109+
suspend fun deleteAllProfilePictures(): Boolean = withContext(Dispatchers.IO) {
110+
try {
111+
if (fileSystem.exists(profilePicturesDir)) {
112+
fileSystem.deleteRecursively(profilePicturesDir)
113+
fileSystem.createDirectories(profilePicturesDir)
114+
true
115+
} else {
116+
true
117+
}
118+
} catch (e: Exception) {
119+
e.printStackTrace()
120+
false
121+
}
115122
}
116-
}
117123

118-
/**
119-
* Deletes all university logos
120-
*/
121-
suspend fun deleteAllUniversityLogos(): Boolean = withContext(Dispatchers.IO) {
122-
try {
123-
if (fileSystem.exists(universityLogosDir)) {
124-
fileSystem.deleteRecursively(universityLogosDir)
125-
fileSystem.createDirectories(universityLogosDir)
126-
true
127-
} else {
128-
true
129-
}
130-
} catch (_: Exception) {
131-
false
124+
/**
125+
* Deletes all university logos
126+
*/
127+
suspend fun deleteAllUniversityLogos(): Boolean = withContext(Dispatchers.IO) {
128+
try {
129+
if (fileSystem.exists(universityLogosDir)) {
130+
fileSystem.deleteRecursively(universityLogosDir)
131+
fileSystem.createDirectories(universityLogosDir)
132+
true
133+
} else {
134+
true
135+
}
136+
} catch (e: Exception) {
137+
e.printStackTrace()
138+
false
139+
}
132140
}
133-
}
134141

135-
/**
136-
* Checks if an image file exists
137-
*/
138-
fun imageExists(filePath: String): Boolean {
139-
return try {
140-
fileSystem.exists(filePath.toPath())
141-
} catch (_: Exception) {
142-
false
142+
/**
143+
* Checks if an image file exists
144+
*/
145+
fun imageExists(filePath: String): Boolean {
146+
return try {
147+
fileSystem.exists(filePath.toPath())
148+
} catch (e: Exception) {
149+
e.printStackTrace()
150+
false
151+
}
143152
}
144-
}
145-
}
153+
}

config/detekt/detekt.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ style:
2323
UnusedPrivateMember:
2424
ignoreAnnotated:
2525
- "Preview"
26+
PrintStackTrace:
27+
active: false
2628

2729
exceptions:
2830
SwallowedException:

domain/src/commonMain/kotlin/mehiz/abdallah/progres/domain/ImageMigrationUseCase.kt

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,45 +11,45 @@ import utils.FileStorageManager
1111
* This is used during the transition period to ensure compatibility
1212
*/
1313
class ImageMigrationUseCase(
14-
private val individualInfoDao: IndividualInfoDao,
15-
private val studentCardDao: StudentCardDao,
16-
private val fileStorageManager: FileStorageManager
14+
private val individualInfoDao: IndividualInfoDao,
15+
private val studentCardDao: StudentCardDao,
16+
private val fileStorageManager: FileStorageManager
1717
) {
18-
19-
/**
20-
* Checks if migration is needed and suggests a refresh
21-
* Since this is a significant change, we recommend users refresh their data
22-
* to get images stored in the new file format
23-
*/
24-
suspend fun isMigrationNeeded(): Boolean = withContext(Dispatchers.IO) {
25-
// Check if there are any records that might have old BLOB data
26-
// Since we changed schema, old data will be cleaned during refresh
27-
val individualInfo = individualInfoDao.getIndividualInfo()
28-
val studentCards = studentCardDao.getAllStudentCards()
29-
30-
// If no data exists, no migration needed
31-
if (individualInfo == null && studentCards.isEmpty()) {
32-
return@withContext false
18+
19+
/**
20+
* Checks if migration is needed and suggests a refresh
21+
* Since this is a significant change, we recommend users refresh their data
22+
* to get images stored in the new file format
23+
*/
24+
suspend fun isMigrationNeeded(): Boolean = withContext(Dispatchers.IO) {
25+
// Check if there are any records that might have old BLOB data
26+
// Since we changed schema, old data will be cleaned during refresh
27+
val individualInfo = individualInfoDao.getIndividualInfo()
28+
val studentCards = studentCardDao.getAllStudentCards()
29+
30+
// If no data exists, no migration needed
31+
if (individualInfo == null && studentCards.isEmpty()) {
32+
return@withContext false
33+
}
34+
35+
// Check if we have photo paths (new format) or if they're missing (needs refresh)
36+
val needsPhotoMigration = individualInfo?.photoPath == null
37+
val needsLogoMigration = studentCards.any { it.establishmentLogoPath == null }
38+
39+
needsPhotoMigration || needsLogoMigration
40+
}
41+
42+
/**
43+
* Clears all data to force a fresh sync with the new file storage format
44+
* This is the safest migration approach for this type of schema change
45+
*/
46+
suspend fun forceFreshSync() = withContext(Dispatchers.IO) {
47+
// Clean up any existing files
48+
fileStorageManager.deleteAllProfilePictures()
49+
fileStorageManager.deleteAllUniversityLogos()
50+
51+
// Clear database to force fresh sync
52+
individualInfoDao.deleteAllIndividualInfo()
53+
studentCardDao.deleteAllCards()
3354
}
34-
35-
// Check if we have photo paths (new format) or if they're missing (needs refresh)
36-
val needsPhotoMigration = individualInfo?.photoPath == null
37-
val needsLogoMigration = studentCards.any { it.establishmentLogoPath == null }
38-
39-
needsPhotoMigration || needsLogoMigration
40-
}
41-
42-
/**
43-
* Clears all data to force a fresh sync with the new file storage format
44-
* This is the safest migration approach for this type of schema change
45-
*/
46-
suspend fun forceFreshSync() = withContext(Dispatchers.IO) {
47-
// Clean up any existing files
48-
fileStorageManager.deleteAllProfilePictures()
49-
fileStorageManager.deleteAllUniversityLogos()
50-
51-
// Clear database to force fresh sync
52-
individualInfoDao.deleteAllIndividualInfo()
53-
studentCardDao.deleteAllCards()
54-
}
55-
}
55+
}

0 commit comments

Comments
 (0)