11package rawrecording
22
33import (
4+ "context"
45 "fmt"
56 "log"
67 "os"
@@ -19,7 +20,11 @@ type GlobalArgs struct {
1920 InputS3 string
2021 Output string
2122 Verbose bool
23+ CacheDir string
2224 WorkDir string
25+
26+ // resolvedInputPath is the local path to the input (after S3 download if needed)
27+ resolvedInputPath string
2328}
2429
2530func NewRootCmd () * cobra.Command {
@@ -51,6 +56,7 @@ func NewRootCmd() *cobra.Command {
5156 pf .String (FlagInputS3 , "" , DescInputS3 )
5257 pf .String (FlagOutput , "" , DescOutput )
5358 pf .Bool (FlagVerbose , false , DescVerbose )
59+ pf .String (FlagCacheDir , "" , DescCacheDir )
5460
5561 // Add subcommands
5662 cmd .AddCommand (
@@ -72,13 +78,20 @@ func getGlobalArgs(cmd *cobra.Command) (*GlobalArgs, error) {
7278 inputS3 , _ := cmd .Flags ().GetString (FlagInputS3 )
7379 output , _ := cmd .Flags ().GetString (FlagOutput )
7480 verbose , _ := cmd .Flags ().GetBool (FlagVerbose )
81+ cacheDir , _ := cmd .Flags ().GetString (FlagCacheDir )
82+
83+ // Use default cache directory if not specified
84+ if cacheDir == "" {
85+ cacheDir = GetDefaultCacheDir ()
86+ }
7587
7688 return & GlobalArgs {
7789 InputFile : inputFile ,
7890 InputDir : inputDir ,
7991 InputS3 : inputS3 ,
8092 Output : output ,
8193 Verbose : verbose ,
94+ CacheDir : cacheDir ,
8295 }, nil
8396}
8497
@@ -109,6 +122,36 @@ func validateGlobalArgs(globalArgs *GlobalArgs, requireOutput bool) error {
109122 return nil
110123}
111124
125+ // resolveInputPath resolves the input to a local path, downloading from S3 if necessary
126+ func resolveInputPath (ctx context.Context , globalArgs * GlobalArgs ) (string , error ) {
127+ // If already resolved, return cached path
128+ if globalArgs .resolvedInputPath != "" {
129+ return globalArgs .resolvedInputPath , nil
130+ }
131+
132+ var inputPath string
133+
134+ if globalArgs .InputFile != "" {
135+ inputPath = globalArgs .InputFile
136+ } else if globalArgs .InputDir != "" {
137+ inputPath = globalArgs .InputDir
138+ } else if globalArgs .InputS3 != "" {
139+ // Download from S3 (with caching)
140+ downloader := NewS3Downloader (globalArgs .CacheDir , globalArgs .Verbose )
141+ downloadedPath , err := downloader .Download (ctx , globalArgs .InputS3 )
142+ if err != nil {
143+ return "" , fmt .Errorf ("failed to download from S3: %w" , err )
144+ }
145+ inputPath = downloadedPath
146+ } else {
147+ return "" , fmt .Errorf ("no input specified" )
148+ }
149+
150+ // Cache the resolved path
151+ globalArgs .resolvedInputPath = inputPath
152+ return inputPath , nil
153+ }
154+
112155// validateInputArgs validates input arguments using mutually exclusive logic
113156func validateInputArgs (globalArgs * GlobalArgs , userID , sessionID , trackID string ) (* processing.RecordingMetadata , error ) {
114157 // Count how many filters are specified
@@ -128,13 +171,10 @@ func validateInputArgs(globalArgs *GlobalArgs, userID, sessionID, trackID string
128171 return nil , fmt .Errorf ("only one filter can be specified at a time: --%s, --%s, and --%s are mutually exclusive" , FlagUserID , FlagSessionID , FlagTrackID )
129172 }
130173
131- var inputPath string
132- if globalArgs .InputFile != "" {
133- inputPath = globalArgs .InputFile
134- } else if globalArgs .InputDir != "" {
135- inputPath = globalArgs .InputDir
136- } else {
137- return nil , fmt .Errorf ("S3 input not implemented yet" )
174+ // Resolve input path (download from S3 if needed)
175+ inputPath , err := resolveInputPath (context .Background (), globalArgs )
176+ if err != nil {
177+ return nil , err
138178 }
139179
140180 // Parse metadata to validate the single specified argument
@@ -202,9 +242,10 @@ func setupLogger(verbose bool) *processing.ProcessingLogger {
202242
203243// prepareWorkDir extracts the recording to a temp directory and returns the working directory
204244func prepareWorkDir (globalArgs * GlobalArgs , logger * processing.ProcessingLogger ) (string , func (), error ) {
205- path := globalArgs .InputFile
206- if path == "" {
207- path = globalArgs .InputDir
245+ // Resolve input path (download from S3 if needed)
246+ path , err := resolveInputPath (context .Background (), globalArgs )
247+ if err != nil {
248+ return "" , nil , err
208249 }
209250
210251 workingDir , cleanup , err := processing .ExtractToTempDir (path , logger )
0 commit comments