Completed
Pull Request — master (#93)
by Janis
04:38
created

FileService::buildTargetNotForShared()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 27
Code Lines 12

Duplication

Lines 7
Ratio 25.93 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 7
loc 27
ccs 0
cts 0
cp 0
rs 8.8571
c 1
b 0
f 0
cc 3
eloc 12
nc 4
nop 1
crap 12
1
<?php
2
3
/**
4
 * Nextcloud - OCR
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later.
7
 * See the COPYING file.
8
 * 
9
 * @author Janis Koehr <[email protected]>
10
 * @copyright Janis Koehr 2017
11
 */
12
namespace OCA\Ocr\Service;
13
14
use OCA\Ocr\Db\FileMapper;
15
use OCA\Ocr\Db\File;
16
use OCP\ILogger;
17
use OCA\Ocr\Db\ShareMapper;
18
use OCP\IL10N;
19
use OCA\Ocr\Constants\OcrConstants;
20
21
22
/**
23
 * Class FileService
24
 * 
25
 * @package OCA\Ocr\Service
26
 */
27
class FileService {
28
29
    /**
30
     *
31
     * @var ILogger
32
     */
33
    private $logger;
34
35
    /**
36
     *
37
     * @var FileMapper
38
     */
39
    private $fileMapper;
40
41
    /**
42
     *
43
     * @var ShareMapper
44
     */
45
    private $shareMapper;
46
47
    /**
48
     *
49
     * @var string
50
     */
51
    private $userId;
52
53
    /**
54
     *
55
     * @var IL10N
56
     */
57
    private $l10n;
58
59 8
    public function __construct(IL10N $l10n, ILogger $logger, $userId, FileMapper $fileMapper, ShareMapper $shareMapper) {
60 8
        $this->l10n = $l10n;
61 8
        $this->logger = $logger;
62 8
        $this->userId = $userId;
63 8
        $this->fileMapper = $fileMapper;
64 8
        $this->shareMapper = $shareMapper;
65 8
    }
66
67
    /**
68
     * Checks if shared with the process initiator
69
     * 
70
     * @param File $fileInfo            
71
     * @return boolean
72
     */
73 2
    public function checkSharedWithInitiator($fileInfo) {
74 2
        $owner = str_replace('home::', '', $fileInfo->getStoragename());
75 2
        if ($this->userId === $owner) {
76
            // user is owner (no shared file)
77 1
            return false;
78
        } else {
79
            // user is not owner (shared file)
80 1
            return true;
81
        }
82
    }
83
84
    /**
85
     * Builds the target name.
86
     * 
87
     * @param File $fileInfo            
88
     * @param boolean $shared            
89
     * @return string
90
     */
91
    public function buildTarget($fileInfo, $shared) {
92
        if ($shared) {
93
            $target = $this->buildTargetForShared($fileInfo);
94
        } else {
95
            $target = $this->buildTargetNotForShared($fileInfo);
96
        }
97
        return $target;
98
    }
99
100
    /**
101
     * Builds the source name.
102
     * 
103
     * @param File $fileInfo            
104
     * @param boolean $shared            
105
     * @return string
106
     */
107
    public function buildSource($fileInfo, $shared) {
108
        $source = $fileInfo->getPath();
109
        if ($shared) {
110
            $source = str_replace('home::', '', $fileInfo->getStoragename()) . '/' . $source;
111
        } else {
112
            $source = $this->userId . '/' . $source;
113
        }
114
        return $source;
115
    }
116
117
    /**
118
     * Returns the fileInfo for each file in files and checks
119
     * if it has a allowed MIME type and some other conditions.
120
     * 
121
     * @param array $files            
122
     * @return File[]
123
     * @throws NotFoundException
124
     */
125
    public function buildFileInfo($files) {
126
        $fileArray = array();
127
        foreach ($files as $file) {
128
            // Check if anything is missing and file type is correct
129
            if (!empty($file['id'])) {
130
                $fileInfo = $this->fileMapper->find($file['id']);
131
                $this->checkMimeType($fileInfo);
132
                array_push($fileArray, $fileInfo);
133
            } else {
134
                throw new NotFoundException($this->l10n->t('Wrong parameter.'));
135
            }
136
        }
137
        return $fileArray;
138
    }
139
140
    /**
141
     * Determines the correct type for the ocr process worker.
142
     * 
143
     * @param File $fileInfo            
144
     * @return integer
145
     */
146
    public function getCorrectType($fileInfo) {
147
        if ($fileInfo->getMimetype() === OcrConstants::MIME_TYPE_PDF) {
148
            return OcrConstants::OCRmyPDF;
149
        } else {
150
            return OcrConstants::TESSERACT;
151
        }
152
    }
153
154
    /**
155
     * Executes the exec function with a remove statement for a given file path.
156
     * @codeCoverageIgnore
157
     * 
158
     * @param string $pathToFile            
159
     */
160
    public function execRemove($pathToFile) {
161
        exec('rm ' . $pathToFile);
162
    }
163
164
    /**
165
     * Wraps the static file_get_contents method of php.
166
     * @codeCoverageIgnore
167
     * 
168
     * @param string $pathToFile            
169
     * @return string
170
     */
171
    public function getFileContents($pathToFile) {
172
        return file_get_contents($pathToFile);
173
    }
174
175
    /**
176
     * Wraps the static file_exists method of php.
177
     * @codeCoverageIgnore
178
     * 
179
     * @param string $pathToFile            
180
     * @return boolean
181
     */
182
    public function fileExists($pathToFile) {
183
        return file_exists($pathToFile);
184
    }
185
186
    /**
187
     * Wraps the static function \OCP\Files::buildNotExistingFileName() in order to be able to test everything else.
188
     * @codeCoverageIgnore
189
     * 
190
     * @param string $filePath            
191
     * @param string $fileName            
192
     * @return string
193
     */
194
    public function buildNotExistingFilename($filePath, $fileName) {
195
        return \OCP\Files::buildNotExistingFileName($filePath, $fileName . '_OCR.pdf');
196
    }
197
198
    /**
199
     * Returns a not existing file name for pdf or image processing
200
     * protected as of testing issues with static methods.
201
     * (Actually
202
     * it will be mocked partially) FIXME: Change this behaviour as soon as the buidlNotExistingFileName function is not
203
     * static anymore
204
     * @codeCoverageIgnore
205
     * 
206
     * @param File $fileInfo            
207
     * @return string
208
     */
209
    private function buildTargetForShared(File $fileInfo) {
210
        $share = $this->shareMapper->find($fileInfo->getFileid(), $this->userId, 
211
                str_replace('home::', '', $fileInfo->getStoragename()));
212
        // get rid of the .png or .pdf and so on
213
        // '/thedom.png' => '/thedom' || '/Test/thedom.png' => '/Test/thedom'
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% 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...
214
        $fileName = substr($share->getFileTarget(), 0, (strrpos($share->getFileTarget(), '.')));
215
        // remove everything in front of and including of the first appearance of a slash from behind
216
        // '/thedom' => 'thedom' || '/Test/thedom' => 'thedom'
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% 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...
217
        $fileName = substr(strrchr($fileName, "/"), 1);
218
        // eliminate the file name from the path
219
        // '/thedom.png' => '/' || '/Test/thedom.png' => '/Test'
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% 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...
220
        $filePath = dirname($share->getFileTarget());
221
        // replace the first slash
222
        $pos = strpos($filePath, '/');
223
        if ($pos !== false) {
224
            // '/' => '' || '/Test/' => 'Test'
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% 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...
225
            $filePath = substr_replace($filePath, '', $pos, strlen('/'));
226
        }
227 View Code Duplication
        if ($fileInfo->getMimetype() === OcrConstants::MIME_TYPE_PDF) {
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...
228
            // PDFs:
229
            return $this->buildNotExistingFilename($filePath, $fileName . '_OCR.pdf');
230
        } else {
231
            // IMAGES:
232
            return $this->buildNotExistingFilename($filePath, $fileName . '_OCR.txt');
233
        }
234
    }
235
236
    /**
237
     * Returns a not existing file name for PDF or image processing
238
     * protected as of testing issues with static methods.
239
     * (Actually
240
     * it will be mocked partially) FIXME: Change this behaviour as soon as the buidlNotExistingFileName function is not
241
     * static anymore
242
     * @codeCoverageIgnore
243
     * 
244
     * @param File $fileInfo            
245
     * @return string
246
     */
247
    private function buildTargetNotForShared(File $fileInfo) {
248
        // get rid of the .png or .pdf and so on
249
        // 'thedom.png' => 'thedom'
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% 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...
250
        $fileName = substr($fileInfo->getName(), 0, (strrpos($fileInfo->getName(), '.'))); 
0 ignored issues
show
Bug introduced by
Consider using $fileInfo->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
251
        // eliminate the file name from the path
252
        // 'files/Test/thedom.png' => 'files/Test/' || 'files/thedom.png' => 'files/'
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% 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...
253
        $filePath = str_replace($fileInfo->getName(), '', $fileInfo->getPath()); 
0 ignored issues
show
Bug introduced by
Consider using $fileInfo->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
254
        // and get the path on top of the files/ dir
255
        // 'files/Test/' => '/Test/' || 'files/' => '/'
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% 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...
256
        $filePath = str_replace('files', '', $filePath);
257
        // remove the last slash
258
        // '/Test/' => '/Test' || '/' => ''
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% 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...
259
        $filePath = substr_replace($filePath, '', strrpos($filePath, '/'), strlen('/'));
260
        // replace the first slash
261
        $pos = strpos($filePath, '/');
262
        if ($pos !== false) {
263
            // '/Test' => '// 'Test' || '/' => ''
264
            $filePath = substr_replace($filePath, '', $pos, strlen('/'));
265
        }
266 View Code Duplication
        if ($fileInfo->getMimetype() === OcrConstants::MIME_TYPE_PDF) {
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...
267
            // PDFs:
268
            return $this->buildNotExistingFilename($filePath, $fileName . '_OCR.pdf');
269
        } else {
270
            // IMAGES:
271
            return $this->buildNotExistingFilename($filePath, $fileName . '_OCR.txt');
272
        }
273
    }
274
275
    /**
276
     * Checks a MIME type for a specifically given FileInfo.
277
     * 
278
     * @param File $fileInfo            
279
     */
280
    private function checkMimeType(File $fileInfo) {
281
        if (!$fileInfo || !in_array($fileInfo->getMimetype(), OcrConstants::ALLOWED_MIME_TYPES)) {
282
            $this->logger->debug('Getting FileInfo did not work or not included in the ALLOWED_MIMETYPES array.');
283
            throw new NotFoundException($this->l10n->t('Wrong MIME type.'));
284
        }
285
    }
286
}