|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace KI\PonthubBundle\Helper; |
|
4
|
|
|
|
|
5
|
|
|
use Doctrine\ORM\EntityManager; |
|
6
|
|
|
use Doctrine\ORM\EntityRepository; |
|
7
|
|
|
|
|
8
|
|
|
class FilelistHelper |
|
9
|
|
|
{ |
|
10
|
|
|
protected $manager; |
|
11
|
|
|
protected $genreRepository; |
|
12
|
|
|
protected $serieRepository; |
|
13
|
|
|
protected $ponthubFileRepository; |
|
14
|
|
|
protected $validExtensions; |
|
15
|
|
|
protected $fileHelper; |
|
16
|
|
|
|
|
17
|
|
|
public function __construct(EntityManager $manager, |
|
|
|
|
|
|
18
|
|
|
EntityRepository $genreRepository, |
|
19
|
|
|
EntityRepository $serieRepository, |
|
20
|
|
|
EntityRepository $ponthubFileRepository, |
|
21
|
|
|
array $validExtensions, |
|
22
|
|
|
FileHelper $fileHelper) |
|
23
|
|
|
{ |
|
24
|
|
|
$this->manager = $manager; |
|
25
|
|
|
$this->genreRepository = $genreRepository; |
|
26
|
|
|
$this->serieRepository = $serieRepository; |
|
27
|
|
|
$this->ponthubFileRepository = $ponthubFileRepository; |
|
28
|
|
|
$this->validExtensions = $validExtensions; |
|
29
|
|
|
$this->fileHelper = $fileHelper; |
|
30
|
|
|
} |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* Lit la liste des fichiers de Fleur et en déduit les opérations à faire |
|
34
|
|
|
* @param string $list |
|
35
|
|
|
*/ |
|
36
|
|
|
public function parseFilelist($list) |
|
37
|
|
|
{ |
|
38
|
|
|
// On va modifier les entités en fonction de la liste, on récupère les |
|
39
|
|
|
// chemins de toutes les entités Ponthub |
|
40
|
|
|
$pathsExisting = $this->ponthubFileRepository->createQueryBuilder('r')->select('r.path')->getQuery()->getScalarResult(); |
|
41
|
|
|
$pathsExisting = array_map('current', $pathsExisting); |
|
42
|
|
|
$pathsDone = []; |
|
43
|
|
|
|
|
44
|
|
|
// On stocke les albums et les séries existantes |
|
45
|
|
|
extract($this->listExistingEntities()); |
|
46
|
|
|
|
|
47
|
|
|
while (!feof($list)) { |
|
48
|
|
|
// On parcourt la liste ligne par ligne |
|
49
|
|
|
$result = $this->parseLine(fgets($list), $pathsDone, $pathsExisting); |
|
50
|
|
|
if (empty($result)) { |
|
51
|
|
|
continue; |
|
52
|
|
|
} |
|
53
|
|
|
extract($result); |
|
54
|
|
|
|
|
55
|
|
|
// On détermine le dossier dans lequel est rangé le fichier et on range selon le type. |
|
56
|
|
|
$this->fileHelper->tryToStoreMovie($line, $name, $size); |
|
57
|
|
|
$this->fileHelper->tryToStoreGame($line, $name, $size); |
|
58
|
|
|
$this->fileHelper->tryToStoreSoftware($line, $name, $size); |
|
59
|
|
|
$this->fileHelper->tryToStoreOther($line, $name, $size); |
|
60
|
|
|
|
|
61
|
|
|
$this->fileHelper->tryToStoreSerie($series, $pathsDone, $ext, $line, $name, $size); |
|
62
|
|
|
} |
|
63
|
|
|
$this->manager->flush(); |
|
64
|
|
|
|
|
65
|
|
|
$this->markFilesNotFound($pathsExisting, $pathsDone); |
|
66
|
|
|
} |
|
67
|
|
|
|
|
68
|
|
|
/** |
|
69
|
|
|
* Sert pour le tri des fichiers enfants (épisode) |
|
70
|
|
|
* @return array |
|
71
|
|
|
*/ |
|
72
|
|
|
private function listExistingEntities() |
|
73
|
|
|
{ |
|
74
|
|
|
$seriesOutput = $genresOutput = []; |
|
75
|
|
|
$series = $this->serieRepository->findAll(); |
|
76
|
|
|
foreach ($series as $serie) { |
|
77
|
|
|
$seriesOutput[$serie->getPath()] = $serie; |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
// On liste aussi les genres |
|
81
|
|
|
$genres = $this->genreRepository->findAll(); |
|
82
|
|
|
foreach ($genres as $genre) { |
|
83
|
|
|
$genresOutput[$genre->getName()] = $genre; |
|
84
|
|
|
} |
|
85
|
|
|
return ['genres' => $genresOutput, 'series' => $seriesOutput]; |
|
86
|
|
|
} |
|
87
|
|
|
|
|
88
|
|
|
/** |
|
89
|
|
|
* Parse une ligne de la liste et renvoie les données correspondantes |
|
90
|
|
|
* @param string $line |
|
91
|
|
|
* @param array $pathsDone |
|
92
|
|
|
* @param array $pathsExisting |
|
93
|
|
|
* @return array |
|
94
|
|
|
*/ |
|
95
|
|
|
private function parseLine($line, &$pathsDone, $pathsExisting) |
|
96
|
|
|
{ |
|
97
|
|
|
// On enlève le caractère de fin de ligne |
|
98
|
|
|
$line = str_replace(["\r", "\n"], ['', ''], $line); |
|
99
|
|
|
|
|
100
|
|
|
// On récupère la taille du fichier et on l'enlève de la line |
|
101
|
|
|
// pour garder uniquement le chemin |
|
102
|
|
|
$match = []; |
|
103
|
|
|
preg_match('/^(([0-9]+)[\t ]*)/', $line, $match); |
|
104
|
|
|
|
|
105
|
|
|
// On vérifie que la line a bien la bonne syntaxe, càd |
|
106
|
|
|
// %size% %path% |
|
107
|
|
|
if (!(isset($match[1]) && isset($match[2]))) { |
|
108
|
|
|
return []; |
|
109
|
|
|
} |
|
110
|
|
|
$size = $match[2] * 1000; |
|
111
|
|
|
$line = str_replace($match[1], '', $line); |
|
112
|
|
|
|
|
113
|
|
|
// On exclut tous les fichiers de type non valide |
|
114
|
|
|
$name = preg_replace(['#.*/#', '#\.[a-zA-Z0-9]+$#'], ['', ''], $line); |
|
115
|
|
|
$ext = strrchr($line, '.'); |
|
116
|
|
|
if ($ext !== false) { |
|
117
|
|
|
$ext = strtolower(substr($ext, 1)); |
|
118
|
|
|
if (!in_array($ext, $this->validExtensions)) { |
|
119
|
|
|
return []; |
|
120
|
|
|
} |
|
121
|
|
|
} |
|
122
|
|
|
|
|
123
|
|
|
// On ne crée une nouvelle entrée que si le fichier n'existe pas |
|
124
|
|
|
if (in_array($line, $pathsExisting)) { |
|
125
|
|
|
$pathsDone[] = $line; |
|
126
|
|
|
return []; |
|
127
|
|
|
} |
|
128
|
|
|
return ['line' => $line, 'name' => $name, 'size' => $size, 'ext' => $ext]; |
|
129
|
|
|
} |
|
130
|
|
|
|
|
131
|
|
|
/** |
|
132
|
|
|
* Prend les fichiers non trouvés dans la liste et les marque comme tel |
|
133
|
|
|
* @param array $pathsExisting |
|
134
|
|
|
* @param array $pathsDone |
|
135
|
|
|
*/ |
|
136
|
|
|
private function markFilesNotFound($pathsExisting, $pathsDone) |
|
137
|
|
|
{ |
|
138
|
|
|
// Maintenant on marque les fichiers non trouvés |
|
139
|
|
|
$notFound = array_diff($pathsExisting, $pathsDone); |
|
140
|
|
|
$items = $this->ponthubFileRepository->findByPath($notFound); |
|
141
|
|
|
|
|
142
|
|
|
foreach ($items as $item) { |
|
143
|
|
|
$item->setStatus('NotFound'); |
|
144
|
|
|
} |
|
145
|
|
|
$this->manager->flush(); |
|
146
|
|
|
} |
|
147
|
|
|
} |
|
148
|
|
|
|
The
EntityManagermight become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:If that code throws an exception and the
EntityManageris closed. Any other code which depends on the same instance of theEntityManagerduring this request will fail.On the other hand, if you instead inject the
ManagerRegistry, thegetManager()method guarantees that you will always get a usable manager instance.