package addon.movie; import bashoid.Addon; import bashoid.Message; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import utils.WebPage; public class Movie extends Addon { private static final String ENCODING = "UTF-8"; private static final String REACT_MESSAGE = "movie "; private static final String ID_PREFIX = "/film/"; private int reactionId = 0; private static class MovieException extends Exception { static final long serialVersionUID = 1L; public MovieException(String message) { super(message); } } class MovieData { String title; String link_csfd; String link_imdb; String country; String year; String length; String director; String genre; String rating_csfd; String rating_imdb; /*public void print() { System.out.print("Title: " + title + "\n" + "Link_csfd: " + link_csfd + "\n" + "Link_imdb: " + link_imdb + "\n" + "Country: " + country + "\n" + "Year: " + year + "\n" + "Length: " + length + "\n" + "Director: " + director + "\n" + "Genre: " + genre + "\n" + "Rating_csfd: " + rating_csfd + "\n" + "Rating_imdb: " + rating_imdb + "\n"); }*/ @Override public String toString() { // Prometheus (2012), USA, 124 min, csfd: 70%, imdb: 7.5, http://csfd.cz/film/290958 String result = title + " "; if (year != null) result += "(" + year + ")"; result += ", "; if (country != null) result += country + ", "; if (length != null) result += length + ", "; if (rating_csfd != null || rating_imdb != null) { result += "Rating: "; if (rating_csfd != null) result += rating_csfd + " (csfd.cz), "; if (rating_imdb != null) result += rating_imdb + " (imdb.com), "; } result += link_csfd; return result; } } private String SearchMovieData(String movieSearch) throws Exception { String link = GetMovieLink(movieSearch); return GetMovieData(link); } private String GetMovieData(String link) throws Exception { MovieData data = new MovieData(); data.link_csfd = link; LoadMovieData(data); if (data.link_imdb != null) LoadImdbData(data); return data.toString(); } private String GetMovieLink(String movieSearch) throws Exception { movieSearch = movieSearch.replaceAll(" ", "+"); String url = "http://www.csfd.cz/hledat/?q=" + movieSearch; WebPage page = WebPage.loadWebPage(url, ENCODING); Document doc = Jsoup.parse( page.getContent() ); String bodyId = doc.body().attr("id"); if (!bodyId.equals("ap-web-search")) throw new MovieException("Movie '" + movieSearch + "' not found"); Element movies = doc.getElementById("search-films"); if (!movies.getElementsByClass("not-found").isEmpty()) throw new MovieException("Movie '" + movieSearch + "' not found"); Element firstMovie = movies.getElementsByClass("subject").first(); Element movieLink = firstMovie.getElementsByTag("a").first(); String partialLink = movieLink.attr("href"); return GenerateCsfdMovieLink(partialLink); } private String ExtractIdFromLink(String partialLink) { int beginIdx = partialLink.indexOf(ID_PREFIX)+ID_PREFIX.length(); int endIdx = partialLink.indexOf("-", beginIdx); String id = endIdx != -1 ? partialLink.substring(beginIdx, endIdx) : partialLink.substring(beginIdx); return id; } private String GenerateCsfdMovieLink(String partialLink) { String id = ExtractIdFromLink(partialLink); return "http://csfd.cz/film/" + id; } private void LoadMovieData(MovieData data) throws Exception { WebPage page = WebPage.loadWebPage(data.link_csfd, ENCODING); Element movieInfo = Jsoup.parse( page.getContent() ).getElementById("profile"); { Element title = movieInfo.getElementsByTag("h1").first(); data.title = title.text().trim(); Elements genres = movieInfo.getElementsByClass("genre"); if (!genres.isEmpty()) data.genre = genres.first().text().trim(); Element origin = movieInfo.getElementsByClass("origin").first(); String[] originParts = origin.text().split(","); if (originParts.length > 0) data.country = originParts[0].trim(); if (originParts.length > 1) data.year = originParts[1].trim(); if (originParts.length > 2) data.length = originParts[2].trim(); Elements otherData = movieInfo.getElementsByTag("h4"); for (Element ele : otherData) { if (ele.text().equals("Režie:")) { Element directorLink = ele.parent().getElementsByTag("a").first(); data.director = directorLink.text(); break; } } } Element sidebar = Jsoup.parse( page.getContent() ).getElementById("sidebar"); { Element rating = sidebar.getElementById("rating"); Element average = rating.getElementsByClass("average").first(); if (!average.text().isEmpty()) data.rating_csfd = average.text().trim(); Element share = sidebar.getElementById("share"); Element links = share.getElementsByClass("links").first(); Elements imdbs = links.getElementsByClass("imdb"); if (!imdbs.isEmpty()) { Element childImdb = imdbs.first(); Element imdb = childImdb.parent(); data.link_imdb = imdb.attr("href"); } } } private void LoadImdbData(MovieData data) throws Exception { WebPage page = WebPage.loadWebPage(data.link_imdb, ENCODING); Elements sidebarList = Jsoup.parse( page.getContent() ).getElementsByClass("star-box-giga-star"); if (sidebarList.isEmpty()) return; Element sidebar = sidebarList.first(); data.rating_imdb = sidebar.text().trim(); } @Override public boolean shouldReact(Message message) { String messageText = message.text.trim(); if (messageText.startsWith("movie") || messageText.startsWith("movies") || messageText.startsWith("vycsfdkuj") || messageText.startsWith("vyfilmuj")) { reactionId = 1; return true; } if (messageText.startsWith("http://www.csfd.cz/film") || messageText.startsWith("http://csfd.cz/film")) { reactionId = 2; return true; } reactionId = 0; return false; } @Override protected void setReaction(Message message) { try { String result; String messageText = message.text.trim(); switch(reactionId) { case 1: { String movieSearch = messageText.substring(messageText.indexOf(" ") +1); result = SearchMovieData(movieSearch); break; } case 2: { String csfdLink = GenerateCsfdMovieLink(messageText); result = GetMovieData(csfdLink); break; } default: return; } reaction.add( result ); } catch (Exception e) { if (e instanceof MovieException) { reaction.add( e.getMessage() ); } else { System.out.println(e); if (message.text.startsWith(REACT_MESSAGE)) setError("Cannot load given URL.", e); } } } }