Избавляемся от war
Теперь KinoSearch самодостаточен и может запускаться без внешних веб-контейнеров
This commit is contained in:
78
pom.xml
78
pom.xml
@@ -15,46 +15,51 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<spring.version>4.2.5.RELEASE</spring.version>
|
<spring.version>4.3.7.RELEASE</spring.version>
|
||||||
|
<jetty.version>9.4.0.v20161208</jetty.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<groupId>ru.dmitriymx</groupId>
|
<groupId>ru.dmitriymx</groupId>
|
||||||
<artifactId>kinosearch</artifactId>
|
<artifactId>kinosearch</artifactId>
|
||||||
<version>2.0.9</version>
|
<version>2.0.10-SNAPSHOT</version>
|
||||||
<packaging>war</packaging>
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- SPRING -->
|
<!-- SPRING -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-context</artifactId>
|
<artifactId>spring-context</artifactId>
|
||||||
<version>${spring.version}</version>
|
<version>${spring.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JETTY -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-server</artifactId>
|
||||||
|
<version>${jetty.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-webapp</artifactId>
|
||||||
|
<version>${jetty.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SPRING MVC -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-webmvc</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-context-support</artifactId>
|
<artifactId>spring-context-support</artifactId>
|
||||||
<version>${spring.version}</version>
|
<version>${spring.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-webmvc</artifactId>
|
|
||||||
<version>${spring.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
|
||||||
<version>3.1.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.servlet.jsp</groupId>
|
|
||||||
<artifactId>javax.servlet.jsp-api</artifactId>
|
|
||||||
<version>2.3.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>jstl</artifactId>
|
|
||||||
<version>1.2</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- COMPONENTS -->
|
<!-- COMPONENTS -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jsoup</groupId>
|
<groupId>org.jsoup</groupId>
|
||||||
@@ -76,6 +81,7 @@
|
|||||||
<artifactId>httpclient</artifactId>
|
<artifactId>httpclient</artifactId>
|
||||||
<version>4.5.2</version>
|
<version>4.5.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- TESTING -->
|
<!-- TESTING -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
@@ -114,16 +120,30 @@
|
|||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>3.0.0</version>
|
<version>2.4</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<classpathPrefix>dependency/</classpathPrefix>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>jetty-maven-plugin</artifactId>
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
<version>9.4.0.v20161208</version>
|
<version>2.8</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-dependencies</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|||||||
16
src/main/java/kinosearch/webapp/Main.java
Normal file
16
src/main/java/kinosearch/webapp/Main.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* DmitriyMX <dmitriymx@yandex.ru>
|
||||||
|
* 2017-12-11
|
||||||
|
*/
|
||||||
|
package kinosearch.webapp;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
|
||||||
|
WebApp webApp = ctx.getBean("webapp", WebApp.class);
|
||||||
|
webApp.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
40
src/main/java/kinosearch/webapp/SpringConfig.java
Normal file
40
src/main/java/kinosearch/webapp/SpringConfig.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* DmitriyMX <dmitriymx@yandex.ru>
|
||||||
|
* 2017-12-11
|
||||||
|
*/
|
||||||
|
package kinosearch.webapp;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
import org.springframework.web.servlet.ViewResolver;
|
||||||
|
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
||||||
|
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Import(kinosearch.core.SpringConfig.class)
|
||||||
|
@PropertySource("classpath:/application.properties")
|
||||||
|
public class SpringConfig {
|
||||||
|
@Bean
|
||||||
|
public WebApp webapp(@Value("${webapp.host}") String host, @Value("${webapp.port}") int port) {
|
||||||
|
return new WebApp(host, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ViewResolver viewResolver() {
|
||||||
|
FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver();
|
||||||
|
viewResolver.setContentType("text/html;charset=UTF-8");
|
||||||
|
viewResolver.setCache(true);
|
||||||
|
viewResolver.setSuffix(".ftl");
|
||||||
|
return viewResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public FreeMarkerConfigurer freemarkerConfig() {
|
||||||
|
FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
|
||||||
|
freeMarkerConfigurer.setTemplateLoaderPath("classpath:/kinosearch/webapp/");
|
||||||
|
return freeMarkerConfigurer;
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/main/java/kinosearch/webapp/SpringMvcConfig.java
Normal file
31
src/main/java/kinosearch/webapp/SpringMvcConfig.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* DmitriyMX <dmitriymx@yandex.ru>
|
||||||
|
* 2017-12-11
|
||||||
|
*/
|
||||||
|
package kinosearch.webapp;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebMvc
|
||||||
|
public class SpringMvcConfig extends WebMvcConfigurerAdapter {
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
|
final String staticPath = "classpath:/kinosearch/webapp/static/";
|
||||||
|
/* Styles */
|
||||||
|
registry.addResourceHandler("/css/**")
|
||||||
|
.addResourceLocations(staticPath+"css/");
|
||||||
|
/* Fonts */
|
||||||
|
registry.addResourceHandler("/fonts/**")
|
||||||
|
.addResourceLocations(staticPath+"fonts/");
|
||||||
|
/* JavaScript */
|
||||||
|
registry.addResourceHandler("/js/**")
|
||||||
|
.addResourceLocations(staticPath+"js/");
|
||||||
|
/* Other */
|
||||||
|
registry.addResourceHandler("/*.svg").addResourceLocations(staticPath);
|
||||||
|
registry.addResourceHandler("/*.png").addResourceLocations(staticPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/main/java/kinosearch/webapp/WebApp.java
Normal file
62
src/main/java/kinosearch/webapp/WebApp.java
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* DmitriyMX <dmitriymx@yandex.ru>
|
||||||
|
* 2017-12-11
|
||||||
|
*/
|
||||||
|
package kinosearch.webapp;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.springframework.web.context.ContextLoaderListener;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||||
|
import org.springframework.web.servlet.DispatcherServlet;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class WebApp {
|
||||||
|
private final Logger logger = Logger.getLogger(WebApp.class.getName());
|
||||||
|
private final String host;
|
||||||
|
private final int port;
|
||||||
|
|
||||||
|
public WebApp(String host, int port) {
|
||||||
|
this.host = host;
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
Server server = new Server(new InetSocketAddress(host, port));
|
||||||
|
server.setHandler(getServletContextHandler(getContext()));
|
||||||
|
try {
|
||||||
|
server.start();
|
||||||
|
server.join();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.SEVERE, "Start server", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServletContextHandler getServletContextHandler(WebApplicationContext context) {
|
||||||
|
ServletContextHandler contextHandler = new ServletContextHandler();
|
||||||
|
contextHandler.setErrorHandler(null);
|
||||||
|
contextHandler.setContextPath("/");
|
||||||
|
contextHandler.addServlet(new ServletHolder(new DispatcherServlet(context)), "/*");
|
||||||
|
contextHandler.addEventListener(new ContextLoaderListener(context));
|
||||||
|
return contextHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WebApplicationContext getContext() {
|
||||||
|
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
|
||||||
|
context.setConfigLocation("kinosearch.webapp");
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* DmitriyMX <dmitriymx@yandex.ru>
|
|
||||||
* 2017-01-04
|
|
||||||
*/
|
|
||||||
package kinosearch.webapp;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import kinosearch.core.KinoPlay;
|
|
||||||
import kinosearch.core.SpringConfig;
|
|
||||||
import org.springframework.context.annotation.*;
|
|
||||||
import org.springframework.web.servlet.ViewResolver;
|
|
||||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
|
||||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
|
||||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
|
||||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableWebMvc
|
|
||||||
@ComponentScan
|
|
||||||
@Import(SpringConfig.class)
|
|
||||||
public class WebAppConfiguration extends WebMvcConfigurerAdapter {
|
|
||||||
@Bean
|
|
||||||
public ViewResolver viewResolver() {
|
|
||||||
FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver();
|
|
||||||
viewResolver.setCache(true);
|
|
||||||
viewResolver.setSuffix(".html");
|
|
||||||
return viewResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public FreeMarkerConfigurer freemarkerConfig() {
|
|
||||||
FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
|
|
||||||
freeMarkerConfigurer.setTemplateLoaderPath("/WEB-INF/");
|
|
||||||
return freeMarkerConfigurer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@Scope("singleton")
|
|
||||||
public Gson gson() {
|
|
||||||
return new GsonBuilder().registerTypeAdapter(KinoPlay.class, new KinoPlaySerializer()).create();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
|
||||||
registry.addResourceHandler("/css/**")
|
|
||||||
.addResourceLocations("/css/");
|
|
||||||
registry.addResourceHandler("/fonts/**")
|
|
||||||
.addResourceLocations("/fonts/");
|
|
||||||
registry.addResourceHandler("/js/**")
|
|
||||||
.addResourceLocations("/js/");
|
|
||||||
registry.addResourceHandler("/*.png")
|
|
||||||
.addResourceLocations("/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,57 +16,50 @@ import org.springframework.ui.ModelMap;
|
|||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/")
|
|
||||||
public class WebAppController {
|
public class WebAppController {
|
||||||
@Autowired
|
private final Logger logger = Logger.getLogger(WebAppController.class.getName());
|
||||||
private ServletContext webAppContext;
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApplicationContext coreContext;
|
private ApplicationContext coreContext;
|
||||||
|
|
||||||
private void setDefaultModel(ModelMap model) {
|
private void setDefaultModel(ModelMap model) {
|
||||||
model.addAttribute("basedir", webAppContext.getContextPath());
|
model.addAttribute("version", "2.0.10-SNAPSHOT");
|
||||||
model.addAttribute("version", "2.0.9");
|
|
||||||
model.addAttribute("rutext", "Поиск кино по пиратским кинотеатрам");
|
model.addAttribute("rutext", "Поиск кино по пиратским кинотеатрам");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDefaultResponse(HttpServletResponse response) {
|
@RequestMapping(value = {"/", "/index.html"}, method = RequestMethod.GET)
|
||||||
response.setContentType("text/html");
|
public String index(ModelMap model) {
|
||||||
response.setCharacterEncoding("utf-8");
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(value = { "/", "/index.html" }, method = RequestMethod.GET)
|
|
||||||
public String index(ModelMap model, HttpServletRequest request, HttpServletResponse response) {
|
|
||||||
setDefaultModel(model);
|
setDefaultModel(model);
|
||||||
setDefaultResponse(response);
|
|
||||||
|
|
||||||
if (request.getParameter("search") != null && !request.getParameter("search").trim().isEmpty()) {
|
|
||||||
boolean strong = (request.getParameter("strong") != null && request.getParameter("strong").equals("1"));
|
|
||||||
search(request.getParameter("search"), model, strong);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "index";
|
return "index";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void search(String search, ModelMap model, boolean strong) {
|
@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<>());
|
List<Kino> list = Collections.synchronizedList(new LinkedList<>());
|
||||||
Map<String, KinoWarez> kinoWarezMap = coreContext.getBeansOfType(KinoWarez.class);
|
Map<String, KinoWarez> kinoWarezMap = coreContext.getBeansOfType(KinoWarez.class);
|
||||||
|
|
||||||
ThreadGroup threadGroup = new ThreadGroup("");
|
ThreadGroup threadGroup = new ThreadGroup("");
|
||||||
for (KinoWarez kinoWarez : kinoWarezMap.values()) { //TODO на будущее надо ограничить количество одновременных потоков
|
for (KinoWarez kinoWarez : kinoWarezMap.values()) { //TODO надо ограничить количество одновременных потоков
|
||||||
new Thread(threadGroup, () -> {
|
new Thread(threadGroup, () -> {
|
||||||
List<Kino> outList = kinoWarez.search(search, strong);
|
List<Kino> outList = kinoWarez.search(searchText, false); //FIXME "strong" нужно учитывать
|
||||||
|
|
||||||
for (Kino kino : outList) {
|
for (Kino kino : outList) {
|
||||||
kino.setName("[" + kinoWarez.getName() + "] " + kino.getName());
|
kino.setName("[" + kinoWarez.getName() + "] " + kino.getName());
|
||||||
@@ -81,9 +74,12 @@ public class WebAppController {
|
|||||||
Tools.SafeSleep(1000);
|
Tools.SafeSleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
model.put("searchtext", search);
|
model.put("searchtext", searchText);
|
||||||
model.put("resultsearch", groupKino(list));
|
model.put("resultsearch", groupKino(list));
|
||||||
model.put("strong", strong);
|
model.put("strong", false); //FIXME "strong" нужно учитывать
|
||||||
|
|
||||||
|
setDefaultModel(model);
|
||||||
|
return "index";
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Kino> groupKino(List<Kino> list) {
|
private List<Kino> groupKino(List<Kino> list) {
|
||||||
@@ -138,32 +134,28 @@ public class WebAppController {
|
|||||||
return grouppedList;
|
return grouppedList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/about.html", method = RequestMethod.GET)
|
|
||||||
public String about(ModelMap model, HttpServletResponse response) {
|
|
||||||
setDefaultModel(model);
|
|
||||||
setDefaultResponse(response);
|
|
||||||
return "simple_template/about";
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(value = "/player/{warez}/**", method = RequestMethod.GET)
|
@RequestMapping(value = "/player/{warez}/**", method = RequestMethod.GET)
|
||||||
public String player(@PathVariable() String warez, ModelMap model, HttpServletRequest request, HttpServletResponse response) {
|
public String player(@PathVariable() String warez, ModelMap model, HttpServletRequest request) throws MalformedURLException {
|
||||||
setDefaultModel(model);
|
|
||||||
setDefaultResponse(response);
|
|
||||||
|
|
||||||
KinoWarez kinoWarez = coreContext.getBean(warez, KinoWarez.class);
|
KinoWarez kinoWarez = coreContext.getBean(warez, KinoWarez.class);
|
||||||
if (kinoWarez == null) {
|
if (kinoWarez == null) {
|
||||||
return "redirect:/";
|
return "redirect:/";
|
||||||
}
|
}
|
||||||
KinoPlay kinoPlay = kinoWarez.player(request.getServletPath().substring(("/player/"+warez).length()));
|
|
||||||
|
//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);
|
Gson gson = coreContext.getBean(Gson.class);
|
||||||
model.put("json", gson.toJson(kinoPlay));
|
model.put("json", gson.toJson(kinoPlay));
|
||||||
|
|
||||||
|
setDefaultModel(model);
|
||||||
return "player";
|
return "player";
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/proxy/{warez}/**", method = RequestMethod.GET)
|
@RequestMapping(value = "/proxy/{warez}/**", method = RequestMethod.GET)
|
||||||
public void proxy(@PathVariable String warez, HttpServletRequest request, HttpServletResponse response) throws IOException {
|
public void proxy(@PathVariable String warez, HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
String path = request.getServletPath().substring(("/proxy/"+warez+"/").length());
|
//TODO а необходимость в URL точно оправдана?
|
||||||
|
URL requestUrl = new URL(request.getRequestURL().toString());
|
||||||
|
String path = requestUrl.getPath().substring(("/proxy/"+warez+"/").length());
|
||||||
|
|
||||||
URL url = new URL("http://" + path);
|
URL url = new URL("http://" + path);
|
||||||
HttpURLConnection con =(HttpURLConnection) url.openConnection();
|
HttpURLConnection con =(HttpURLConnection) url.openConnection();
|
||||||
@@ -211,4 +203,19 @@ public class WebAppController {
|
|||||||
webToProxyBuf.close();
|
webToProxyBuf.close();
|
||||||
con.disconnect();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* DmitriyMX <dmitriymx@yandex.ru>
|
|
||||||
* 2017-01-04
|
|
||||||
*/
|
|
||||||
package kinosearch.webapp;
|
|
||||||
|
|
||||||
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
|
|
||||||
|
|
||||||
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
|
|
||||||
@Override
|
|
||||||
protected Class<?>[] getRootConfigClasses() {
|
|
||||||
return new Class<?>[]{WebAppConfiguration.class};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Class<?>[] getServletConfigClasses() {
|
|
||||||
return new Class<?>[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String[] getServletMappings() {
|
|
||||||
return new String[]{"/"};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2
src/main/resources/application.properties
Normal file
2
src/main/resources/application.properties
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
webapp.host=127.0.0.1
|
||||||
|
webapp.port=8080
|
||||||
28
src/main/resources/kinosearch/webapp/about.ftl
Normal file
28
src/main/resources/kinosearch/webapp/about.ftl
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
[#ftl]
|
||||||
|
[#include "/header.inc.ftl"]
|
||||||
|
<hr>
|
||||||
|
<p>
|
||||||
|
Частенько бывает, что желанный фильм, мультфильм или сериал располагается только на одном каком-то кино-ресурсе.
|
||||||
|
И хорошо, если этот ресурс был первым в вашем списке ручного поиска кино.<br>
|
||||||
|
А если нет?<br>
|
||||||
|
А если у вас таких сайтов 5-10?<br>
|
||||||
|
А если на всех ваших любимых сайтах не оказалась искомого?<br>
|
||||||
|
Тогда вы лезете в Google/Яндекс и...
|
||||||
|
И обязательно напарываетесь на какую-то напичканную рекламой хрень, где еще и вылезет ошибка "фильм не найден".
|
||||||
|
Поиск "кинца" начинает затягиваться, а желание его посмотреть и вовсе улетучится.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Нет, так быть не должно! Если уж решился смотреть кино в онлайне, то пусть это будет комфортно!<br>
|
||||||
|
Мой проект возьмет всю рутину поиска на себя, а вам остается только выбрать место просмотра и наслаждаться
|
||||||
|
фильмом/сериалом/еще чем-то.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Кинотеатры подбираются так, чтобы в них было поменьше рекламы и побольше нужных фильмов. А в скором времени я и
|
||||||
|
это ... упрощу =)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Приятного просмотра!
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<p>Автор: <a href="http://dmitriymx.di9.ru">DmitriyMX</a>/2015</p>
|
||||||
|
[#include "/fother.inc.ftl"]
|
||||||
35
src/main/resources/kinosearch/webapp/header.inc.ftl
Normal file
35
src/main/resources/kinosearch/webapp/header.inc.ftl
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
[#ftl]
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="description" content="${rutext}">
|
||||||
|
<meta name="version" content="${version}">
|
||||||
|
<title>KinoSearch :: ${rutext}</title>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/ks3logo.svg" >
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/awesome-bootstrap-checkbox.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/style.css">
|
||||||
|
<script type="text/javascript" src="/js/jquery-2.1.4.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/js/bootstrap.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="title"><a href="/"><img src="/ks3logo.svg"> KinoSearch</a></h1>
|
||||||
|
<p class="text-center">${rutext}</p>
|
||||||
|
<form method="get" action="/">
|
||||||
|
<div class="input-group">
|
||||||
|
<input class="form-control" type="text" placeholder="Что ищем?" name="search" value="[#if searchtext??]${searchtext}[/#if]"/>
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-primary" type="submit">Ищи!</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox checkbox-primary">
|
||||||
|
<input type="checkbox" id="strong" name="strong" value="1"[#if strong?? && strong = true] checked[/#if]>
|
||||||
|
<label for="strong">Точное совпадение</label>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="text-center">
|
||||||
|
<a href="/about.html">О проекте</a> | <a href="mailto:dmitriymx@yandex.ru">Написать отзыв</a>
|
||||||
|
</div>
|
||||||
62
src/main/resources/kinosearch/webapp/index.ftl
Normal file
62
src/main/resources/kinosearch/webapp/index.ftl
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
[#ftl]
|
||||||
|
[#include "/header.inc.ftl"]
|
||||||
|
[#if resultsearch??]
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function(){
|
||||||
|
$('a.spoiler').bind('click',function(){
|
||||||
|
$(this).next().collapse('toggle');
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<hr>
|
||||||
|
[#if resultsearch?has_content]
|
||||||
|
[#list resultsearch as kino]
|
||||||
|
[#if kino.getClass().getSimpleName() == "KinoGroup"]
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<a href="#" class="panel-heading spoiler">
|
||||||
|
<span class="glyphicon glyphicon-chevron-down"> </span><b>${kino.name}</b>
|
||||||
|
</a>
|
||||||
|
<div class="panel-collapse collapse out">
|
||||||
|
<div class="panel-body">
|
||||||
|
[#list kino.kinolist as kino_groupped]
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><b>${kino_groupped.name}</b></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<a class="btn btn-primary btn-block" href="${kino_groupped.url}" target="_blank">на сайте</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<a class="btn btn-danger btn-block" href="/player/${kino_groupped.getPlayerUrl()}" target="_blank">в плеере</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
[/#list]
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
[#else]
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><b>${kino.name}</b></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<a class="btn btn-primary btn-block" href="${kino.url}" target="_blank">на сайте</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<a class="btn btn-danger btn-block" href="/player/${kino.getPlayerUrl()}" target="_blank">в плеере</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
[/#if]
|
||||||
|
[/#list]
|
||||||
|
[#else]
|
||||||
|
<p>Ничего не найдено =(</p>
|
||||||
|
[/#if]
|
||||||
|
[#else]
|
||||||
|
[#include "/news.inc.ftl"]
|
||||||
|
[/#if]
|
||||||
|
[#include "/fother.inc.ftl"]
|
||||||
117
src/main/resources/kinosearch/webapp/player.ftl
Normal file
117
src/main/resources/kinosearch/webapp/player.ftl
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
[#ftl]
|
||||||
|
[#include "/header.inc.ftl"]
|
||||||
|
<script type="text/javascript" src="/js/js.cookie-2.1.0.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/js/player.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var playerCore;
|
||||||
|
var data;
|
||||||
|
var plSeason;
|
||||||
|
var plSerial;
|
||||||
|
var playerObj;
|
||||||
|
|
||||||
|
$(function(){
|
||||||
|
var video_data = ${json};
|
||||||
|
var titleObj = $('#title');
|
||||||
|
|
||||||
|
plSeason = $('#pl-season');
|
||||||
|
plSerial = $('#pl-serial');
|
||||||
|
playerObj = $('#player');
|
||||||
|
|
||||||
|
playerCore = new PlayerCore(playerObj, titleObj, video_data);
|
||||||
|
playerCore.setupPlayer();
|
||||||
|
|
||||||
|
// загрузка ранее сохранённых данных
|
||||||
|
data = Cookies.getJSON(playerCore.path);
|
||||||
|
if (data != null) {
|
||||||
|
var fulltime = playerCore.msToTime(data.time * 1000);
|
||||||
|
$('#mdl-vtime').text(fulltime.h + ':' + fulltime.m + ':' + fulltime.s);
|
||||||
|
if (playerCore.getType() == 'simple_serial') {
|
||||||
|
$('#mdl-serial').find('span').text(data.serial + 1);
|
||||||
|
$('#mdl-serial').removeClass('hide');
|
||||||
|
} else if (playerCore.getType() == 'seasons_serial') {
|
||||||
|
$('#mdl-season').find('span').text(data.season + 1);
|
||||||
|
$('#mdl-season').removeClass('hide');
|
||||||
|
$('#mdl-serial').find('span').text(data.serial + 1);
|
||||||
|
$('#mdl-serial').removeClass('hide');
|
||||||
|
}
|
||||||
|
$('#modal').modal('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playerCore.getType() == 'one_film') {
|
||||||
|
playerCore.setTitle();
|
||||||
|
playerCore.setupPlayerForOneFilm();
|
||||||
|
} else if (playerCore.getType() == 'simple_serial') {
|
||||||
|
playerCore.setupPlayerForSimpleSerial($('#pl-serial'));
|
||||||
|
titleObj.hide();
|
||||||
|
} else if (playerCore.getType() == 'seasons_serial') {
|
||||||
|
playerCore.setupPlayerForSeasonSerial($('#pl-season'), $('#pl-serial'));
|
||||||
|
titleObj.hide();
|
||||||
|
} else {
|
||||||
|
console.debug(playerCore.videoData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function continueVideo() {
|
||||||
|
if (playerCore.getType() == 'simple_serial') {
|
||||||
|
playerCore.setSerial(data.serial, plSerial);
|
||||||
|
} else if (playerCore.getType() == 'seasons_serial') {
|
||||||
|
playerCore.setSeason(data.season, plSeason);
|
||||||
|
playerCore.setSerial(data.serial, plSerial, data.season);
|
||||||
|
}
|
||||||
|
playerObj[0].currentTime = data.time;
|
||||||
|
playerObj.load();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="modal fade" tabindex="-1" role="dialog" id="modal">
|
||||||
|
<div class="modal-dialog modal-sm">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Продолжить просмотр?</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<b>Время:</b> <span id="mdl-vtime"></span>
|
||||||
|
<div id="mdl-blk-serial">
|
||||||
|
<div id="mdl-season" class="hide"><b>Сезон:</b> <span></span></div>
|
||||||
|
<div id="mdl-serial" class="hide"><b>Серия:</b> <span></span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="continueVideo()">Да</button>
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal" onclick="playerObj.load()">Нет</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div id="pl-season" class="dropdown hide" style="display: inline-block;">
|
||||||
|
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownSeason" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||||
|
Seasons
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul id="pl-season-menu" class="dropdown-menu" aria-labelledby="dropdownSeason">
|
||||||
|
<li><a href="#">Season</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="pl-serial" class="dropdown hide" style="display: inline-block;">
|
||||||
|
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownSerial" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||||
|
Serials
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul id="pl-serial-menu" class="dropdown-menu" aria-labelledby="dropdownSerial">
|
||||||
|
<li><a href="#">Serial</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br id="plbr">
|
||||||
|
|
||||||
|
<h2 id="title"></h2>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<video id="player" class="center-block" controls="controls" preload="none"></video>
|
||||||
|
<br>
|
||||||
|
[#include "/fother.inc.ftl"]
|
||||||
@@ -12,12 +12,10 @@ body {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title .logo {
|
.title img {
|
||||||
background-image: url("../favicon.png");
|
vertical-align: bottom;
|
||||||
width: 2em;
|
height: 1.119em;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-size: 2em auto;
|
|
||||||
background-position: 0px center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.title a {
|
.title a {
|
||||||
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
@@ -1,11 +1,9 @@
|
|||||||
function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
function PlayerCore(playerObj, titleObj, videoData) {
|
||||||
this.baseDir = baseDir;
|
|
||||||
this.playerObj = playerObj;
|
this.playerObj = playerObj;
|
||||||
this.titleObj = titleObj;
|
this.titleObj = titleObj;
|
||||||
this.videoData = videoData;
|
this.videoData = videoData;
|
||||||
this.origDocTitle = document.title;
|
this.origDocTitle = document.title;
|
||||||
|
|
||||||
this.path = window.location.pathname.substr(baseDir.length);
|
|
||||||
this.timeLast = 0;
|
this.timeLast = 0;
|
||||||
|
|
||||||
this.msToTime = function(ms) {
|
this.msToTime = function(ms) {
|
||||||
@@ -23,22 +21,22 @@ function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
|||||||
'm': addZ(_min),
|
'm': addZ(_min),
|
||||||
'h': addZ(_hr)
|
'h': addZ(_hr)
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
this.setTitle = function(title = videoData.title) {
|
this.setTitle = function(title = videoData.title) {
|
||||||
document.title = title + " :: " + this.origDocTitle;
|
document.title = title + " :: " + this.origDocTitle;
|
||||||
titleObj.text(title);
|
titleObj.text(title);
|
||||||
titleObj.show();
|
titleObj.show();
|
||||||
}
|
};
|
||||||
|
|
||||||
this.getType = function() {
|
this.getType = function() {
|
||||||
return this.videoData.type;
|
return this.videoData.type;
|
||||||
}
|
};
|
||||||
|
|
||||||
this.setupPlayerForOneFilm = function() {
|
this.setupPlayerForOneFilm = function() {
|
||||||
playerObj.attr('src', this.baseDir + videoData.file);
|
playerObj.attr('src', videoData.file);
|
||||||
playerObj.load();
|
playerObj.load();
|
||||||
}
|
};
|
||||||
|
|
||||||
this.setupPlayerForSimpleSerial = function(serialBlock) {
|
this.setupPlayerForSimpleSerial = function(serialBlock) {
|
||||||
var menu = serialBlock.find('.dropdown-menu');
|
var menu = serialBlock.find('.dropdown-menu');
|
||||||
@@ -53,7 +51,7 @@ function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
serialBlock.removeClass('hide');
|
serialBlock.removeClass('hide');
|
||||||
}
|
};
|
||||||
|
|
||||||
this.setupPlayerForSeasonSerial = function(seasonBlock, serialBlock) {
|
this.setupPlayerForSeasonSerial = function(seasonBlock, serialBlock) {
|
||||||
var menu = seasonBlock.find('.dropdown-menu');
|
var menu = seasonBlock.find('.dropdown-menu');
|
||||||
@@ -62,13 +60,13 @@ function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
|||||||
this.videoData.seasons.forEach(function(item, i) {
|
this.videoData.seasons.forEach(function(item, i) {
|
||||||
var aTag = $('<a/>', {'href':'#', 'text':item.title});
|
var aTag = $('<a/>', {'href':'#', 'text':item.title});
|
||||||
aTag.click(function(){_self.setSeason(i, seasonBlock, serialBlock)});
|
aTag.click(function(){_self.setSeason(i, seasonBlock, serialBlock)});
|
||||||
var liTag = $('<li/>')
|
var liTag = $('<li/>');
|
||||||
liTag.append(aTag);
|
liTag.append(aTag);
|
||||||
menu.append(liTag);
|
menu.append(liTag);
|
||||||
});
|
});
|
||||||
|
|
||||||
seasonBlock.removeClass('hide');
|
seasonBlock.removeClass('hide');
|
||||||
}
|
};
|
||||||
|
|
||||||
this.setupPlayer = function() {
|
this.setupPlayer = function() {
|
||||||
var _self = this;
|
var _self = this;
|
||||||
@@ -90,17 +88,17 @@ function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
|||||||
console.debug({'path': _self.path, 'saveTime': save_data});
|
console.debug({'path': _self.path, 'saveTime': save_data});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
this.setSerial = function(idx, serialBlock, sidx = 0) {
|
this.setSerial = function(idx, serialBlock, sidx = 0) {
|
||||||
var title;
|
var title;
|
||||||
var playerSrc;
|
var playerSrc;
|
||||||
if (this.getType() == 'seasons_serial') {
|
if (this.getType() == 'seasons_serial') {
|
||||||
title = videoData.seasons[sidx].serials[idx].title;
|
title = videoData.seasons[sidx].serials[idx].title;
|
||||||
playerSrc = this.baseDir + videoData.seasons[sidx].serials[idx].file;
|
playerSrc = videoData.seasons[sidx].serials[idx].file;
|
||||||
} else {
|
} else {
|
||||||
title = videoData.serials[idx].title;
|
title = videoData.serials[idx].title;
|
||||||
playerSrc = this.baseDir + videoData.serials[idx].file;
|
playerSrc = videoData.serials[idx].file;
|
||||||
}
|
}
|
||||||
this.setTitle(title);
|
this.setTitle(title);
|
||||||
|
|
||||||
@@ -110,7 +108,7 @@ function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
|||||||
playerObj.attr('src', playerSrc);
|
playerObj.attr('src', playerSrc);
|
||||||
playerObj.attr('data-serial', idx);
|
playerObj.attr('data-serial', idx);
|
||||||
playerObj.load();
|
playerObj.load();
|
||||||
}
|
};
|
||||||
|
|
||||||
this.setSeason = function(idx, seasonBlock, serialBlock) {
|
this.setSeason = function(idx, seasonBlock, serialBlock) {
|
||||||
var title = videoData.seasons[idx].title;
|
var title = videoData.seasons[idx].title;
|
||||||
@@ -124,7 +122,7 @@ function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
|||||||
this.videoData.seasons[idx].serials.forEach(function(item, i) {
|
this.videoData.seasons[idx].serials.forEach(function(item, i) {
|
||||||
var aTag = $('<a/>', {'href':'#', 'text':item.title});
|
var aTag = $('<a/>', {'href':'#', 'text':item.title});
|
||||||
aTag.click(function(){_self.setSerial(i, serialBlock, idx)});
|
aTag.click(function(){_self.setSerial(i, serialBlock, idx)});
|
||||||
var liTag = $('<li/>')
|
var liTag = $('<li/>');
|
||||||
liTag.append(aTag);
|
liTag.append(aTag);
|
||||||
menu.append(liTag);
|
menu.append(liTag);
|
||||||
});
|
});
|
||||||
34
src/main/resources/kinosearch/webapp/static/ks3logo.svg
Normal file
34
src/main/resources/kinosearch/webapp/static/ks3logo.svg
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" id="ks3logo" viewBox="0 0 492 208" version="1.1" xml:space="preserve" x="0px" y="0px" width="492" height="208">
|
||||||
|
<g id="node0">
|
||||||
|
<g id="node1">
|
||||||
|
<path d="m 149.1667,7.1667 c 22.5,-9.6667 45.1666,-10.8334 58.3333,6.5 C 196.8333,21.3333 23.6667,69 23.6667,69 L 0,69 C 0,69 148.5,7.5 149.1667,7.1667 Z" id="path5" style="fill:#e2e2e2"/>
|
||||||
|
<path d="m 165.1667,7.1667 c 28.8333,-5.8334 51,-5.3334 54.5,47 1.5,23.3333 -25.1463,28.4274 -31.1667,13 C 185.6667,59 198.25,23.5 172.4344,32.3417 154.3706,38.5285 84,69 84,69 L 16,69 C 16,69 164.5,7.5 165.1667,7.1667 Z" id="path7" style="fill:#c9c9c9"/>
|
||||||
|
<path d="m 219.5115,52.0346 c 0.0552,0.7009 0.107,1.4116 0.1552,2.1321 1.5,23.3333 -25.1463,28.4274 -31.1667,13 -0.2215,-0.6384 -0.4032,-1.3449 -0.5529,-2.1074" id="path9" style="opacity:0.2;fill:#000000"/>
|
||||||
|
<path d="M 10,65 94,65 84,69 0,69 10,65 Z" id="path11" style="opacity:0.2;fill:#000000"/>
|
||||||
|
</g>
|
||||||
|
<g id="node2">
|
||||||
|
<path d="M 343.3333,7.1667 C 320.8334,-2.5 298.1666,-3.6667 285,13.6667 295.6666,21.3333 468.3334,69 468.3334,69 L 492,69 C 492,69 344,7.5 343.3333,7.1667 Z" id="path14" style="fill:#e2e2e2"/>
|
||||||
|
<path d="m 327.5609,7.1667 c -28.8333,-5.8334 -51,-5.3334 -54.5,47 -1.5,23.3333 25.1463,28.4274 31.1667,13 C 307.0609,59 294.4776,23.5 320.2932,32.3417 338.357,38.5285 408.7276,69 408.7276,69 l 68,0 c 0,0 -148.5001,-61.5 -149.1667,-61.8333 z" id="path16" style="fill:#c9c9c9"/>
|
||||||
|
<path d="m 273.1631,52.0346 c -0.0552,0.7009 -0.1069,1.4116 -0.1552,2.1321 -1.5,23.3333 25.1463,28.4274 31.1667,13 0.2215,-0.6384 0.4033,-1.3449 0.5529,-2.1074" id="path18" style="opacity:0.2;fill:#000000"/>
|
||||||
|
<path d="m 482,65 -83,0 10,4 83,0 -10,-4 z" id="path20" style="opacity:0.2;fill:#000000"/>
|
||||||
|
</g>
|
||||||
|
<g id="node3">
|
||||||
|
<path d="m 0,69 492,0 0,139 -214,0 -21,-75 -22,0 -21,75 L 0,208 0,69 Z" id="path23" style="fill:#e2e2e2"/>
|
||||||
|
<path d="m 0,197 217,0 -3,11 -214,0 0,-11 z" id="path25" style="fill:#cbcbcb"/>
|
||||||
|
<path d="m 275,197 217,0 0,11 -214,0 -3,-11 z" id="path27" style="fill:#cbcbcb"/>
|
||||||
|
<path d="m 0,69 492,0 0,5 -492,0 0,-5 z" id="path29" style="fill:#fcfcfc"/>
|
||||||
|
</g>
|
||||||
|
<g id="node4">
|
||||||
|
<path d="M 294,101.125 C 294,97.7422 296.7422,95 300.125,95 l 169.75,0 c 3.3828,0 6.125,2.7422 6.125,6.125 l 0,79.75 c 0,3.3828 -2.7422,6.125 -6.125,6.125 l -169.75,0 C 296.7422,187 294,184.2578 294,180.875 l 0,-79.75 z" id="path32" style="fill:#ce504d"/>
|
||||||
|
<path d="m 398,95 45,0 -92,92 -45,0 92,-92 z" id="path34" style="fill:#e56161"/>
|
||||||
|
<path d="m 294,174.875 0,6 c 0,3.3828 2.7422,6.125 6.125,6.125 l 169.75,0 c 3.3828,0 6.125,-2.7422 6.125,-6.125 l 0,-6 c 0,3.3828 -2.7422,6.125 -6.125,6.125 l -169.75,0 C 296.7422,181 294,178.2578 294,174.875 Z" id="path36" style="opacity:0.2196;fill:#000000"/>
|
||||||
|
</g>
|
||||||
|
<g id="node5">
|
||||||
|
<path d="M 16,101.125 C 16,97.7422 18.7422,95 22.125,95 l 169.75,0 c 3.3828,0 6.125,2.7422 6.125,6.125 l 0,79.75 c 0,3.3828 -2.7422,6.125 -6.125,6.125 l -169.75,0 C 18.7422,187 16,184.2578 16,180.875 l 0,-79.75 z" id="path39" style="fill:#4e96cc"/>
|
||||||
|
<path d="m 59.5,187 -19.5,0 92,-92 19,0 -91.5,92 z" id="path41" style="fill:#5ab0e5"/>
|
||||||
|
<path d="M 158,95 168,95 76.6667,187 66,187 158,95 Z" id="path43" style="fill:#5ab0e5"/>
|
||||||
|
<path d="m 16,174.875 0,6 c 0,3.3828 2.7422,6.125 6.125,6.125 l 169.75,0 c 3.3828,0 6.125,-2.7422 6.125,-6.125 l 0,-6 c 0,3.3828 -2.7422,6.125 -6.125,6.125 l -169.75,0 C 18.7422,181 16,178.2578 16,174.875 Z" id="path45" style="opacity:0.2196;fill:#000000"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
@@ -1,35 +0,0 @@
|
|||||||
[#ftl]
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="ru">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<meta name="description" content="${rutext}">
|
|
||||||
<meta name="version" content="${version}">
|
|
||||||
<title>KinoSearch :: ${rutext}</title>
|
|
||||||
<link rel="icon" type="image/png" href="${basedir}/favicon.png" >
|
|
||||||
<link rel="stylesheet" type="text/css" href="${basedir}/css/bootstrap.min.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="${basedir}/css/awesome-bootstrap-checkbox.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="${basedir}/css/style.css">
|
|
||||||
<script type="text/javascript" src="${basedir}/js/jquery-2.1.4.min.js"></script>
|
|
||||||
<script type="text/javascript" src="${basedir}/js/bootstrap.min.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1 class="title"><a href="${basedir}/"><span class="logo"> </span> KinoSearch</a></h1>
|
|
||||||
<p class="text-center">${rutext}</p>
|
|
||||||
<form method="get" action="${basedir}/">
|
|
||||||
<div class="input-group">
|
|
||||||
<input class="form-control" type="text" placeholder="Что ищем?" name="search" value="[#if searchtext??]${searchtext}[/#if]"/>
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button class="btn btn-primary" type="submit">Ищи!</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="checkbox checkbox-primary">
|
|
||||||
<input type="checkbox" id="strong" name="strong" value="1"[#if strong?? && strong = true] checked[/#if]>
|
|
||||||
<label for="strong">Точное совпадение</label>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<div class="text-center">
|
|
||||||
<a href="${basedir}/about.html">О проекте</a> | <a href="mailto:admin@dmitriymx.ru">Написать отзыв</a>
|
|
||||||
</div>
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
[#ftl]
|
|
||||||
[#include "/header.inc.html"]
|
|
||||||
[#if resultsearch??]
|
|
||||||
<script type="text/javascript">
|
|
||||||
$(function(){
|
|
||||||
$('a.spoiler').bind('click',function(){
|
|
||||||
$(this).next().collapse('toggle');
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<hr>
|
|
||||||
[#if resultsearch?has_content]
|
|
||||||
[#list resultsearch as kino]
|
|
||||||
[#if kino.getClass().getSimpleName() == "KinoGroup"]
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<a href="#" class="panel-heading spoiler">
|
|
||||||
<span class="glyphicon glyphicon-chevron-down"> </span><b>${kino.name}</b>
|
|
||||||
</a>
|
|
||||||
<div class="panel-collapse collapse out">
|
|
||||||
<div class="panel-body">
|
|
||||||
[#list kino.kinolist as kino_groupped]
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading"><b>${kino_groupped.name}</b></div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<a class="btn btn-primary btn-block" href="${kino_groupped.url}" target="_blank">на сайте</a>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<a class="btn btn-danger btn-block" href="/player/${kino_groupped.getPlayerUrl()}" target="_blank">в плеере</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
[/#list]
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
[#else]
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading"><b>${kino.name}</b></div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<a class="btn btn-primary btn-block" href="${kino.url}" target="_blank">на сайте</a>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<a class="btn btn-danger btn-block" href="/player/${kino.getPlayerUrl()}" target="_blank">в плеере</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
[/#if]
|
|
||||||
[/#list]
|
|
||||||
[#else]
|
|
||||||
<p>Ничего не найдено =(</p>
|
|
||||||
[/#if]
|
|
||||||
[#else]
|
|
||||||
[#include "/news.inc.html"]
|
|
||||||
[/#if]
|
|
||||||
[#include "/fother.inc.html"]
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
[#ftl]
|
|
||||||
[#include "/header.inc.html"]
|
|
||||||
<script type="text/javascript" src="${basedir}/js/js.cookie-2.1.0.min.js"></script>
|
|
||||||
<script type="text/javascript" src="${basedir}/js/player.js"></script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
var playerCore;
|
|
||||||
var data;
|
|
||||||
var plSeason;
|
|
||||||
var plSerial;
|
|
||||||
var playerObj;
|
|
||||||
|
|
||||||
$(function(){
|
|
||||||
var video_data = ${json};
|
|
||||||
var titleObj = $('#title');
|
|
||||||
|
|
||||||
plSeason = $('#pl-season');
|
|
||||||
plSerial = $('#pl-serial');
|
|
||||||
playerObj = $('#player');
|
|
||||||
|
|
||||||
playerCore = new PlayerCore('${basedir}', playerObj, titleObj, video_data);
|
|
||||||
playerCore.setupPlayer();
|
|
||||||
|
|
||||||
// загрузка ранее сохранённых данных
|
|
||||||
data = Cookies.getJSON(playerCore.path);
|
|
||||||
if (data != null) {
|
|
||||||
var fulltime = playerCore.msToTime(data.time * 1000);
|
|
||||||
$('#mdl-vtime').text(fulltime.h + ':' + fulltime.m + ':' + fulltime.s);
|
|
||||||
if (playerCore.getType() == 'simple_serial') {
|
|
||||||
$('#mdl-serial').find('span').text(data.serial + 1);
|
|
||||||
$('#mdl-serial').removeClass('hide');
|
|
||||||
} else if (playerCore.getType() == 'seasons_serial') {
|
|
||||||
$('#mdl-season').find('span').text(data.season + 1);
|
|
||||||
$('#mdl-season').removeClass('hide');
|
|
||||||
$('#mdl-serial').find('span').text(data.serial + 1);
|
|
||||||
$('#mdl-serial').removeClass('hide');
|
|
||||||
}
|
|
||||||
$('#modal').modal('show');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playerCore.getType() == 'one_film') {
|
|
||||||
playerCore.setTitle();
|
|
||||||
playerCore.setupPlayerForOneFilm();
|
|
||||||
} else if (playerCore.getType() == 'simple_serial') {
|
|
||||||
playerCore.setupPlayerForSimpleSerial($('#pl-serial'));
|
|
||||||
titleObj.hide();
|
|
||||||
} else if (playerCore.getType() == 'seasons_serial') {
|
|
||||||
playerCore.setupPlayerForSeasonSerial($('#pl-season'), $('#pl-serial'));
|
|
||||||
titleObj.hide();
|
|
||||||
} else {
|
|
||||||
console.debug(playerCore.videoData);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function continueVideo() {
|
|
||||||
if (playerCore.getType() == 'simple_serial') {
|
|
||||||
playerCore.setSerial(data.serial, plSerial);
|
|
||||||
} else if (playerCore.getType() == 'seasons_serial') {
|
|
||||||
playerCore.setSeason(data.season, plSeason);
|
|
||||||
playerCore.setSerial(data.serial, plSerial, data.season);
|
|
||||||
}
|
|
||||||
playerObj[0].currentTime = data.time;
|
|
||||||
playerObj.load();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="modal fade" tabindex="-1" role="dialog" id="modal">
|
|
||||||
<div class="modal-dialog modal-sm">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h4 class="modal-title">Продолжить просмотр?</h4>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<b>Время:</b> <span id="mdl-vtime"></span>
|
|
||||||
<div id="mdl-blk-serial">
|
|
||||||
<div id="mdl-season" class="hide"><b>Сезон:</b> <span></span></div>
|
|
||||||
<div id="mdl-serial" class="hide"><b>Серия:</b> <span></span></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="continueVideo()">Да</button>
|
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal" onclick="playerObj.load()">Нет</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div id="pl-season" class="dropdown hide" style="display: inline-block;">
|
|
||||||
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownSeason" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
|
||||||
Seasons
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<ul id="pl-season-menu" class="dropdown-menu" aria-labelledby="dropdownSeason">
|
|
||||||
<li><a href="#">Season</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="pl-serial" class="dropdown hide" style="display: inline-block;">
|
|
||||||
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownSerial" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
|
||||||
Serials
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<ul id="pl-serial-menu" class="dropdown-menu" aria-labelledby="dropdownSerial">
|
|
||||||
<li><a href="#">Serial</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<br id="plbr">
|
|
||||||
|
|
||||||
<h2 id="title"></h2>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<video id="player" class="center-block" controls="controls" preload="none"></video>
|
|
||||||
<br>
|
|
||||||
[#include "/fother.inc.html"]
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
[#ftl]
|
|
||||||
[#include "/header.inc.html"]
|
|
||||||
<hr>
|
|
||||||
<p>
|
|
||||||
Частенько бывает, что желанный фильм, мультфильм или сериал располагается только на одном каком-то кино-ресурсе.
|
|
||||||
И хорошо, если этот ресурс был первым в вашем списке ручного поиска кино.<br>
|
|
||||||
А если нет?<br>
|
|
||||||
А если у вас таких сайтов 5-10?<br>
|
|
||||||
А если на всех ваших любимых сайтах не оказалась искомого?<br>
|
|
||||||
Тогда вы лезете в Google/Яндекс и...
|
|
||||||
И обязательно напарываетесь на какую-то напичканную рекламой хрень, где еще и вылезет ошибка "фильм не найден".
|
|
||||||
Поиск "кинца" начинает затягиваться, а желание его посмотреть и вовсе улетучится.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Нет, так быть не должно! Если уж решился смотреть кино в онлайне, то пусть это будет комфортно!<br>
|
|
||||||
Мой проект возьмет всю рутину поиска на себя, а вам остается только выбрать место просмотра и наслаждаться
|
|
||||||
фильмом/сериалом/еще чем-то.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Кинотеатры подбираются так, чтобы в них было поменьше рекламы и побольше нужных фильмов. А в скором времени я и
|
|
||||||
это ... упрощу =)
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Приятного просмотра!
|
|
||||||
</p>
|
|
||||||
<hr>
|
|
||||||
<p>Автор: <a href="http://dmitriymx.ru">DmitriyMX</a> / 2015</p>
|
|
||||||
[#include "/fother.inc.html"]
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.4 KiB |
Reference in New Issue
Block a user