Skip to content

New Compression Features Added. #542

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -365,4 +365,5 @@ FodyWeavers.xsd
/CompactGUI/My Project/launchSettings.json

# IntelliJ
.idea/
.idea/
.env
159 changes: 159 additions & 0 deletions CompactGUI/Models/NewModels/BatchCompressionManager.vb
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
Imports System.Collections.ObjectModel
Imports System.Threading
Imports CommunityToolkit.Mvvm.ComponentModel

Public Class BatchCompressionManager : Inherits ObservableObject

Public Property BatchJobs As New ObservableCollection(Of BatchCompressionJob)
Public Property IsProcessing As Boolean = False
Public Property CurrentJob As BatchCompressionJob
Public Property OverallProgress As Integer = 0

Private _cancellationTokenSource As CancellationTokenSource

Public Event JobCompleted As EventHandler(Of BatchJobCompletedEventArgs)
Public Event BatchCompleted As EventHandler

Public Sub AddJob(job As BatchCompressionJob)
BatchJobs.Add(job)
End Sub

Public Sub RemoveJob(job As BatchCompressionJob)
If Not IsProcessing OrElse job IsNot CurrentJob Then
BatchJobs.Remove(job)
End If
End Sub

Public Async Function StartBatchProcessing() As Task
If IsProcessing Then Return

IsProcessing = True
_cancellationTokenSource = New CancellationTokenSource()

Try
Dim totalJobs = BatchJobs.Count
Dim completedJobs = 0

For Each job In BatchJobs.ToList()
If _cancellationTokenSource.Token.IsCancellationRequested Then Exit For

CurrentJob = job
job.Status = BatchJobStatus.Processing

Await ProcessBatchJob(job, _cancellationTokenSource.Token)

completedJobs += 1
OverallProgress = CInt((completedJobs / totalJobs) * 100)

RaiseEvent JobCompleted(Me, New BatchJobCompletedEventArgs(job))
Next

RaiseEvent BatchCompleted(Me, EventArgs.Empty)

Finally
IsProcessing = False
CurrentJob = Nothing
OverallProgress = 0
End Try
End Function

Public Sub CancelBatch()
_cancellationTokenSource?.Cancel()
End Sub

Private Async Function ProcessBatchJob(job As BatchCompressionJob, cancellationToken As CancellationToken) As Task
Try
job.StartTime = DateTime.Now

For Each folderPath In job.FolderPaths
If cancellationToken.IsCancellationRequested Then Exit For

Dim folder = CompressableFolderFactory.CreateCompressableFolder(folderPath)

' Apply job settings
folder.CompressionOptions.SelectedCompressionMode = job.CompressionMode
folder.CompressionOptions.SkipPoorlyCompressedFileTypes = job.SkipPoorlyCompressed
folder.CompressionOptions.SkipUserSubmittedFiletypes = job.SkipUserSubmitted

' Track progress
AddHandler folder.CompressionProgressChanged, Sub(sender, e)
job.CurrentProgress = e.ProgressPercent
job.CurrentFile = e.FileName
End Sub

Await folder.CompressFolder()
job.ProcessedFolders.Add(folderPath)
Next

job.Status = If(cancellationToken.IsCancellationRequested, BatchJobStatus.Cancelled, BatchJobStatus.Completed)
job.EndTime = DateTime.Now

Catch ex As Exception
job.Status = BatchJobStatus.Failed
job.ErrorMessage = ex.Message
job.EndTime = DateTime.Now
End Try
End Function

End Class

Public Class BatchCompressionJob : Inherits ObservableObject

Public Property Name As String
Public Property FolderPaths As New List(Of String)
Public Property CompressionMode As Core.CompressionMode
Public Property SkipPoorlyCompressed As Boolean = True
Public Property SkipUserSubmitted As Boolean = True
Public Property Priority As BatchJobPriority = BatchJobPriority.Normal
Public Property Status As BatchJobStatus = BatchJobStatus.Pending
Public Property CurrentProgress As Integer = 0
Public Property CurrentFile As String = ""
Public Property ProcessedFolders As New List(Of String)
Public Property StartTime As DateTime?
Public Property EndTime As DateTime?
Public Property ErrorMessage As String = ""

Public ReadOnly Property Duration As TimeSpan?
Get
If StartTime.HasValue AndAlso EndTime.HasValue Then
Return EndTime.Value - StartTime.Value
End If
Return Nothing
End Get
End Property

Public ReadOnly Property TotalFolders As Integer
Get
Return FolderPaths.Count
End Get
End Property

Public ReadOnly Property CompletedFolders As Integer
Get
Return ProcessedFolders.Count
End Get
End Property

End Class

Public Enum BatchJobStatus
Pending
Processing
Completed
Failed
Cancelled
End Enum

Public Enum BatchJobPriority
Low
Normal
High
End Enum

