Files can now have mirrors. Implemented SMOMatcher service to attempt to automaticall...
[rock.divinelegy.git] / Controllers / SimfileController.php
1 <?php
2
3 namespace Controllers;
4
5 use Controllers\IDivineController;
6 use Services\Http\IHttpResponse;
7 use Services\Uploads\IUploadManager;
8 use Services\IUserSession;
9 use Services\IZipParser;
10 use Services\ISMOMatcher;
11 use DataAccess\StepMania\ISimfileRepository;
12 use DataAccess\StepMania\IPackRepository;
13 use DataAccess\IFileRepository;
14 use Domain\Entities\StepMania\ISimfile;
15 use Domain\Entities\IFile;
16 use Domain\VOs\IFileMirror;
17
18 class SimfileController implements IDivineController
19 {
20 private $_simfileRepository;
21 private $_packRepository;
22 private $_fileRepository;
23 private $_response;
24 private $_uploadManager;
25 private $_userSession;
26 private $_zipParser;
27 private $_smoMatcher;
28
29 public function __construct(
30 IHttpResponse $response,
31 IUploadManager $uploadManager,
32 ISimfileRepository $simfileRepository,
33 IPackRepository $packRepository,
34 IFileRepository $fileRepository,
35 IUserSession $userSession,
36 IZipParser $zipParser,
37 ISMOMatcher $smoMatcher
38 ) {
39 $this->_response = $response;
40 $this->_uploadManager = $uploadManager;
41 $this->_simfileRepository = $simfileRepository;
42 $this->_packRepository = $packRepository;
43 $this->_fileRepository = $fileRepository;
44 $this->_userSession = $userSession;
45 $this->_zipParser = $zipParser;
46 $this->_smoMatcher = $smoMatcher;
47 }
48
49 public function indexAction() {
50 ;
51 }
52
53 // list simfiles
54 public function listAction()
55 {
56 /* @var $simfile Domain\Entities\StepMania\ISimfile */
57 $simfiles = $this->_simfileRepository->findAll();
58 $packs = $this->_packRepository->findAll();
59 $simfileArray = array();
60 $packArray = array();
61
62 foreach($simfiles as $simfile)
63 {
64 $simfileArray[] = $this->simfileToArray($simfile);
65 }
66
67 foreach($packs as $pack)
68 {
69 $packSimfiles = array();
70 foreach($pack->getSimfiles() as $simfile)
71 {
72 $packSimfiles[] = $this->simfileToArray($simfile);
73 }
74
75 $packMirrors = array();
76 if($pack->getFile()->getMirrors())
77 {
78 foreach($pack->getFile()->getMirrors() as $mirror)
79 {
80 $packMirrors = $mirror->getUri();
81 }
82 }
83
84 $packArray[] = array(
85 'title'=> $pack->getTitle(),
86 'contributors' => $pack->getContributors(),
87 'simfiles' => $packSimfiles,
88 'banner' => $pack->getBanner() ? 'files/banner/' . $pack->getBanner()->getHash() : 'files/banner/default',
89 'mirrors' => $packMirrors
90 );
91 }
92
93 $returnArray = array('simfiles' => $simfileArray, 'packs' => $packArray);
94
95 $this->_response->setHeader('Content-Type', 'application/json')
96 ->setBody(json_encode($returnArray))
97 ->sendResponse();
98 }
99
100 public function uploadAction()
101 {
102 //TODO: Put directory in config ?
103 $files = $this->_uploadManager->setFilesDirectory('../files')
104 ->setDestination('StepMania/')
105 ->process();
106
107 foreach($files as $file)
108 {
109 $zipParser = $this->_zipParser;
110 $zipParser->parse($file);
111
112 //save the actual zip in the db
113 $this->findAndAddSmoMirror($file);
114 $this->_fileRepository->save($file);
115
116 if($zipParser->isPack())
117 {
118 //XXX: Tricky! pack() uses packbuilder and so returns a new pack each time.
119 //I tried to be clever and call pack() multiple times thinking I was getting the same
120 //object. Should I cache it in zipparser?
121 $pack = $zipParser->pack();
122 $packBanner = $pack->getBanner() ? $this->_fileRepository->save($pack->getBanner()) : null;
123 $this->_packRepository->save($pack);
124 }
125
126 foreach($zipParser->simfiles() as $simfile)
127 {
128 $banner = $simfile->getBanner() ? $this->_fileRepository->save($simfile->getBanner()) : null;
129 $simfileZip = $simfile->getSimfile() ? $this->_fileRepository->save($simfile->getSimfile()) : null;
130
131 if(isset($pack)) $simfile->addToPack($pack);
132 $this->_simfileRepository->save($simfile);
133 }
134 }
135 }
136
137 private function findAndAddSmoMirror(IFile $file)
138 {
139 $basename = pathinfo($file->getFilename(), PATHINFO_FILENAME);
140 $match = $this->_smoMatcher->match($basename, $file->getSize());
141
142 //XXX: Direct instantiation of FileMirror bad?
143 if($match && $match['confidence'] > 90)
144 {
145 $file->addMirror(new \Domain\VOs\FileMirror($match['href']));
146 }
147 }
148
149 private function simfileToArray(ISimfile $simfile)
150 {
151 $singleSteps = array();
152 $doubleSteps = array();
153
154 foreach($simfile->getSteps() as $steps)
155 {
156 $stepDetails = array(
157 'artist' => $steps->getArtist()->getTag(),
158 'difficulty' => $steps->getDifficulty()->getITGName(),
159 'rating' => $steps->getRating()
160 );
161
162 if($steps->getMode()->getPrettyName() == 'Single')
163 {
164 $singleSteps[] = $stepDetails;
165 } else {
166 $doubleSteps[] = $stepDetails;
167 }
168 }
169
170 return array(
171 'title' => $simfile->getTitle(),
172 'artist' => $simfile->getArtist()->getName(),
173 'steps' => array(
174 'single' => $singleSteps,
175 'double' => $doubleSteps
176 ),
177 'bgChanges' => $simfile->hasBgChanges() ? 'Yes' : 'No',
178 'fgChanges' => $simfile->hasFgChanges() ? 'Yes' : 'No',
179 'bpmChanges' => $simfile->hasBPMChanges() ? 'Yes' : 'No',
180 'banner' => $simfile->getBanner() ? 'files/banner/' . $simfile->getBanner()->getHash() : 'files/banner/default'
181 );
182 }
183 }