0
Files
KinoSearch/src/main/java/kinosearch/webapp/WebAppController.java

239 lines
8.5 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* DmitriyMX <dmitriymx@yandex.ru>
* 2017-01-04
*/
package kinosearch.webapp;
import com.google.gson.Gson;
import kinosearch.core.Kino;
import kinosearch.core.KinoPlay;
import kinosearch.core.Tools;
import kinosearch.core.warez.KinoWarez;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
@Controller
public class WebAppController {
private final Logger logger = Logger.getLogger(WebAppController.class.getName());
@Autowired
private ApplicationContext coreContext;
private void setDefaultModel(ModelMap model) {
model.addAttribute("version", "2.0.10-SNAPSHOT");
model.addAttribute("rutext", "Поиск кино по пиратским кинотеатрам");
}
@RequestMapping(value = {"/", "/index.html"}, method = RequestMethod.GET)
public String index(ModelMap model) {
setDefaultModel(model);
return "index";
}
@RequestMapping(value = {"/", "/index.html"}, method = RequestMethod.GET, params = {"search"})
public String search(@RequestParam("search") String searchText, ModelMap model) {
if (searchText.trim().isEmpty()) {
return "redirect:/";
}
List<Kino> list = Collections.synchronizedList(new LinkedList<>());
Map<String, KinoWarez> kinoWarezMap = coreContext.getBeansOfType(KinoWarez.class);
ThreadGroup threadGroup = new ThreadGroup("");
for (KinoWarez kinoWarez : kinoWarezMap.values()) { //TODO надо ограничить количество одновременных потоков
new Thread(threadGroup, () -> {
List<Kino> outList = kinoWarez.search(searchText, false); //FIXME "strong" нужно учитывать
for (Kino kino : outList) {
kino.setName("[" + kinoWarez.getName() + "] " + kino.getName());
}
list.addAll(outList);
}).start();
}
// ждем максимум 15 секунд
//FIXME надо бы убивать потоки, которые не успели найти контент
for (int i = 0; i < 15 && threadGroup.activeCount() > 0; i++) {
Tools.SafeSleep(1000);
}
model.put("searchtext", searchText);
model.put("resultsearch", groupKino(list));
model.put("strong", false); //FIXME "strong" нужно учитывать
setDefaultModel(model);
return "index";
}
private List<Kino> groupKino(List<Kino> list) {
Map<String, KinoGroup> hashGroup = new HashMap<>();
List<Kino> grouppedList = new ArrayList<>();
//TODO: необходима оптимизация
Iterator<Kino> itr1 = list.iterator();
int skip = 1;
while (itr1.hasNext()) {
Kino kino1 = itr1.next();
String s1 = Tools.cleanString(kino1.getName().replaceAll("^\\[.+?\\] ",""));
if (hashGroup.containsKey(s1)) {
skip++;
continue;
}
KinoGroup group = new KinoGroup(s1, null, null);
Iterator<Kino> itr2 = list.iterator();
int val = 0;
while (itr2.hasNext()) {
if (val < skip) {
val++;
itr2.next();
continue;
}
Kino kino2 = itr2.next();
String s2 = Tools.cleanString(kino2.getName().replaceAll("^\\[.+?\\] ",""));
int res = s1.compareTo(s2);
if (res == 0) {
if (!group.contains(kino2)) {
group.add(kino2);
}
}
}
if (group.getKinolist().size() > 0) {
group.add(kino1);
hashGroup.put(s1, group);
} else {
grouppedList.add(kino1);
}
skip++;
}
grouppedList.addAll(0, hashGroup.values());
return grouppedList;
}
@RequestMapping(value = "/player/{warez}/**", method = RequestMethod.GET)
public String player(@PathVariable() String warez, ModelMap model, HttpServletRequest request) throws MalformedURLException {
KinoWarez kinoWarez = coreContext.getBean(warez, KinoWarez.class);
if (kinoWarez == null) {
return "redirect:/";
}
//TODO а необходимость в URL точно оправдана?
URL requestUrl = new URL(request.getRequestURL().toString());
KinoPlay kinoPlay = kinoWarez.player(requestUrl.getPath().substring(("/player/"+warez).length()));
Gson gson = coreContext.getBean(Gson.class);
model.put("json", gson.toJson(kinoPlay));
setDefaultModel(model);
return "player";
}
@RequestMapping(value = "/proxy/{warez}/**", method = RequestMethod.GET)
public void proxy(@PathVariable String warez, HttpServletRequest request, HttpServletResponse response) throws IOException {
//TODO а необходимость в URL точно оправдана?
URL requestUrl = new URL(request.getRequestURL().toString());
String path = requestUrl.getPath().substring(("/proxy/"+warez+"/").length());
URL url = new URL("http://" + path);
HttpURLConnection con =(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setDoOutput(true);
con.setDoInput(true);
con.setUseCaches(true);
for (Enumeration names = request.getHeaderNames(); names.hasMoreElements();) {
String headerName = names.nextElement().toString();
if (headerName.equalsIgnoreCase("referer")) continue;
con.setRequestProperty(headerName, request.getHeader(headerName));
}
boolean connected;
int _try = 0;
do {
try {
con.connect();
connected = true;
} catch (IOException e) {
con.disconnect();
connected = false;
_try++;
logger.log(Level.WARNING,String.format("Error connection to '%s': '%s'. Try again...", url.toString(), e.getMessage()));
}
} while (!connected && _try < 3);
if (!connected) {
response.sendError(524);
return;
}
int statusCode = con.getResponseCode();
response.setStatus(statusCode);
if (statusCode != 200 && statusCode != 206) {
con.disconnect();
return;
}
for (Map.Entry<String, List<String>> stringListEntry : con.getHeaderFields().entrySet()) {
Map.Entry mapEntry = stringListEntry;
if (mapEntry.getKey() != null) {
response.setHeader(mapEntry.getKey().toString(), ((List) mapEntry.getValue()).get(0).toString());
}
}
BufferedInputStream webToProxyBuf = new BufferedInputStream(con.getInputStream());
BufferedOutputStream proxyToClientBuf = new BufferedOutputStream(response.getOutputStream());
int oneByte;
try {
while ((oneByte = webToProxyBuf.read()) != -1) {
proxyToClientBuf.write(oneByte);
}
proxyToClientBuf.flush();
proxyToClientBuf.close();
} catch (Exception ignore) {
// ignore
}
webToProxyBuf.close();
con.disconnect();
}
@RequestMapping(value = {"/about", "/about.html"}, method = RequestMethod.GET)
public String about(ModelMap model) {
setDefaultModel(model);
return "about";
}
@RequestMapping(value = "/favicon.ico")
public void favicon(HttpServletResponse response) {
try {
response.sendError(404);
} catch (IOException e) {
logger.log(Level.WARNING, "favicon 404", e);
}
}
}