Completed
Push — master ( 99ade0...004bdb )
by Nicolas
04:25 queued 02:00
created

TranscodeAssetActivity::do_activity()   D

Complexity

Conditions 9
Paths 9

Size

Total Lines 103
Code Lines 54

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 103
rs 4.8196
cc 9
eloc 54
nc 9
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This class handles the transcoding activity
5
 * Based on the input file type we lunch the proper transcoder
6
 */
7
8
require_once __DIR__.'/BasicActivity.php';
9
10
use SA\CpeSdk;
11
12
class TranscodeAssetActivity extends BasicActivity
13
{
14
    const CONVERSION_TYPE_ERROR = "CONVERSION_TYPE_ERROR";
15
    const TMP_PATH_OPEN_FAIL    = "TMP_PATH_OPEN_FAIL";
16
17
    private $output;
18
    private $pathToOutputFiles;
19
    
20
    // Perform the activity
21
    public function do_activity($task)
22
    {
23
        // Save output object
24
        $this->output = $this->input->{'output_asset'};
25
        
26
        // Custom validation for transcoding. Set $this->output
27
        $this->validate_input();
28
        
29
        $this->cpeLogger->log_out(
30
            "INFO", 
31
            basename(__FILE__), 
32
            "Preparing Asset transcoding ...",
33
            $this->activityLogKey
34
        );
35
        
36
        // Call parent do_activity:
37
        // It download the input file we will process.
38
        parent::do_activity($task);
39
        
40
        // Set output path to store result files
41
        $this->set_output_path($task);
42
43
        // Result output
44
        $result = null;
45
46
        // Load the right transcoder base on input_type
47
        // Get asset detailed info
48
        switch ($this->input->{'input_asset'}->{'type'}) 
49
        {
50
        case self::VIDEO:
51
            require_once __DIR__.'/transcoders/VideoTranscoder.php';
52
53
            // Instanciate transcoder to output Videos
54
            $videoTranscoder = new VideoTranscoder($this, $task);
55
            
56
            // Check preset file, read its content and add its data to output object
57
            if ($this->output->{'type'} == self::VIDEO &&
58
                isset($this->output->{'preset'}))
59
            {
60
                // Validate output preset
61
                $videoTranscoder->validate_preset($this->output);
62
63
                // Set preset value
64
                $this->output->{'preset_values'} =
65
                    $videoTranscoder->get_preset_values($this->output);
66
            }
67
68
            # If we have metadata, we expect the output of ffprobe
69
            $metadata = null;
70
            if (isset($this->input->{'input_asset_metadata'})) 
71
                $metadata = $this->input->{'input_asset_metadata'};
72
                
73
            // Perform transcoding
74
            $result = $videoTranscoder->transcode_asset(
75
                $this->tmpPathInput,
76
                $this->pathToInputFile,
77
                $this->pathToOutputFiles,
78
                $metadata, 
79
                $this->output
80
            );
81
82
            unset($videoTranscoder);
83
84
            break;
85
        case self::IMAGE:
86
            require_once __DIR__.'/transcoders/ImageTranscoder.php';
87
            
88
            // Instanciate transcoder to output Images
89
            $imageTranscoder = new ImageTranscoder($this, $task);
90
91
            # If we have metadata, we expect the output of ffprobe
92
            $metadata = null;
93
            if (isset($this->input->{'input_asset_metadata'})) 
94
                $metadata = $this->input->{'input_asset_metadata'};
95
            
96
            // Perform transcoding
97
            $result = $imageTranscoder->transcode_asset(
98
                $this->tmpPathInput,
99
                $this->pathToInputFile,
100
                $this->pathToOutputFiles,
101
                $metadata, 
102
                $this->output
103
            );
104
            
105
            unset($imageTranscoder);
106
                
107
            break;
108
        case self::AUDIO:
109
                
110
            break;
111
        case self::DOC:
112
                
113
            break;
114
        default:
115
            throw new CpeSdk\CpeException("Unknown input asset 'type'! Abording ...", 
116
                self::UNKOWN_INPUT_TYPE);
117
        }
118
        
119
        // Upload resulting file
120
        $this->upload_result_files($task);
121
        
122
        return $result;
123
    }
124
125
    // Upload all output files to destination S3 bucket
126
    private function upload_result_files($task)
127
    {
128
        // Sanitize output bucket and file path "/"
129
        $s3Bucket = str_replace("//", "/",
130
            $this->output->{"bucket"});
131
132
        // XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
133
        // XXX: Add tmp workflowID to output bucket to seperate upload
134
        // XXX: For testing only !
135
        // $s3Bucket .= "/".$task["workflowExecution"]["workflowId"];
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
136
        // XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
137
138
        // Set S3 options
139
        $options = array("rrs" => false, "encrypt" => false);
140
        if (isset($this->output->{'s3_rrs'}) &&
141
            $this->output->{'s3_rrs'} == true) {
142
            $options['rrs'] = true;
143
        }
144
        if (isset($this->output->{'s3_encrypt'}) &&
145
            $this->output->{'s3_encrypt'} == true) {
146
            $options['encrypt'] = true;
147
        }
148
        
149
        // Open '$pathToOutputFiles' to read it and send all files to S3 bucket
150
        if (!$handle = opendir($this->pathToOutputFiles)) {
151
            throw new CpeSdk\CpeException("Can't open tmp path '$this->pathToOutputFiles'!", 
152
                self::TMP_PATH_OPEN_FAIL);
153
        }
154
        
155
        // Upload all resulting files sitting in $pathToOutputFiles to S3
156
        while ($entry = readdir($handle)) {
157
            if ($entry == "." || $entry == "..") {
158
                continue;
159
            }
160
161
            // Destination path on S3. Sanitizing
162
            $s3Location = $this->output->{'output_file_info'}['dirname']."/$entry";
163
            $s3Location = str_replace("//", "/", $s3Location);
164
            
165
            // Send to S3. We reference the callback s3_put_processing_callback
166
            // The callback ping back SWF so we stay alive
167
            $s3Output = $this->s3Utils->put_file_into_s3(
168
                $s3Bucket, 
169
                $s3Location,
170
                "$this->pathToOutputFiles/$entry", 
171
                $options, 
172
                array($this, "s3_put_processing_callback"), 
173
                $task
174
            );
175
            // We delete the TMP file once uploaded
176
            unlink("$this->pathToOutputFiles/$entry");
177
            
178
            $this->cpeLogger->log_out("INFO", basename(__FILE__), 
179
                $s3Output['msg'],
180
                $this->activityLogKey);
181
        }
182
    }
183
184
    private function set_output_path($task)
185
    {
186
        $this->pathToOutputFiles = self::TMP_FOLDER 
187
            . $task["workflowExecution"]["workflowId"]."/output/" 
188
            . $this->activityId;
189
        
190
        // Create TMP folder for output files
191
        $outputFileInfo = pathinfo($this->output->{'file'});
192
        $this->output->{'output_file_info'} = $outputFileInfo;
193
        $this->pathToOutputFiles .= "/".$outputFileInfo['dirname'];
194
        
195 View Code Duplication
        if (!file_exists($this->pathToOutputFiles)) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
196
        {
197
            if ($this->debug)
198
                $this->cpeLogger->log_out("INFO", basename(__FILE__), 
199
                    "Creating TMP output folder '".$this->pathToOutputFiles."'",
200
                    $this->activityLogKey);
201
202
            if (!mkdir($this->pathToOutputFiles, 0750, true))
203
                throw new CpeSdk\CpeException(
204
                    "Unable to create temporary folder '$this->pathToOutputFiles' !",
205
                    self::TMP_FOLDER_FAIL
206
                );
207
        }
208
    }
209
    
210
    // Perform custom validation on JSON input
211
    // Callback function used in $this->do_input_validation
212
    private function validate_input()
213
    {
214
        
215
        if ((
216
                $this->input->{'input_asset'}->{'type'} == self::VIDEO &&
217
                $this->output->{'type'} != self::VIDEO &&
218
                $this->output->{'type'} != self::THUMB &&
219
                $this->output->{'type'} != self::AUDIO
220
            )
221
            ||
222
            (
223
                $this->input->{'input_asset'}->{'type'} == self::IMAGE &&
224
                $this->output->{'type'} != self::IMAGE
225
            )
226
            ||
227
            (
228
                $this->input->{'input_asset'}->{'type'} == self::AUDIO &&
229
                $this->output->{'type'} != self::AUDIO
230
            )
231
            ||
232
            (
233
                $this->input->{'input_asset'}->{'type'} == self::DOC &&
234
                $this->output->{'type'} != self::DOC
235
            ))
236
        {
237
            throw new CpeSdk\CpeException("Can't convert that input asset 'type' (".$this->input->{'input_asset'}->{'type'}.") into this output asset 'type' (".$this->output->{'type'}.")! Abording.", 
238
                self::CONVERSION_TYPE_ERROR);
239
        }
240
    }
241
}
242
243
244