Skip to content

Commit

Permalink
feat: delete old videos Directory (openedx#326)
Browse files Browse the repository at this point in the history
feat: delete old videos Directory

- Delete all the videos and folders of old app

fix: LEARNER-9950
  • Loading branch information
omerhabib26 authored May 31, 2024
1 parent 3df3c05 commit 3e95560
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 7 deletions.
11 changes: 11 additions & 0 deletions app/src/main/java/org/openedx/app/AppViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.openedx.core.BaseViewModel
import org.openedx.core.SingleEventLiveData
import org.openedx.core.config.Config
import org.openedx.core.data.storage.CorePreferences
import org.openedx.core.utils.FileUtil

class AppViewModel(
private val config: Config,
Expand All @@ -21,6 +22,7 @@ class AppViewModel(
private val preferencesManager: CorePreferences,
private val dispatcher: CoroutineDispatcher,
private val analytics: AppAnalytics,
private val fileUtil: FileUtil,
) : BaseViewModel() {

private val _logoutUser = SingleEventLiveData<Unit>()
Expand All @@ -32,10 +34,14 @@ class AppViewModel(
private var logoutHandledAt: Long = 0

val isBranchEnabled get() = config.getBranchConfig().enabled
private val canResetAppDirectory get() = preferencesManager.canResetAppDirectory

override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
setUserId()
if (canResetAppDirectory) {
resetAppDirectory()
}
viewModelScope.launch {
notifier.notifier.collect { event ->
if (event is LogoutEvent && System.currentTimeMillis() - logoutHandledAt > 5000) {
Expand All @@ -60,6 +66,11 @@ class AppViewModel(
)
}

private fun resetAppDirectory() {
fileUtil.deleteOldAppDirectory()
preferencesManager.canResetAppDirectory = false
}

private fun setUserId() {
preferencesManager.user?.let {
analytics.setUserIdForSession(it.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
}
get() = getBoolean(APP_WAS_POSITIVE_RATED)

override var canResetAppDirectory: Boolean
set(value) {
saveBoolean(RESET_APP_DIRECTORY, value)
}
get() = getBoolean(RESET_APP_DIRECTORY, true)

override fun setCalendarSyncEventsDialogShown(courseName: String) {
saveBoolean(courseName.replaceSpace("_"), true)
}
Expand All @@ -172,5 +178,6 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
private const val VIDEO_SETTINGS_STREAMING_QUALITY = "video_settings_streaming_quality"
private const val VIDEO_SETTINGS_DOWNLOAD_QUALITY = "video_settings_download_quality"
private const val APP_CONFIG = "app_config"
private const val RESET_APP_DIRECTORY = "reset_app_directory"
}
}
2 changes: 1 addition & 1 deletion app/src/main/java/org/openedx/app/di/ScreenModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ import org.openedx.whatsnew.presentation.whatsnew.WhatsNewViewModel

val screenModule = module {

viewModel { AppViewModel(get(), get(), get(), get(), get(named("IODispatcher")), get()) }
viewModel { AppViewModel(get(), get(), get(), get(), get(named("IODispatcher")), get(), get()) }
viewModel { MainViewModel(get(), get(), get()) }

factory { AuthRepository(get(), get(), get()) }
Expand Down
35 changes: 32 additions & 3 deletions app/src/test/java/org/openedx/AppViewModelTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import org.openedx.app.system.notifier.AppNotifier
import org.openedx.app.system.notifier.LogoutEvent
import org.openedx.core.config.Config
import org.openedx.core.data.model.User
import org.openedx.core.utils.FileUtil

@ExperimentalCoroutinesApi
class AppViewModelTest {
Expand All @@ -42,6 +43,7 @@ class AppViewModelTest {
private val room = mockk<AppDatabase>()
private val preferencesManager = mockk<PreferencesManager>()
private val analytics = mockk<AppAnalytics>()
private val fileUtil = mockk<FileUtil>()

private val user = User(0, "", "", "")

Expand All @@ -60,8 +62,17 @@ class AppViewModelTest {
every { analytics.setUserIdForSession(any()) } returns Unit
every { preferencesManager.user } returns user
every { notifier.notifier } returns flow { }
every { preferencesManager.canResetAppDirectory } returns false
val viewModel =
AppViewModel(config, notifier, room, preferencesManager, dispatcher, analytics)
AppViewModel(
config,
notifier,
room,
preferencesManager,
dispatcher,
analytics,
fileUtil
)

val mockLifeCycleOwner: LifecycleOwner = mockk()
val lifecycleRegistry = LifecycleRegistry(mockLifeCycleOwner)
Expand All @@ -82,8 +93,17 @@ class AppViewModelTest {
every { preferencesManager.user } returns user
every { room.clearAllTables() } returns Unit
every { analytics.logoutEvent(true) } returns Unit
every { preferencesManager.canResetAppDirectory } returns false
val viewModel =
AppViewModel(config, notifier, room, preferencesManager, dispatcher, analytics)
AppViewModel(
config,
notifier,
room,
preferencesManager,
dispatcher,
analytics,
fileUtil
)

val mockLifeCycleOwner: LifecycleOwner = mockk()
val lifecycleRegistry = LifecycleRegistry(mockLifeCycleOwner)
Expand All @@ -106,8 +126,17 @@ class AppViewModelTest {
every { preferencesManager.user } returns user
every { room.clearAllTables() } returns Unit
every { analytics.logoutEvent(true) } returns Unit
every { preferencesManager.canResetAppDirectory } returns false
val viewModel =
AppViewModel(config, notifier, room, preferencesManager, dispatcher, analytics)
AppViewModel(
config,
notifier,
room,
preferencesManager,
dispatcher,
analytics,
fileUtil
)

val mockLifeCycleOwner: LifecycleOwner = mockk()
val lifecycleRegistry = LifecycleRegistry(mockLifeCycleOwner)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface CorePreferences {
var user: User?
var videoSettings: VideoSettings
var appConfig: AppConfig
var canResetAppDirectory: Boolean

fun clear()
}
43 changes: 42 additions & 1 deletion core/src/main/java/org/openedx/core/utils/FileUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import java.io.File
import java.util.Collections

class FileUtil(val context: Context) {

Expand All @@ -15,7 +16,10 @@ class FileUtil(val context: Context) {
return file
}

inline fun <reified T> saveObjectToFile(obj: T, fileName: String = "${T::class.java.simpleName}.json") {
inline fun <reified T> saveObjectToFile(
obj: T,
fileName: String = "${T::class.java.simpleName}.json",
) {
val gson: Gson = GsonBuilder().setPrettyPrinting().create()
val jsonString = gson.toJson(obj)
File(getExternalAppDir().path + fileName).writeText(jsonString)
Expand All @@ -31,6 +35,43 @@ class FileUtil(val context: Context) {
null
}
}

/**
* Deletes all the files and directories in the app's external storage directory.
*/
fun deleteOldAppDirectory() {
val externalFilesDir = context.getExternalFilesDir(null)
val externalAppDir = File(externalFilesDir?.parentFile, Directories.VIDEOS.name)
if (externalAppDir.isDirectory) {
deleteRecursive(externalAppDir, Collections.emptyList())
}
}

/**
* Deletes a file or directory and all its content recursively.
*
* @param fileOrDirectory The file or directory that needs to be deleted.
* @param exceptions Names of the files or directories that need to be skipped while deletion.
*/
private fun deleteRecursive(
fileOrDirectory: File,
exceptions: List<String>,
) {
if (exceptions.contains(fileOrDirectory.name)) return

if (fileOrDirectory.isDirectory) {
val filesList = fileOrDirectory.listFiles()
if (filesList != null) {
for (child in filesList) {
deleteRecursive(child, exceptions)
}
}
}

// Don't break the recursion upon encountering an error
// noinspection ResultOfMethodCallIgnored
fileOrDirectory.delete()
}
}

enum class Directories {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ private fun CourseItem(
apiHostUrl: String,
enrolledCourse: EnrolledCourse,
windowSize: WindowSize,
onClick: (EnrolledCourse) -> Unit
onClick: (EnrolledCourse) -> Unit,
) {
val imageWidth by remember(key1 = windowSize) {
mutableStateOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class DashboardListViewModel(
private val resourceManager: ResourceManager,
private val discoveryNotifier: DiscoveryNotifier,
private val analytics: DashboardAnalytics,
private val appUpgradeNotifier: AppUpgradeNotifier
private val appUpgradeNotifier: AppUpgradeNotifier,
) : BaseViewModel() {

private val coursesList = mutableListOf<EnrolledCourse>()
Expand Down

0 comments on commit 3e95560

Please sign in to comment.