126 lines
3.7 KiB
Go
126 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
|
|
"google.golang.org/protobuf/types/known/emptypb"
|
|
)
|
|
|
|
const crashReportsDirectoryName = "crash_reports"
|
|
|
|
var crashReportFileOrder = []string{metadataFileName, nativeLogFileName, goLogFileName, configSnapshotFileName}
|
|
|
|
func (s *desktopService) ListCrashReports(ctx context.Context, empty *emptypb.Empty) (*CrashReportList, error) {
|
|
reportsDirectory, userID, err := s.daemon.reportCaller(ctx, crashReportsDirectoryName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
entries, err := os.ReadDir(reportsDirectory)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return &CrashReportList{}, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
reports := make([]*CrashReportEntry, 0, len(entries))
|
|
for _, entry := range entries {
|
|
if !entry.IsDir() {
|
|
continue
|
|
}
|
|
fullPath := filepath.Join(reportsDirectory, entry.Name())
|
|
if !reportOwnedBy(fullPath, userID) {
|
|
continue
|
|
}
|
|
reports = append(reports, &CrashReportEntry{
|
|
Name: entry.Name(),
|
|
CrashedAt: reportTime(fullPath, "crashedAt").UnixMilli(),
|
|
IsRead: reportIsRead(fullPath),
|
|
})
|
|
}
|
|
sort.Slice(reports, func(i, j int) bool {
|
|
return reports[i].CrashedAt > reports[j].CrashedAt
|
|
})
|
|
return &CrashReportList{Reports: reports}, nil
|
|
}
|
|
|
|
func (s *desktopService) ReadCrashReport(ctx context.Context, request *CrashReportRequest) (*CrashReportContent, error) {
|
|
reportsDirectory, userID, err := s.daemon.reportCaller(ctx, crashReportsDirectoryName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
fullPath, err := reportPathForUser(reportsDirectory, request.Name, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
files := make([]*CrashReportFile, 0, len(crashReportFileOrder))
|
|
for _, fileName := range crashReportFileOrder {
|
|
content, readError := os.ReadFile(filepath.Join(fullPath, fileName))
|
|
if readError != nil {
|
|
if os.IsNotExist(readError) {
|
|
continue
|
|
}
|
|
return nil, readError
|
|
}
|
|
files = append(files, &CrashReportFile{
|
|
Name: fileName,
|
|
Content: string(content),
|
|
})
|
|
}
|
|
return &CrashReportContent{Files: files}, nil
|
|
}
|
|
|
|
func (s *desktopService) MarkCrashReportRead(ctx context.Context, request *CrashReportRequest) (*emptypb.Empty, error) {
|
|
reportsDirectory, userID, err := s.daemon.reportCaller(ctx, crashReportsDirectoryName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
fullPath, err := reportPathForUser(reportsDirectory, request.Name, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = os.WriteFile(filepath.Join(fullPath, readMarkerFileName), nil, 0o600)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &emptypb.Empty{}, nil
|
|
}
|
|
|
|
func (s *desktopService) ExportCrashReport(ctx context.Context, request *CrashReportExportRequest) (*CrashReportArchive, error) {
|
|
reportsDirectory, userID, err := s.daemon.reportCaller(ctx, crashReportsDirectoryName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return exportReportArchive(reportsDirectory, request.Name, userID, request.WithConfiguration, request.WithLog, request.Encrypt)
|
|
}
|
|
|
|
func (s *desktopService) DeleteCrashReport(ctx context.Context, request *CrashReportRequest) (*emptypb.Empty, error) {
|
|
reportsDirectory, userID, err := s.daemon.reportCaller(ctx, crashReportsDirectoryName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
fullPath, err := reportPathForUser(reportsDirectory, request.Name, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = os.RemoveAll(fullPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &emptypb.Empty{}, nil
|
|
}
|
|
|
|
func (s *desktopService) DeleteAllCrashReports(ctx context.Context, empty *emptypb.Empty) (*emptypb.Empty, error) {
|
|
reportsDirectory, userID, err := s.daemon.reportCaller(ctx, crashReportsDirectoryName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = deleteReportsForUser(reportsDirectory, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &emptypb.Empty{}, nil
|
|
}
|