Completed
Push — master ( 75a8a0...8053cf )
by Peter
02:57
created

StorageController::isEndOfLog()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 13
ccs 0
cts 8
cp 0
rs 9.4285
cc 3
eloc 6
nc 3
nop 1
crap 12
1
<?php
2
/**
3
 * AnimeDb package.
4
 *
5
 * @author    Peter Gribanov <[email protected]>
6
 * @copyright Copyright (c) 2011, Peter Gribanov
7
 * @license   http://opensource.org/licenses/GPL-3.0 GPL v3
8
 */
9
10
namespace AnimeDb\Bundle\CatalogBundle\Controller;
11
12
use AnimeDb\Bundle\CatalogBundle\Entity\Storage;
13
use AnimeDb\Bundle\CatalogBundle\Repository\Storage as StorageRepository;
14
use AnimeDb\Bundle\CatalogBundle\Service\Storage\Scan\LogResponse;
15
use Symfony\Component\Form\Form;
16
use Symfony\Component\HttpFoundation\Request;
17
use AnimeDb\Bundle\CatalogBundle\Form\Type\Entity\Storage as StorageForm;
18
use Symfony\Component\HttpFoundation\JsonResponse;
19
use Symfony\Component\HttpFoundation\Response;
20
21
/**
22
 * Storages.
23
 *
24
 * @author  Peter Gribanov <[email protected]>
25
 */
