Избавляемся от war
Теперь KinoSearch самодостаточен и может запускаться без внешних веб-контейнеров
This commit is contained in:
78
pom.xml
78
pom.xml
@@ -15,46 +15,51 @@
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<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>
|
||||
|
||||
<groupId>ru.dmitriymx</groupId>
|
||||
<artifactId>kinosearch</artifactId>
|
||||
<version>2.0.9</version>
|
||||
<packaging>war</packaging>
|
||||
<version>2.0.10-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
<!-- SPRING -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</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>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</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 -->
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
@@ -76,6 +81,7 @@
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- TESTING -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
@@ -114,16 +120,30 @@
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>dependency/</classpathPrefix>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-maven-plugin</artifactId>
|
||||
<version>9.4.0.v20161208</version>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>2.8</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-dependencies</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</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.RequestMapping;
|
||||
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.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
|
||||
@RequestMapping("/")
|
||||
public class WebAppController {
|
||||
@Autowired
|
||||
private ServletContext webAppContext;
|
||||
private final Logger logger = Logger.getLogger(WebAppController.class.getName());
|
||||
@Autowired
|
||||
private ApplicationContext coreContext;
|
||||
|
||||
private void setDefaultModel(ModelMap model) {
|
||||
model.addAttribute("basedir", webAppContext.getContextPath());
|
||||
model.addAttribute("version", "2.0.9");
|
||||
model.addAttribute("version", "2.0.10-SNAPSHOT");
|
||||
model.addAttribute("rutext", "Поиск кино по пиратским кинотеатрам");
|
||||
}
|
||||
|
||||
private void setDefaultResponse(HttpServletResponse response) {
|
||||
response.setContentType("text/html");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
}
|
||||
|
||||
@RequestMapping(value = { "/", "/index.html" }, method = RequestMethod.GET)
|
||||
public String index(ModelMap model, HttpServletRequest request, HttpServletResponse response) {
|
||||
@RequestMapping(value = {"/", "/index.html"}, method = RequestMethod.GET)
|
||||
public String index(ModelMap 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";
|
||||
}
|
||||
|
||||
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<>());
|
||||
Map<String, KinoWarez> kinoWarezMap = coreContext.getBeansOfType(KinoWarez.class);
|
||||
|
||||
ThreadGroup threadGroup = new ThreadGroup("");
|
||||
for (KinoWarez kinoWarez : kinoWarezMap.values()) { //TODO на будущее надо ограничить количество одновременных потоков
|
||||
for (KinoWarez kinoWarez : kinoWarezMap.values()) { //TODO надо ограничить количество одновременных потоков
|
||||
new Thread(threadGroup, () -> {
|
||||
List<Kino> outList = kinoWarez.search(search, strong);
|
||||
List<Kino> outList = kinoWarez.search(searchText, false); //FIXME "strong" нужно учитывать
|
||||
|
||||
for (Kino kino : outList) {
|
||||
kino.setName("[" + kinoWarez.getName() + "] " + kino.getName());
|
||||
@@ -81,9 +74,12 @@ public class WebAppController {
|
||||
Tools.SafeSleep(1000);
|
||||
}
|
||||
|
||||
model.put("searchtext", search);
|
||||
model.put("searchtext", searchText);
|
||||
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) {
|
||||
@@ -138,32 +134,28 @@ public class WebAppController {
|
||||
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)
|
||||
public String player(@PathVariable() String warez, ModelMap model, HttpServletRequest request, HttpServletResponse response) {
|
||||
setDefaultModel(model);
|
||||
setDefaultResponse(response);
|
||||
|
||||
public String player(@PathVariable() String warez, ModelMap model, HttpServletRequest request) throws MalformedURLException {
|
||||
KinoWarez kinoWarez = coreContext.getBean(warez, KinoWarez.class);
|
||||
if (kinoWarez == null) {
|
||||
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);
|
||||
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 {
|
||||
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);
|
||||
HttpURLConnection con =(HttpURLConnection) url.openConnection();
|
||||
@@ -211,4 +203,19 @@ public class WebAppController {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
.title .logo {
|
||||
background-image: url("../favicon.png");
|
||||
width: 2em;
|
||||
.title img {
|
||||
vertical-align: bottom;
|
||||
height: 1.119em;
|
||||
display: inline-block;
|
||||
background-size: 2em auto;
|
||||
background-position: 0px center;
|
||||
}
|
||||
|
||||
.title a {
|
||||
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
@@ -1,11 +1,9 @@
|
||||
function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
||||
this.baseDir = baseDir;
|
||||
function PlayerCore(playerObj, titleObj, videoData) {
|
||||
this.playerObj = playerObj;
|
||||
this.titleObj = titleObj;
|
||||
this.videoData = videoData;
|
||||
this.origDocTitle = document.title;
|
||||
|
||||
this.path = window.location.pathname.substr(baseDir.length);
|
||||
this.timeLast = 0;
|
||||
|
||||
this.msToTime = function(ms) {
|
||||
@@ -23,22 +21,22 @@ function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
||||
'm': addZ(_min),
|
||||
'h': addZ(_hr)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
this.setTitle = function(title = videoData.title) {
|
||||
document.title = title + " :: " + this.origDocTitle;
|
||||
titleObj.text(title);
|
||||
titleObj.show();
|
||||
}
|
||||
};
|
||||
|
||||
this.getType = function() {
|
||||
return this.videoData.type;
|
||||
}
|
||||
};
|
||||
|
||||
this.setupPlayerForOneFilm = function() {
|
||||
playerObj.attr('src', this.baseDir + videoData.file);
|
||||
playerObj.attr('src', videoData.file);
|
||||
playerObj.load();
|
||||
}
|
||||
};
|
||||
|
||||
this.setupPlayerForSimpleSerial = function(serialBlock) {
|
||||
var menu = serialBlock.find('.dropdown-menu');
|
||||
@@ -53,7 +51,7 @@ function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
||||
});
|
||||
|
||||
serialBlock.removeClass('hide');
|
||||
}
|
||||
};
|
||||
|
||||
this.setupPlayerForSeasonSerial = function(seasonBlock, serialBlock) {
|
||||
var menu = seasonBlock.find('.dropdown-menu');
|
||||
@@ -62,13 +60,13 @@ function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
||||
this.videoData.seasons.forEach(function(item, i) {
|
||||
var aTag = $('<a/>', {'href':'#', 'text':item.title});
|
||||
aTag.click(function(){_self.setSeason(i, seasonBlock, serialBlock)});
|
||||
var liTag = $('<li/>')
|
||||
var liTag = $('<li/>');
|
||||
liTag.append(aTag);
|
||||
menu.append(liTag);
|
||||
});
|
||||
|
||||
seasonBlock.removeClass('hide');
|
||||
}
|
||||
};
|
||||
|
||||
this.setupPlayer = function() {
|
||||
var _self = this;
|
||||
@@ -90,17 +88,17 @@ function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
||||
console.debug({'path': _self.path, 'saveTime': save_data});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.setSerial = function(idx, serialBlock, sidx = 0) {
|
||||
var title;
|
||||
var playerSrc;
|
||||
if (this.getType() == 'seasons_serial') {
|
||||
title = videoData.seasons[sidx].serials[idx].title;
|
||||
playerSrc = this.baseDir + videoData.seasons[sidx].serials[idx].file;
|
||||
playerSrc = videoData.seasons[sidx].serials[idx].file;
|
||||
} else {
|
||||
title = videoData.serials[idx].title;
|
||||
playerSrc = this.baseDir + videoData.serials[idx].file;
|
||||
playerSrc = videoData.serials[idx].file;
|
||||
}
|
||||
this.setTitle(title);
|
||||
|
||||
@@ -110,7 +108,7 @@ function PlayerCore(baseDir, playerObj, titleObj, videoData) {
|
||||
playerObj.attr('src', playerSrc);
|
||||
playerObj.attr('data-serial', idx);
|
||||
playerObj.load();
|
||||
}
|
||||
};
|
||||
|
||||
this.setSeason = function(idx, seasonBlock, serialBlock) {
|
||||
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) {
|
||||
var aTag = $('<a/>', {'href':'#', 'text':item.title});
|
||||
aTag.click(function(){_self.setSerial(i, serialBlock, idx)});
|
||||
var liTag = $('<li/>')
|
||||
var liTag = $('<li/>');
|
||||
liTag.append(aTag);
|
||||
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