diff --git a/src/main/java/kinosearch/core/KinoItem.java b/src/main/java/kinosearch/core/KinoItem.java new file mode 100644 index 0000000..0faa210 --- /dev/null +++ b/src/main/java/kinosearch/core/KinoItem.java @@ -0,0 +1,31 @@ +/* + * DmitriyMX + * 2017-01-05 + */ +package kinosearch.core; + +public class KinoItem { + private String title; + private String fileMp4; + + public KinoItem(String title, String file) { + this.title = title; + this.fileMp4 = file; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getFile() { + return fileMp4; + } + + public void setFile(String fileMp4) { + this.fileMp4 = fileMp4; + } +} diff --git a/src/main/java/kinosearch/core/KinoPlay.java b/src/main/java/kinosearch/core/KinoPlay.java new file mode 100644 index 0000000..f45bdc4 --- /dev/null +++ b/src/main/java/kinosearch/core/KinoPlay.java @@ -0,0 +1,60 @@ +/* + * DmitriyMX + * 2017-01-05 + */ +package kinosearch.core; + +import java.util.ArrayList; +import java.util.Map; + +public class KinoPlay { + private String title; + private KinoType type = KinoType.UNKNOW; + private KinoItem oneFilm; + private ArrayList serials; + private Map> seasons; + + public enum KinoType { + UNKNOW, ONE_FILM, SIMPLE_SERIAL, SEASONS_SERIAL + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public KinoType getType() { + return type; + } + + public void setType(KinoType type) { + this.type = type; + } + + public KinoItem getOneFilm() { + return oneFilm; + } + + public void setOneFilm(KinoItem oneFilm) { + this.oneFilm = oneFilm; + } + + public ArrayList getSerials() { + return serials; + } + + public void setSerials(ArrayList serials) { + this.serials = serials; + } + + public Map> getSeasons() { + return seasons; + } + + public void setSeasons(Map> seasons) { + this.seasons = seasons; + } +} diff --git a/src/main/java/kinosearch/core/SpringConfig.java b/src/main/java/kinosearch/core/SpringConfig.java index 8c5c5dd..598e950 100644 --- a/src/main/java/kinosearch/core/SpringConfig.java +++ b/src/main/java/kinosearch/core/SpringConfig.java @@ -4,8 +4,11 @@ */ package kinosearch.core; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import kinosearch.core.browser.ApacheHttpBrowser; import kinosearch.core.browser.Browser; +import kinosearch.webapp.KinoPlaySerializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -19,4 +22,10 @@ public class SpringConfig { public Browser browser() { return new ApacheHttpBrowser(); } + + @Bean + @Scope("singleton") + public Gson gson() { + return new GsonBuilder().registerTypeAdapter(KinoPlay.class, new KinoPlaySerializer()).create(); + } } diff --git a/src/main/java/kinosearch/core/warez/KinoWarez.java b/src/main/java/kinosearch/core/warez/KinoWarez.java index e36a3fd..ebcfea6 100644 --- a/src/main/java/kinosearch/core/warez/KinoWarez.java +++ b/src/main/java/kinosearch/core/warez/KinoWarez.java @@ -1,12 +1,13 @@ package kinosearch.core.warez; import kinosearch.core.Kino; +import kinosearch.core.KinoPlay; import java.util.List; public interface KinoWarez { String getName(); List search(String nameKino, boolean strong); - String player(String page); + KinoPlay player(String page); String getDomain(); } diff --git a/src/main/java/kinosearch/core/warez/Onlinelife.java b/src/main/java/kinosearch/core/warez/Onlinelife.java index c322f41..1f3d256 100644 --- a/src/main/java/kinosearch/core/warez/Onlinelife.java +++ b/src/main/java/kinosearch/core/warez/Onlinelife.java @@ -5,6 +5,8 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import kinosearch.core.Kino; +import kinosearch.core.KinoItem; +import kinosearch.core.KinoPlay; import kinosearch.core.Tools; import kinosearch.core.browser.Browser; import org.jsoup.Jsoup; @@ -14,9 +16,7 @@ import org.jsoup.select.Elements; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -26,6 +26,8 @@ public class Onlinelife implements KinoWarez { private static final String NAME = "OnlineLife"; @Autowired private Browser browser; + @Autowired + private Gson gson; @Override public String getName() { @@ -80,26 +82,76 @@ public class Onlinelife implements KinoWarez { } @Override - public String player(String page) { + public KinoPlay player(String page) { + // получаем id фильма String movie_id = page.substring(1,page.indexOf("-")); + // делаем запрос на получение json данных browser.setEncoding("windows-1251"); browser.setHeader("Referer", "http://dterod.com/player.php?newsid=" + movie_id); String html = browser.get("http://dterod.com/js.php?id=" + movie_id); html = html.substring(0, html.indexOf('\n')).trim(); String json = html.substring(html.indexOf('{'), html.indexOf("};")+1); - JsonObject jsonObj = new Gson().fromJson(json, JsonObject.class); + JsonObject jsonObj = gson.fromJson(json, JsonObject.class); + // формируем результат + KinoPlay kinoPlay = new KinoPlay(); if (jsonObj.has("file")) { - String fileMp4 = jsonObj.get("file").getAsString().substring("http://".length()); + // одиночный фильм + kinoPlay.setType(KinoPlay.KinoType.ONE_FILM); + String title = jsonObj.get("comment").getAsString(); - return "{\"file\":\"/proxy/onlinelife/" + fileMp4 + "\",\"title\":\"" + title + "\"}"; + kinoPlay.setTitle(title); + kinoPlay.setOneFilm(new KinoItem( + title, + "/proxy/onlinelife/" + jsonObj.get("file").getAsString().substring("http://".length()) + )); } else if (jsonObj.has("pl")) { browser.setEncoding("utf-8"); - return replaceToProxy(browser.get(jsonObj.get("pl").getAsString())); - } else { - return "{}"; + json = browser.get(jsonObj.get("pl").getAsString()); + jsonObj = gson.fromJson(json, JsonObject.class); + JsonArray jsonArray = jsonObj.get("playlist").getAsJsonArray(); + + JsonObject jsonTestObj = jsonArray.get(0).getAsJsonObject(); + if (jsonTestObj.has("playlist")) { + // сезонный сериал + kinoPlay.setType(KinoPlay.KinoType.SEASONS_SERIAL); + + Map> seasons = new HashMap<>(); + for (JsonElement element : jsonArray) { + jsonObj = element.getAsJsonObject(); + String titleSeason = jsonObj.get("comment").getAsString(); + + ArrayList serials = new ArrayList<>(); + JsonArray jsonSerials = jsonObj.get("playlist").getAsJsonArray(); + for (JsonElement elm1 : jsonSerials) { + jsonObj = elm1.getAsJsonObject(); + serials.add(new KinoItem( + jsonObj.get("comment").getAsString(), + jsonObj.get("file").getAsString().replace("http://", "/proxy/onlinelife/") + )); + } + + seasons.put(titleSeason, serials); + } + + kinoPlay.setSeasons(seasons); + } else { + // простой сериал + kinoPlay.setType(KinoPlay.KinoType.SIMPLE_SERIAL); + + ArrayList serials = new ArrayList<>(); + for (JsonElement element : jsonArray) { + jsonObj = element.getAsJsonObject(); + serials.add(new KinoItem( + jsonObj.get("comment").getAsString(), + jsonObj.get("file").getAsString().replace("http://", "/proxy/onlinelife/") + )); + } + kinoPlay.setSerials(serials); + } } + return kinoPlay; } private String replaceToProxy(String json) { diff --git a/src/main/java/kinosearch/webapp/KinoPlaySerializer.java b/src/main/java/kinosearch/webapp/KinoPlaySerializer.java new file mode 100644 index 0000000..509c142 --- /dev/null +++ b/src/main/java/kinosearch/webapp/KinoPlaySerializer.java @@ -0,0 +1,92 @@ +/* + * DmitriyMX + * 2017-01-05 + */ +package kinosearch.webapp; + +import com.google.gson.*; +import kinosearch.core.KinoItem; +import kinosearch.core.KinoPlay; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Map; + +public class KinoPlaySerializer implements JsonSerializer { + @Override + public JsonElement serialize(KinoPlay kinoPlay, Type type, JsonSerializationContext jsonSerializationContext) { + JsonObject outJson = new JsonObject(); + + outJson.addProperty("title", kinoPlay.getTitle()); + outJson.addProperty("type", kinoPlay.getType().name().toLowerCase()); + + if (kinoPlay.getType().equals(KinoPlay.KinoType.ONE_FILM)) { + outJson.addProperty("file", kinoPlay.getOneFilm().getFile()); + } else if (kinoPlay.getType().equals(KinoPlay.KinoType.SIMPLE_SERIAL)) { + JsonArray jsonArray = new JsonArray(); + for (KinoItem kinoItem : kinoPlay.getSerials()) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("title", kinoItem.getTitle()); + jsonObject.addProperty("file", kinoItem.getFile()); + jsonArray.add(jsonObject); + } + outJson.add("serials", jsonArray); + } else if (kinoPlay.getType().equals(KinoPlay.KinoType.SEASONS_SERIAL)) { + /* + { + title: 'Title', + type: 'seasons', + seasons: [ + { + title: 'seasonName' + serials: [ + { + title: 'title', + file: 'fileMp4' + }, + { + title: 'title', + file: 'fileMp4' + } + ] + }, + { + title: 'seasonName' + serials: [ + { + title: 'title', + file: 'fileMp4' + }, + { + title: 'title', + file: 'fileMp4' + } + ] + } + ] + } + */ + JsonArray jsonSeasons = new JsonArray(); + + for (Map.Entry> entry : kinoPlay.getSeasons().entrySet()) { + JsonObject jsonSeason = new JsonObject(); + jsonSeason.addProperty("title", entry.getKey()); + + JsonArray jsonSerials = new JsonArray(); + for (KinoItem kinoItem : entry.getValue()) { + JsonObject jsonItem = new JsonObject(); + jsonItem.addProperty("title", kinoItem.getTitle()); + jsonItem.addProperty("file", kinoItem.getFile()); + jsonSerials.add(jsonItem); + } + jsonSeason.add("serials", jsonSerials); + + jsonSeasons.add(jsonSeason); + } + + outJson.add("seasons", jsonSeasons); + } + + return outJson; + } +} diff --git a/src/main/java/kinosearch/webapp/WebAppConfiguration.java b/src/main/java/kinosearch/webapp/WebAppConfiguration.java index d761ac0..77dd977 100644 --- a/src/main/java/kinosearch/webapp/WebAppConfiguration.java +++ b/src/main/java/kinosearch/webapp/WebAppConfiguration.java @@ -4,11 +4,11 @@ */ 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.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; +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; @@ -36,6 +36,12 @@ public class WebAppConfiguration extends WebMvcConfigurerAdapter { 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/**") diff --git a/src/main/java/kinosearch/webapp/WebAppController.java b/src/main/java/kinosearch/webapp/WebAppController.java index d0923a4..75e9511 100644 --- a/src/main/java/kinosearch/webapp/WebAppController.java +++ b/src/main/java/kinosearch/webapp/WebAppController.java @@ -4,7 +4,9 @@ */ package kinosearch.webapp; +import com.google.gson.Gson; import kinosearch.core.Kino; +import kinosearch.core.KinoPlay; import kinosearch.core.Tools; import kinosearch.core.warez.KinoWarez; import org.springframework.beans.factory.annotation.Autowired; @@ -152,8 +154,9 @@ public class WebAppController { if (kinoWarez == null) { return "redirect:/"; } - String json = kinoWarez.player(request.getServletPath().substring(("/player/"+warez).length())); - model.put("json", json); + KinoPlay kinoPlay = kinoWarez.player(request.getServletPath().substring(("/player/"+warez).length())); + Gson gson = coreContext.getBean(Gson.class); + model.put("json", gson.toJson(kinoPlay)); return "player"; } @@ -177,7 +180,7 @@ public class WebAppController { con.connect(); - int statusCode = con.getResponseCode(); + int statusCode = con.getResponseCode(); //FIXME bug #20 response.setStatus(statusCode); for (Map.Entry> stringListEntry : con.getHeaderFields().entrySet()) { diff --git a/src/main/webapp/WEB-INF/player.html b/src/main/webapp/WEB-INF/player.html index f0dc8c3..25d3b20 100644 --- a/src/main/webapp/WEB-INF/player.html +++ b/src/main/webapp/WEB-INF/player.html @@ -1,137 +1,64 @@ <#include "/header.inc.html"> + @@ -144,13 +71,13 @@ diff --git a/src/main/webapp/js/player.js b/src/main/webapp/js/player.js new file mode 100644 index 0000000..97a3abf --- /dev/null +++ b/src/main/webapp/js/player.js @@ -0,0 +1,134 @@ +function PlayerCore(baseDir, playerObj, titleObj, videoData) { + this.baseDir = baseDir; + 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) { + function addZ(n) { return (n<10? '0':'') + n; } + + var _ms = ms % 1000; + ms = (ms - _ms) / 1000; + var _sec = ms % 60; + ms = (ms - _sec) / 60; + var _min = ms % 60; + var _hr = (ms - _min) / 60; + + return { + 's': addZ(_sec), + '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.load(); + } + + this.setupPlayerForSimpleSerial = function(serialBlock) { + var menu = serialBlock.find('.dropdown-menu'); + menu.html(''); + var _self = this; + this.videoData.serials.forEach(function(item, i) { + var aTag = $('', {'href':'#', 'text':item.title}); + aTag.click(function(){_self.setSerial(i, serialBlock)}); + var liTag = $('
  • ') + liTag.append(aTag); + menu.append(liTag); + }); + + serialBlock.removeClass('hide'); + } + + this.setupPlayerForSeasonSerial = function(seasonBlock, serialBlock) { + var menu = seasonBlock.find('.dropdown-menu'); + menu.html(''); + var _self = this; + this.videoData.seasons.forEach(function(item, i) { + var aTag = $('', {'href':'#', 'text':item.title}); + aTag.click(function(){_self.setSeason(i, seasonBlock, serialBlock)}); + var liTag = $('
  • ') + liTag.append(aTag); + menu.append(liTag); + }); + + seasonBlock.removeClass('hide'); + } + + this.setupPlayer = function() { + var _self = this; + // сохранение времени просмотра + playerObj.bind('play', function(){ + _self.timeLast = $.now(); + }); + + playerObj.bind('timeupdate', function(){ + var timeCurrent = $.now(); + var sec = Math.floor((timeCurrent - _self.timeLast)/1000); + if (sec >= 5) { + playerCurrentTime = playerObj[0].currentTime; + if (Math.floor(playerCurrentTime) <= 10) return; + + var save_data = {'time':playerCurrentTime}; + Cookies.set(_self.path, save_data, {'expires':30}); + _self.timeLast = timeCurrent; + 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; + } else { + title = videoData.serials[idx].title; + playerSrc = this.baseDir + videoData.serials[idx].file; + } + this.setTitle(title); + + var menuBtn = serialBlock.find('#dropdownSerial'); + menuBtn.html(title + ' '); + + playerObj.attr('src', playerSrc); + playerObj.attr('data-serial', idx); + playerObj.load(); + } + + this.setSeason = function(idx, seasonBlock, serialBlock) { + var title = videoData.seasons[idx].title; + + var menuBtn = seasonBlock.find('#dropdownSeason'); + menuBtn.html(title + ' '); + + var menu = serialBlock.find('.dropdown-menu'); + menu.html(''); + var _self = this; + this.videoData.seasons[idx].serials.forEach(function(item, i) { + var aTag = $('', {'href':'#', 'text':item.title}); + aTag.click(function(){_self.setSerial(i, serialBlock, idx)}); + var liTag = $('
  • ') + liTag.append(aTag); + menu.append(liTag); + }); + + serialBlock.removeClass('hide'); + } +} \ No newline at end of file