26
class StorageController extends BaseController
27
{
28
    /**
29
     * Link to guide, how add a new storage.
30
     *
31
     * @var string
32
     */
33
    const GUIDE_LINK = '/guide/storage/add.html';
34
35
    /**
36
     * Storage list.
37
     *
38
     * @param Request $request
39
     *
40
     * @return Response
41
     */
42
    public function listAction(Request $request)
43
    {
44
        $response = $this->getCacheTimeKeeper()->getResponse('AnimeDbCatalogBundle:Storage');
45
        // response was not modified for this request
46
        if ($response->isNotModified($request)) {
47
            return $response;
48
        }
49
50
        /* @var $rep StorageRepository */
51
        $rep = $this->getDoctrine()->getRepository('AnimeDbCatalogBundle:Storage');
52
53
        return $this->render('AnimeDbCatalogBundle:Storage:list.html.twig', [
54
            'storages' => $rep->getList(),
55
        ], $response);
56
    }
57
58
    /**
59
     * Change storage.
60
     *
61
     * @param Storage $storage
62
     * @param Request $request
63
     *
64
     * @return Response
65
     */
66
    public function changeAction(Storage $storage, Request $request)
67
    {
68
        $response = $this->getCacheTimeKeeper()->getResponse($storage->getDateUpdate());
69
        // response was not modified for this request
70
        if ($response->isNotModified($request)) {
71
            return $response;
72
        }
73
74
        /* @var $form Form */
75
        $form = $this->createForm(new StorageForm(), $storage);
76
77
        if ($request->getMethod() == 'POST') {
78
            $form->handleRequest($request);
79
            if ($form->isValid()) {
80
                $em = $this->getDoctrine()->getManager();
81
                $em->persist($storage);
82
                $em->flush();
83
84
                return $this->redirect($this->generateUrl('storage_list'));
85
            }
86
        }
87
88
        return $this->render('AnimeDbCatalogBundle:Storage:change.html.twig', [
89
            'storage' => $storage,
90
            'form' => $form->createView(),
91
        ], $response);
92
    }
93
94
    /**
95
     * Add storage.
96
     *
97
     * @param Request $request
98
     *
99
     * @return Response
100
     */
101
    public function addAction(Request $request)
102
    {
103
        $storage = new Storage();
104
105
        /* @var $form Form */
106
        $form = $this->createForm(new StorageForm(), $storage);
107
108
        if ($request->getMethod() == 'POST') {
109
            $form->handleRequest($request);
110
            if ($form->isValid()) {
111
                $em = $this->getDoctrine()->getManager();
112
                $em->persist($storage);
113
                $em->flush();
114
115
                return $this->redirect($this->generateUrl('storage_list'));
116
            }
117
        }
118
119
        return $this->render('AnimeDbCatalogBundle:Storage:add.html.twig', [
120
            'form' => $form->createView(),
121
            'guide' => $this->get('anime_db.api.client')->getSiteUrl(self::GUIDE_LINK),
122
        ]);
123
    }
124
125
    /**
126
     * Delete storage.
127
     *
128
     * @param Storage $storage
129
     *
130
     * @return Response
131
     */
132
    public function deleteAction(Storage $storage)
133
    {
134
        $em = $this->getDoctrine()->getManager();
135
        $em->remove($storage);
136
        $em->flush();
137
138
        return $this->redirect($this->generateUrl('storage_list'));
139
    }
140
141
    /**
142
     * Get storage path.
143
     *
144
     * @param Request $request
145
     *
146
     * @return Response
147
     */
148
    public function getPathAction(Request $request)
149
    {
150
        /* @var $response JsonResponse */
151
        $response = $this->getCacheTimeKeeper()
152
            ->getResponse('AnimeDbCatalogBundle:Storage', -1, new JsonResponse());
153
        // response was not modified for this request
154
        if ($response->isNotModified($request)) {
155
            return $response;
156
        }
157
158
        /* @var $storage Storage */
159
        $storage = $this->getDoctrine()->getManager()
160
            ->find('AnimeDbCatalogBundle:Storage', $request->get('id'));
161
162
        return $response->setData([
163
            'required' => $storage->isPathRequired(),
164
            'path' => $storage->getPath(),
165
        ]);
166
    }
167
168
    /**
169
     * Scan storage.
170
     *
171
     * @param Storage $storage
172
     *
173
     * @return Response
174
     */
175
    public function scanAction(Storage $storage)
176
    {
177
        $this->get('anime_db.storage.scan_executor')->export($storage);
178
179
        return $this->render('AnimeDbCatalogBundle:Storage:scan.html.twig', [
180
            'storage' => $storage,
181
        ]);
182
    }
183
184
    /**
185
     * Get storage scan output.
186
     *
187
     * @param Storage $storage
188
     * @param Request $request
189
     *
190
     * @return JsonResponse
191
     */
192
    public function scanOutputAction(Storage $storage, Request $request)
193
    {
194
        $filename = $this->container->getParameter('anime_db.catalog.storage.scan_output');
195
        $filename = sprintf($filename, $storage->getId());
196
        if (!file_exists($filename)) {
197
            throw $this->createNotFoundException('Log file is not found');
198
        }
199
200
        $log = file_get_contents($filename);
201
        $is_end = $this->isEndOfLog($log);
202
203
        // force stop scan progress
204
        if ($is_end) {
205
            $this->get('anime_db.storage.scan_executor')->forceStopScan($storage);
206
        }
207
208
        return LogResponse::logOffset($log, $request->query->get('offset', 0), $is_end);
209
    }
210
211
    /**
212
     * @param string $log
213
     *
214
     * @return bool
215
     */
216
    private function isEndOfLog($log)
217
    {
218
        $is_end = preg_match('/\nTime: \d+ s./', $log);
219
220
        // end of execute scan on Windows
221
        $root = realpath($this->getParameter('kernel.root_dir').'/../');
222
        $is_end_win = preg_match('/\n'.preg_quote($root).'>/', $log);
223
224
        // detect fatal error in log
225
        $is_end_error = strpos($log, 'Fatal error: ') != false;
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing strpos($log, 'Fatal error: ') of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
226
227
        return $is_end || $is_end_win || $is_end_error;
228
    }
229
230
    /**
231
     * Get storage scan progress.
232
     *
233
     * @param Storage $storage
234
     *
235
     * @return JsonResponse
236
     */
237
    public function scanProgressAction(Storage $storage)
238
    {
239
        $filename = $this->container->getParameter('anime_db.catalog.storage.scan_progress');
240
        $filename = sprintf($filename, $storage->getId());
241
        if (!file_exists($filename)) {
242
            throw $this->createNotFoundException('The progress status cannot be read');
243
        }
244
245
        $log = trim(file_get_contents($filename), " \r\n%");
246
247
        return new JsonResponse(['status' => ($log != '' ? intval($log) : 100)]);
248
    }
249
}
250