9ab78ad879a991ee34820afca9c5b00f946e3a48
[rock.divinelegy.git] / Controllers / SimfileController.php
1 <?php
2
3 namespace Controllers;
4
5 use Exception;
6 use Controllers\IDivineController;
7 use Services\Http\IHttpResponse;
8 use Services\Http\IHttpRequest;
9 use Services\Uploads\IUploadManager;
10 use Services\IUserSession;
11 use Services\IZipParser;
12 use Services\ISMOMatcher;
13 use Services\IStatusReporter;
14 use DataAccess\StepMania\ISimfileRepository;
15 use DataAccess\StepMania\IPackRepository;
16 use DataAccess\IFileRepository;
17 use DataAccess\IDownloadRepository;
18 use Domain\Entities\StepMania\ISimfile;
19 use Domain\Entities\IFile;
20 use Domain\Entities\StepMania\IPack;
21 use Domain\Util;
22
23 class SimfileController implements IDivineController
24 {
25 private $_simfileRepository;
26 private $_packRepository;
27 private $_fileRepository;
28 private $_request;
29 private $_response;
30 private $_uploadManager;
31 private $_zipParser;
32 private $_smoMatcher;
33 private $_downloadRepository;
34 private $_statusReporter;
35 private $_userSession;
36
37 public function __construct(
38 IHttpResponse $response,
39 IHttpRequest $request,
40 IUploadManager $uploadManager,
41 ISimfileRepository $simfileRepository,
42 IPackRepository $packRepository,
43 IFileRepository $fileRepository,
44 IUserSession $userSession,
45 IZipParser $zipParser,
46 ISMOMatcher $smoMatcher,
47 IDownloadRepository $downloadRepository,
48 IStatusReporter $statusReporter
49 ) {
50 $this->_response = $response;
51 $this->_request = $request;
52 $this->_uploadManager = $uploadManager;
53 $this->_simfileRepository = $simfileRepository;
54 $this->_packRepository = $packRepository;
55 $this->_fileRepository = $fileRepository;
56 $this->_zipParser = $zipParser;
57 $this->_smoMatcher = $smoMatcher;
58 $this->_downloadRepository = $downloadRepository;
59 $this->_statusReporter = $statusReporter;
60 $this->_userSession = $userSession;
61 }
62
63 public function indexAction() {
64 ;
65 }
66
67 // list simfiles
68 public function listAction()
69 {
70 $file = '../SimfileCache/simfiles.json';
71 $path = realpath($file);
72
73 //Always set incase list changes
74 $hash = md5_file($path);
75 $this->_response->setHeader('etag', $hash)
76 ->setHeader('last-modified', gmdate("D, d M Y H:i:s", filemtime($file)) . " GMT")
77 ->setHeader('cache-control', 'max-age=-1');
78
79 if($this->_request->getHeader('HTTP_IF_NONE_MATCH') == $hash)
80 {
81 $this->_response->setHeader("HTTP/1.1 304 Not Modified", 'Nice meme!');
82 } else {
83 $this->_response->setHeader('Content-Type', 'application/json')
84 ->setBody(file_get_contents($path));
85 }
86
87 $this->_response->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(Util::simfileToArray(reset($simfile))))
95 ->sendResponse();
96 }
97
98 public function latestPackAction()
99 {
100 $pack = $this->_packRepository->findRange(0, -1);
101 $this->_response->setHeader('Content-Type', 'application/json')
102 ->setBody(json_encode(Util::packToArray(reset($pack))))
103 ->sendResponse();
104 }
105
106 public function popularAction()
107 {
108 $returnArray = array();
109 $popularDownloads = $this->_downloadRepository->findPopular();
110 $packOrFileId = reset($popularDownloads)->getFile()->getId();
111
112 $simfile = $this->_simfileRepository->findByFileId($packOrFileId);
113 if($simfile)
114 {
115 $returnArray = Util::simfileToArray(reset($simfile));
116 } else {
117 $pack = $this->_packRepository->findByFileId($packOrFileId);
118 $returnArray = Util::packToArray(reset($pack));
119 }
120
121 $this->_response->setHeader('Content-Type', 'application/json')
122 ->setBody(json_encode($returnArray))
123 ->sendResponse();
124 }
125
126 public function uploadAction()
127 {
128 if(!$this->_userSession->getCurrentUser()) $this->_statusReporter->error('You must be authenticated to upload files');
129
130 //TODO: Put directory in config ?
131 $files = $this->_uploadManager->setFilesDirectory('../files')
132 ->setDestination('StepMania/')
133 ->process();
134
135 foreach($files as $file)
136 {
137 $zipParser = $this->_zipParser;
138 $zipParser->parse($file);
139
140 if(!$zipParser->simfiles()) $this->_statusReporter->error('That zip doesn\'t seem to have any simfiles in it.');
141
142 //save the actual zip in the db
143 $this->findAndAddSmoMirror($file);
144 $this->_fileRepository->save($file);
145
146 if($zipParser->isPack())
147 {
148 //XXX: Tricky! pack() uses packbuilder and so returns a new pack each time.
149 //I tried to be clever and call pack() multiple times thinking I was getting the same
150 //object. Should I cache it in zipparser?
151 $pack = $zipParser->pack();
152 $packBanner = $pack->getBanner() ? $this->_fileRepository->save($pack->getBanner()) : null;
153 $this->_packRepository->save($pack);
154 }
155
156 foreach($zipParser->simfiles() as $simfile)
157 {
158 $banner = $simfile->getBanner() ? $this->_fileRepository->save($simfile->getBanner()) : null;
159 $simfileZip = $simfile->getSimfile() ? $this->_fileRepository->save($simfile->getSimfile()) : null;
160
161 if(isset($pack)) $simfile->addToPack($pack);
162 $this->_simfileRepository->save($simfile);
163 }
164 }
165
166 $this->_statusReporter->success('Uploaded succesfully');
167 }
168
169 private function findAndAddSmoMirror(IFile $file)
170 {
171 $basename = pathinfo($file->getFilename(), PATHINFO_FILENAME);
172 $match = $this->_smoMatcher->match($basename, $file->getSize());
173
174 //XXX: Direct instantiation of FileMirror bad?
175 if($match && $match['confidence'] > 90)
176 {
177 $file->addMirror(new \Domain\VOs\FileMirror($match['href'], 'Stepmania Online'));
178 }
179 }
180 }