fix: findscu go mkiso
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -78,31 +79,43 @@ func (s *DicomService) FetchDICOMMultiple(ctx context.Context, accessionNumbers
|
||||
default:
|
||||
}
|
||||
|
||||
exitCode, _, stderr, err := dicom.RunMoveSCU(
|
||||
ctx,
|
||||
s.cfg.DCMTK.Movescu,
|
||||
s.cfg.OurAE.AETitle,
|
||||
s.cfg.PACS.AETitle,
|
||||
s.cfg.PACS.Host,
|
||||
s.cfg.PACS.Port,
|
||||
port,
|
||||
acc,
|
||||
300, // 5 min timeout
|
||||
)
|
||||
studyUIDs, err := s.findStudyUIDs(ctx, acc)
|
||||
if err != nil {
|
||||
slog.Warn("movescu failed for accession",
|
||||
slog.Warn("findscu failed for accession",
|
||||
"accession", acc,
|
||||
"exit_code", exitCode,
|
||||
"stderr", stderr,
|
||||
"error", err,
|
||||
)
|
||||
// Continue with next accession — partial success is acceptable
|
||||
continue
|
||||
}
|
||||
slog.Info("movescu completed",
|
||||
"accession", acc,
|
||||
"exit_code", exitCode,
|
||||
)
|
||||
|
||||
for _, studyUID := range studyUIDs {
|
||||
exitCode, _, stderr, err := dicom.RunMoveSCUByStudyUID(
|
||||
ctx,
|
||||
s.cfg.DCMTK.Movescu,
|
||||
s.cfg.OurAE.AETitle,
|
||||
s.cfg.PACS.AETitle,
|
||||
s.cfg.PACS.Host,
|
||||
s.cfg.PACS.Port,
|
||||
port,
|
||||
studyUID,
|
||||
300, // 5 min timeout
|
||||
)
|
||||
if err != nil {
|
||||
slog.Warn("movescu failed for study uid",
|
||||
"accession", acc,
|
||||
"study_uid", studyUID,
|
||||
"exit_code", exitCode,
|
||||
"stderr", stderr,
|
||||
"error", err,
|
||||
)
|
||||
continue
|
||||
}
|
||||
slog.Info("movescu completed",
|
||||
"accession", acc,
|
||||
"study_uid", studyUID,
|
||||
"exit_code", exitCode,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Count files retrieved
|
||||
@@ -140,26 +153,33 @@ func (s *DicomService) fetchDICOMWithPort(ctx context.Context, accessionNumber,
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// Run movescu
|
||||
exitCode, _, stderr, err := dicom.RunMoveSCU(
|
||||
ctx,
|
||||
s.cfg.DCMTK.Movescu,
|
||||
s.cfg.OurAE.AETitle,
|
||||
s.cfg.PACS.AETitle,
|
||||
s.cfg.PACS.Host,
|
||||
s.cfg.PACS.Port,
|
||||
port,
|
||||
accessionNumber,
|
||||
300, // 5 min timeout
|
||||
)
|
||||
studyUIDs, err := s.findStudyUIDs(ctx, accessionNumber)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("movescu failed (exit %d): %s (stderr: %s)", exitCode, err, stderr)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
slog.Info("movescu completed",
|
||||
"accession", accessionNumber,
|
||||
"exit_code", exitCode,
|
||||
)
|
||||
for _, studyUID := range studyUIDs {
|
||||
exitCode, _, stderr, err := dicom.RunMoveSCUByStudyUID(
|
||||
ctx,
|
||||
s.cfg.DCMTK.Movescu,
|
||||
s.cfg.OurAE.AETitle,
|
||||
s.cfg.PACS.AETitle,
|
||||
s.cfg.PACS.Host,
|
||||
s.cfg.PACS.Port,
|
||||
port,
|
||||
studyUID,
|
||||
300, // 5 min timeout
|
||||
)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("movescu failed for study uid %q (exit %d): %s (stderr: %s)", studyUID, exitCode, err, stderr)
|
||||
}
|
||||
|
||||
slog.Info("movescu completed",
|
||||
"accession", accessionNumber,
|
||||
"study_uid", studyUID,
|
||||
"exit_code", exitCode,
|
||||
)
|
||||
}
|
||||
|
||||
// Count files
|
||||
filesCount, err = countFiles(destDir)
|
||||
@@ -174,6 +194,24 @@ func (s *DicomService) fetchDICOMWithPort(ctx context.Context, accessionNumber,
|
||||
return filesCount, nil
|
||||
}
|
||||
|
||||
func (s *DicomService) findStudyUIDs(ctx context.Context, accessionNumber string) ([]string, error) {
|
||||
findscuBin := filepath.Join(filepath.Dir(s.cfg.DCMTK.Movescu), "findscu")
|
||||
studyUIDs, _, stderr, err := dicom.RunFindSCUStudyUIDs(
|
||||
ctx,
|
||||
findscuBin,
|
||||
s.cfg.OurAE.AETitle,
|
||||
s.cfg.PACS.AETitle,
|
||||
s.cfg.PACS.Host,
|
||||
s.cfg.PACS.Port,
|
||||
accessionNumber,
|
||||
60,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("findscu failed for accession %q: %w (stderr: %s)", accessionNumber, err, stderr)
|
||||
}
|
||||
return studyUIDs, nil
|
||||
}
|
||||
|
||||
// waitForStorescpReady waits for storescp to start or detects early failure.
|
||||
func waitForStorescpReady(resultCh <-chan dicom.StorescpResult) error {
|
||||
select {
|
||||
|
||||
Reference in New Issue
Block a user