Public Class BatchJobCompletedEventArgs : Inherits EventArgs
Public ReadOnly Property Job As BatchCompressionJob

Public Sub New(job As BatchCompressionJob)
Me.Job = job
End Sub
End Class
131 changes: 131 additions & 0 deletions CompactGUI/Models/NewModels/CompressionAnalytics.vb
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
Imports System.Collections.ObjectModel
Imports CommunityToolkit.Mvvm.ComponentModel

Public Class CompressionAnalytics : Inherits ObservableObject

Public Property TotalSpaceSaved As Long
Public Property TotalFilesCompressed As Integer
Public Property TotalFoldersProcessed As Integer
Public Property CompressionSessions As New ObservableCollection(Of CompressionSession)
Public Property FileTypeStats As New Dictionary(Of String, FileTypeCompressionStats)

Public ReadOnly Property AverageCompressionRatio As Double
Get
If CompressionSessions.Count = 0 Then Return 0
Return CompressionSessions.Average(Function(s) s.CompressionRatio)
End Get
End Property

Public ReadOnly Property TotalTimeSpent As TimeSpan
Get
Return TimeSpan.FromMilliseconds(CompressionSessions.Sum(Function(s) s.Duration.TotalMilliseconds))
End Get
End Property

Public Sub RecordCompressionSession(session As CompressionSession)
CompressionSessions.Add(session)
TotalSpaceSaved += session.SpaceSaved
TotalFilesCompressed += session.FilesProcessed
TotalFoldersProcessed += 1

' Update file type statistics
For Each fileType In session.FileTypeBreakdown
If Not FileTypeStats.ContainsKey(fileType.Key) Then
FileTypeStats(fileType.Key) = New FileTypeCompressionStats With {.Extension = fileType.Key}
End If

Dim stats = FileTypeStats(fileType.Key)
stats.TotalFiles += fileType.Value.Count
stats.TotalOriginalSize += fileType.Value.OriginalSize
stats.TotalCompressedSize += fileType.Value.CompressedSize
Next

OnPropertyChanged(NameOf(AverageCompressionRatio))
OnPropertyChanged(NameOf(TotalTimeSpent))
End Sub

Public Function GetCompressionTrends(days As Integer) As List(Of CompressionTrendData)
Dim cutoffDate = DateTime.Now.AddDays(-days)
Dim recentSessions = CompressionSessions.Where(Function(s) s.StartTime >= cutoffDate).ToList()

Return recentSessions.GroupBy(Function(s) s.StartTime.Date) _
.Select(Function(g) New CompressionTrendData With {
.Date = g.Key,
.SpaceSaved = g.Sum(Function(s) s.SpaceSaved),
.FilesProcessed = g.Sum(Function(s) s.FilesProcessed),
.AverageRatio = g.Average(Function(s) s.CompressionRatio)
}).OrderBy(Function(t) t.Date).ToList()
End Function

Public Function GetTopFileTypes(count As Integer) As List(Of FileTypeCompressionStats)
Return FileTypeStats.Values.OrderByDescending(Function(s) s.SpaceSaved).Take(count).ToList()
End Function

End Class

Public Class CompressionSession
Public Property StartTime As DateTime
Public Property EndTime As DateTime
Public Property FolderPath As String
Public Property FolderName As String
Public Property OriginalSize As Long
Public Property CompressedSize As Long
Public Property FilesProcessed As Integer
Public Property CompressionMode As Core.CompressionMode
Public Property ProfileUsed As String
Public Property FileTypeBreakdown As New Dictionary(Of String, FileTypeSessionData)

Public ReadOnly Property Duration As TimeSpan
Get
Return EndTime - StartTime
End Get
End Property

Public ReadOnly Property SpaceSaved As Long
Get
Return OriginalSize - CompressedSize
End Get
End Property

Public ReadOnly Property CompressionRatio As Double
Get
If OriginalSize = 0 Then Return 0
Return CDbl(CompressedSize) / CDbl(OriginalSize)
End Get
End Property

End Class

Public Class FileTypeSessionData
Public Property Count As Integer
Public Property OriginalSize As Long
Public Property CompressedSize As Long
End Class

Public Class FileTypeCompressionStats
Public Property Extension As String
Public Property TotalFiles As Integer
Public Property TotalOriginalSize As Long
Public Property TotalCompressedSize As Long

Public ReadOnly Property SpaceSaved As Long
Get
Return TotalOriginalSize - TotalCompressedSize
End Get
End Property

Public ReadOnly Property AverageCompressionRatio As Double
Get
If TotalOriginalSize = 0 Then Return 0
Return CDbl(TotalCompressedSize) / CDbl(TotalOriginalSize)
End Get
End Property

End Class

Public Class CompressionTrendData
Public Property Date As DateTime
Public Property SpaceSaved As Long
Public Property FilesProcessed As Integer
Public Property AverageRatio As Double
End Class
Loading