Popular downloads stuff.
[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 DataAccess\IDownloadRepository;
15 use Domain\Entities\StepMania\ISimfile;
16 use Domain\Entities\IFile;
17 use Domain\Entities\StepMania\IPack;
18 use Domain\Util;
19
20 class SimfileController implements IDivineController
21 {
22 private $_simfileRepository;
23 private $_packRepository;
24 private $_fileRepository;
25 private $_response;
26 private $_uploadManager;
27 private $_zipParser;
28 private $_smoMatcher;
29 private $_downloadRepository;
30
31 public function __construct(
32 IHttpResponse $response,
33 IUploadManager $uploadManager,
34 ISimfileRepository $simfileRepository,
35 IPackRepository $packRepository,
36 IFileRepository $fileRepository,
37 IUserSession $userSession,
38 IZipParser $zipParser,
39 ISMOMatcher $smoMatcher,
40 IDownloadRepository $downloadRepository
41 ) {
42 $this->_response = $response;
43 $this->_uploadManager = $uploadManager;
44 $this->_simfileRepository = $simfileRepository;
45 $this->_packRepository = $packRepository;
46 $this->_fileRepository = $fileRepository;
47 $this->_zipParser = $zipParser;
48 $this->_smoMatcher = $smoMatcher;
49 $this->_downloadRepository = $downloadRepository;
50 }
51
52 public function indexAction() {
53 ;
54 }
55
56 // list simfiles
57 public function listAction()
58 {
59 /* @var $simfile Domain\Entities\StepMania\ISimfile */
60 $simfiles = $this->_simfileRepository->findAll();
61 $packs = $this->_packRepository->findAll();
62 $simfileArray = array();
63 $packArray = array();
64
65 foreach($simfiles as $simfile)
66 {
67 $simfileArray[] = $this->simfileToArray($simfile);
68 }
69
70 foreach($packs as $pack)
71 {
72 $packArray[] = array(
73 'title'=> $pack->getTitle(),
74 'contributors' => $pack->getContributors(),
75 'simfiles' => $this->getPackSimfilesArray($pack),
76 'banner' => $pack->getBanner() ? 'files/banner/' . $pack->getBanner()->getHash() : 'files/banner/default',
77 'mirrors' => $this->getPackMirrorsArray($pack),
78 'size' => $pack->getFile() ? Util::bytesToHumanReadable($pack->getFile()->getSize()) : null,
79 'uploaded' => $pack->getFile() ? date('F jS, Y', $pack->getFile()->getUploadDate()) : null
80 );
81 }
82
83 $returnArray = array('simfiles' => $simfileArray, 'packs' => $packArray);
84
85 $this->_response->setHeader('Content-Type', 'application/json')
86 ->setBody(json_encode($returnArray))
87 ->sendResponse();
88 }
89
90 public function latestSimfileAction()
91 {
92 $simfile = $this->_simfileRepository->findRange(0, -1);
93 $this->_response->setHeader('Content-Type', 'application/json')
94 ->setBody(json_encode($this->simfileToArray(reset($simfile))))
95 ->sendResponse();
96 }
97
98 public function latestPackAction()
99 {
100 $pack = $this->_packRepository->findRange(0, -1);
101 $pack = reset($pack);
102
103 $packArray = array(
104 'title'=> $pack->getTitle(),
105 'contributors' => $pack->getContributors(),
106 'simfiles' => $this->getPackSimfilesArray($pack),
107 'banner' => $pack->getBanner() ? 'files/banner/' . $pack->getBanner()->getHash() : 'files/banner/default',
108 'mirrors' => $this->getPackMirrorsArray($pack),
109 'size' => $pack->getFile() ? Util::bytesToHumanReadable($pack->getFile()->getSize()) : null,
110 'uploaded' => $pack->getFile() ? date('F jS, Y', $pack->getFile()->getUploadDate()) : null
111 );
112
113 $this->_response->setHeader('Content-Type', 'application/json')
114 ->setBody(json_encode($packArray))
115 ->sendResponse();
116 }
117
118 public function popularAction()
119 {
120 $returnArray = array();
121 $popularDownloads = $this->_downloadRepository->findPopular();
122 $popularDownloads = reset($popularDownloads);
123 $packOrFileId = $popularDownloads->getFile()->getId();
124
125 $simfile = $this->_simfileRepository->findByFileId($packOrFileId);
126 if($simfile)
127 {
128 $returnArray = $this->simfileToArray(reset($simfile));
129 } else {
130 $pack = $this->_packRepository->findByFileId($packOrFileId);
131 $pack = reset($pack);
132 $returnArray = array(
133 'title'=> $pack->getTitle(),
134 'contributors' => $pack->getContributors(),
135 'simfiles' => $this->getPackSimfilesArray($pack),
136 'banner' => $pack->getBanner() ? 'files/banner/' . $pack->getBanner()->getHash() : 'files/banner/default',
137 'mirrors' => $this->getPackMirrorsArray($pack),
138 'size' => $pack->getFile() ? Util::bytesToHumanReadable($pack->getFile()->getSize()) : null,
139 'uploaded' => $pack->getFile() ? date('F jS, Y', $pack->getFile()->getUploadDate()) : null
140 );
141 }
142
143 $this->_response->setHeader('Content-Type', 'application/json')
144 ->setBody(json_encode($returnArray))
145 ->sendResponse();
146
147 }
148
149 public function uploadAction()
150 {
151 //TODO: Put directory in config ?
152 $files = $this->_uploadManager->setFilesDirectory('../files')
153 ->setDestination('StepMania/')
154 ->process();
155
156 foreach($files as $file)
157 {
158 $zipParser = $this->_zipParser;
159 $zipParser->parse($file);
160
161 //save the actual zip in the db
162 $this->findAndAddSmoMirror($file);
163 $this->_fileRepository->save($file);
164
165 if($zipParser->isPack())
166 {
167 //XXX: Tricky! pack() uses packbuilder and so returns a new pack each time.
168 //I tried to be clever and call pack() multiple times thinking I was getting the same
169 //object. Should I cache it in zipparser?
170 $pack = $zipParser->pack();
171 $packBanner = $pack->getBanner() ? $this->_fileRepository->save($pack->getBanner()) : null;
172 $this->_packRepository->save($pack);
173 }
174
175 foreach($zipParser->simfiles() as $simfile)
176 {
177 $banner = $simfile->getBanner() ? $this->_fileRepository->save($simfile->getBanner()) : null;
178 $simfileZip = $simfile->getSimfile() ? $this->_fileRepository->save($simfile->getSimfile()) : null;
179
180 if(isset($pack)) $simfile->addToPack($pack);
181 $this->_simfileRepository->save($simfile);
182 }
183 }
184 }
185
186 private function getPackMirrorsArray(IPack $pack)
187 {
188 $packMirrors = array();
189
190 if($pack->getFile())
191 {
192 $packMirrors[] = array('source' => 'DivinElegy', 'uri' => 'files/pack/' . $pack->getFile()->getHash());
193 }
194
195 if($pack->getFile()->getMirrors())
196 {
197 foreach($pack->getFile()->getMirrors() as $mirror)
198 {
199 $packMirrors[] = array('source' => $mirror->getSource(), 'uri' => $mirror->getUri());
200 }
201 }
202
203 return $packMirrors;
204 }
205
206 private function getPackSimfilesArray(IPack $pack)
207 {
208 $packSimfiles = array();
209 foreach($pack->getSimfiles() as $simfile)
210 {
211 $packSimfiles[] = $this->simfileToArray($simfile);
212 }
213
214 return $packSimfiles;
215 }
216
217 private function findAndAddSmoMirror(IFile $file)
218 {
219 $basename = pathinfo($file->getFilename(), PATHINFO_FILENAME);
220 $match = $this->_smoMatcher->match($basename, $file->getSize());
221
222 //XXX: Direct instantiation of FileMirror bad?
223 if($match && $match['confidence'] > 90)
224 {
225 $file->addMirror(new \Domain\VOs\FileMirror($match['href'], 'Stepmania Online'));
226 }
227 }
228
229 private function simfileToArray(ISimfile $simfile)
230 {
231 $singleSteps = array();
232 $doubleSteps = array();
233
234 foreach($simfile->getSteps() as $steps)
235 {
236 $stepDetails = array(
237 'artist' => $steps->getArtist()->getTag(),
238 'difficulty' => $steps->getDifficulty()->getITGName(),
239 'rating' => $steps->getRating()
240 );
241
242 if($steps->getMode()->getPrettyName() == 'Single')
243 {
244 $singleSteps[] = $stepDetails;
245 } else {
246 $doubleSteps[] = $stepDetails;
247 }
248 }
249
250 return array(
251 'title' => $simfile->getTitle(),
252 'artist' => $simfile->getArtist()->getName(),
253 'steps' => array(
254 'single' => $singleSteps,
255 'double' => $doubleSteps
256 ),
257 'bgChanges' => $simfile->hasBgChanges() ? 'Yes' : 'No',
258 'fgChanges' => $simfile->hasFgChanges() ? 'Yes' : 'No',
259 'bpmChanges' => $simfile->hasBPMChanges() ? 'Yes' : 'No',
260 'banner' => $simfile->getBanner() ? 'files/banner/' . $simfile->getBanner()->getHash() : 'files/banner/default',
261 'download' => $simfile->getSimfile() ? 'files/simfile/' . $simfile->getSimfile()->getHash() : null,
262 'size' => $simfile->getSimfile() ? Util::bytesToHumanReadable($simfile->getSimfile()->getSize()) : null,
263 'uploaded' => $simfile->getSimfile() ? date('F jS, Y', $simfile->getSimfile()->getUploadDate()) : null
264 );
265 }
266 }