Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package emma; import com.omertron.themoviedbapi.enumeration.ExternalSource; import com.omertron.themoviedbapi.methods.TmdbFind; import com.omertron.themoviedbapi.model.FindResults; import com.omertron.themoviedbapi.tools.HttpTools; import com.sun.javafx.iio.ImageFrame; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import edu.cmu.sphinx.api.LiveSpeechRecognizer; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.math.BigInteger; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.URL; import java.nio.file.DirectoryStream; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Scanner; import java.util.concurrent.Executors; import javax.imageio.ImageIO; import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.yamj.api.common.http.SimpleHttpClientBuilder; /** * * @author tdn */ public class Emma { static boolean debug = true; public static void debug(String s) { if (debug) { System.out.println(s); } } public static void error(String s) { if (debug) { System.err.println(s); } } /** * * HTTP * */ static class Http { public Http() { } static public int get(String url, StringBuilder response, String auth) { System.out.println("get->" + url); if (auth == null) { } try { HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection(); con.setRequestMethod("GET"); con.setRequestProperty("User-Agent", "Mozilla/5.0"); con.setRequestProperty("Authorization", "Basic " + auth); con.setInstanceFollowRedirects(false); BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; int code = con.getResponseCode(); // directly found and redirected by "Location" header if (code == 302) { // redirected String location = con.getHeaderField("Location"); if (location.length() > 0) { String s = "?fr="; int idx = location.indexOf(s); if (idx > -1) { location = location.substring(0, idx); } get(location, response, null); return code; } } while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); return code; } catch (Exception e) { System.err.println(e.toString()); } return 404; } } public static String getPath(String p) { String OS = System.getProperty("os.name").toLowerCase(); if ((OS.contains("win"))) { //p = p.replace("\\", "\\\\"); } return p; } /** * * * IMDB * */ static class MetaInfo { public MetaInfo() { } public static String getURL(String hash) { return Memory.select("url", "entries", "hash = '" + hash + "'").get(0); } public static String getAlt(String hash) { return Memory.select("alt", "entries", "hash = '" + hash + "'").get(0); } private static void readImg(String c, String hash) { // c = alt int idx; String s = "IMDb</title>"; String s_html = c; int code = 0; StringBuilder r = new StringBuilder(2048); // return if exists File outputfile = new File("www/images/work/" + hash + ".jpg"); if (!outputfile.exists()) { // IMDB // <img alt="TRON: Legacy (2010) Poster" title="TRON: Legacy (2010) Poster" src="http://ia.media-imdb.com/images/M/MV5BMTk4NTk4MTk1OF5BMl5BanBnXkFtZTcwNTE2MDIwNA@@._V1_SX214_AL_.jpg" itemprop="image" height="317" width="214"> idx = s_html.indexOf(s); if (idx > -1) { s = "itemprop=\"image"; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx - 250, idx + 250); s = "src=\""; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length()); s = "\""; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(0, idx); code = Http.get(s_html, r, null); if (code == 404) { System.err.println(hash + ".jpg"); } try { BufferedImage img = ImageIO.read(new URL(s_html)); ImageIO.write(img, "jpg", outputfile); } catch (Exception e) { System.err.println(e.toString()); } } } } } else { // TheMovieDB s = "id=\"upload_poster\""; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length()); s = "src=\""; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length()); s = "\""; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(0, idx); code = Http.get(s_html, r, null); if (code == 404) { System.err.println(hash + ".jpg"); } try { BufferedImage img = ImageIO.read(new URL(c)); ImageIO.write(img, "jpg", outputfile); } catch (Exception e) { System.err.println(e.toString()); } } } } } } // big one s_html = c; outputfile = new File("www/images/work/_" + hash + ".jpg"); if (!outputfile.exists()) { // IMDB s = "<a href=\"/media/"; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx); s = "\""; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length()); s = "\""; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(0, idx); Http.get("http://www.imdb.com" + s_html, r, null); s_html = r.toString(); s = "<div class=\"photo\">"; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length()); s = "src=\""; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length()); s = "\""; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(0, idx); try { BufferedImage img = ImageIO.read(new URL(s_html)); ImageIO.write(img, "jpg", outputfile); } catch (Exception e) { System.err.println(e.toString()); } } } } } } } else { // TheMovieDB } } } private static void downloadMetaData(String name, String hash) { try { if (name.length() == 0) return; // IMDB //String url = "http://www.imdb.com/xml/find?json=1&q=" + URLEncoder.encode(name, "ISO-8859-1"); String url = "http://www.imdb.com/xml/find?json=1&q=" + name.replace(" ", "+").replace("&", "%26").replace("", "%DF"); boolean found = false, exit = false; // work files File html = new File(getPath("work/" + hash + ".html")); // if name is url, imdb url already known if (name.startsWith("http:")) { /* // only write correct imdb title page FileUtils.writeStringToFile(html, r.toString()); // read img from title page readImg(r.toString(), hash); */ StringBuilder r = new StringBuilder(8192); int code = Http.get(name, r, null); if (html.exists()) { html.delete(); } File image = new File("www/images/work/" + hash + ".jpg"); if (image.exists()) { image.delete(); } image = new File("www/images/work/_" + hash + ".jpg"); if (image.exists()) { image.delete(); } FileUtils.writeStringToFile(html, r.toString()); readImg(r.toString(), hash); return; } // exit after title found if (html.exists()) { return; } String s = ""; int tr_idx = -1, idx = -1, tmp_idx = -1; // http request StringBuilder r = new StringBuilder(8192); int code = Http.get(url, r, null); // build local imdb String s_html = r.toString(); if (code == 200) { // ok will response json // --> try to get title // try search and parse first output line r = new StringBuilder(8192); //url = "http://www.imdb.com/find?ref_=nv_sr_fn&q=" + URLEncoder.encode(name, "ISO-8859-1") + "&s=all"; url = "http://www.imdb.com/find?ref_=nv_sr_fn&q=" + name.replace(" ", "+").replace("&", "%26") + "&s=all"; code = Http.get(url, r, null); // ok will response html if (code == 200) { s_html = r.toString(); String response = s_html; // reading in loop -> every <tr while (found == false && exit == false) { s = "<tr class=\"findResult"; idx = s_html.indexOf(s); tr_idx = idx; if (idx > -1) { s_html = s_html.substring(idx + s.length()); s = "</tr>"; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(0, idx); s = "<a href=\""; idx = s_html.indexOf(s); if (idx > -1) { // /tt... s_html = s_html.substring(idx + s.length(), s_html.length()); tmp_idx = s_html.indexOf("><img") - 2; if (tmp_idx > -1) { String title_url = s_html.substring(0, tmp_idx); s = "<a href="; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length(), s_html.length()); s = ">"; idx = s_html.indexOf(s); if (idx > -1) { tmp_idx = s_html.indexOf("</td>"); if (tmp_idx > -1) { String title = s_html.substring(idx + s.length(), tmp_idx) .trim().replace("</a>", ""); int lfd = org.apache.commons.lang3.StringUtils .getLevenshteinDistance(name, title); double ratio = ((double) lfd) / (Math.max(name.length(), title.length())); // levenshtein = 0.5 = 50% // levenshtein = 0.0 = 100% if (ratio <= 0.4) { r = new StringBuilder(8192); //url = "http://www.imdb.com" + URLEncoder.encode(title_url, "ISO-8859-1") + "/?ref_=fn_al_tt_1"; url = "http://www.imdb.com" + title_url.replace("&", "%26") + "/?ref_=fn_al_tt_1"; code = Http.get(url, r, null); debug("has: " + hash + ">>" + url + ">>" + name); if (code == 200) { // ok will response html // write .html if (!html.exists()) { // only write correct imdb title page FileUtils.writeStringToFile(html, r.toString()); // read img from title page readImg(r.toString(), hash); return; } } else { // WHATS UP HERE??? System.err.println("404-2>>>" + hash + ">>" + url + ">>" + name); } } else { // try other name if (title.startsWith( name.substring(0, name.lastIndexOf("("))) && title.contains( name.substring(name.lastIndexOf("("), name.lastIndexOf(")") + 1))) { r = new StringBuilder(8192); //url = "http://www.imdb.com" + URLEncoder.encode(title_url, "ISO-8859-1") + "/?ref_=fn_al_tt_1"; url = "http://www.imdb.com" + title_url.replace("&", "%26") + "/?ref_=fn_al_tt_1"; code = Http.get(url, r, null); debug("has: " + hash + ">>" + url + ">>" + name); if (code == 200) { // ok will response html // write .html if (!html.exists()) { // only write correct imdb title page FileUtils.writeStringToFile(html, r.toString()); // read img from title page readImg(r.toString(), hash); return; } } } } } else { } } else { } } else { } } else { } } else { } } else { } response = response.substring(tr_idx + s.length()); s_html = response; } else { exit = true; } } if (!found) { // TheMovieDB exit = false; // for the loop r = new StringBuilder(8192); // https://www.themoviedb.org/search?query=dark+knight s = " ("; idx = name.lastIndexOf(s); String tmp_name = name, s_name = name; if (idx > -1) { tmp_name = name.substring(0, idx); } int i = 0; while (!found) { if (i == 0) { url = "https://www.themoviedb.org/search?query=" + tmp_name.replace("&", "%26").replace(" ", "%20") + "&language=de"; } else { url = "https://www.themoviedb.org/search?query=" + name.replace("&", "%26").replace(" ", "%20") + "&language=de"; } code = Http.get(url, r, null); if (code == 200) { s_html = r.toString(); s = "<ul class=\"search_results movie\">"; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length()); while (!found && !exit) { s = "<li>"; idx = s_html.indexOf(s); tr_idx = idx; if (idx > -1) { s_html = s_html.substring(idx + s.length()); s = "<div class=\"info\">"; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length()); s = "<a"; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length()); // href="/movie/218-the-terminator" String title_url = s_html.substring(idx + s.length()); s = "href=\""; idx = title_url.indexOf(s); if (idx > -1) { title_url = title_url.substring(idx + s.length()); s = "\""; idx = title_url.indexOf(s); if (idx > -1) { title_url = title_url.substring(0, idx); } } s = ">"; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length()); s = "</span>"; idx = s_html.indexOf(s); if (idx > -1) { String title = s_html.substring(0, idx); title = title.replace("</a>", "").replace("<span>", ""); int lfd = org.apache.commons.lang3.StringUtils .getLevenshteinDistance(name, title); double ratio = ((double) lfd) / (Math.max(name.length(), title.length())); // levenshtein = 0.5 = 50% // levenshtein = 0.0 = 100% if (ratio <= 0.4) { // https://www.themoviedb.org/movie/155-the-dark-knight url = "https://www.themoviedb.org" + title_url + "?language=de"; r = new StringBuilder(8192); code = Http.get(url, r, null); if (code == 200) { if (!html.exists()) { System.err.println(">>>" + hash); FileUtils.writeStringToFile(html, r.toString()); // read img from title page readImg(r.toString(), hash); return; } } } else { } } } } } } else { exit = true; } } exit = false; } else { s = "<h3>"; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length()); s = "href=\""; idx = s_html.indexOf(s); if (idx > -1) { String title_url = s_html = s_html.substring(idx + s.length()); s = "\""; idx = title_url.indexOf(s); if (idx > -1) { title_url = title_url.substring(0, idx); s = ">"; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(idx + s.length()); s = "<"; idx = s_html.indexOf(s); if (idx > -1) { s_html = s_html.substring(0, idx); int lfd = org.apache.commons.lang3.StringUtils .getLevenshteinDistance(name, s_html); double ratio = ((double) lfd) / (Math.max(name.length(), s_html.length())); // levenshtein = 0.5 = 50% // levenshtein = 0.0 = 100% if (ratio <= 0.4) { // https://www.themoviedb.org/movie/155-the-dark-knight url = "https://www.themoviedb.org" + title_url + "?language=de"; r = new StringBuilder(8192); code = Http.get(url, r, null); if (code == 200) { if (!html.exists()) { FileUtils.writeStringToFile(html, r.toString()); // read img from title page readImg(r.toString(), hash); return; } } } else { } } } } } } } } if (i < 3) { // i < size of fiter (tokenizers) if (i == 0) { name = s_name.replaceAll("(?i)der ", "").replaceAll("(?i)die ", "") .replaceAll("(?i)das ", "").replaceAll("(?i)the ", ""); s = " ("; idx = name.lastIndexOf(s); if (idx > -1) { name = name.substring(0, idx); } } if (i == 1) { name = s_name; } if (i == 2) { name = s_name; s = " ("; idx = name.lastIndexOf(s); if (idx > -1) { name = name.substring(0, idx); } name = name.replace(" I", ""); name = name.replace(" II", ""); name = name.replace(" III", ""); name = name.replace(" IV", ""); name = name.replace(" V", ""); name = name.replace(" VI", ""); name = name.replace(" VII", ""); name = name.replace(" VIII", ""); name = name.replace(" IX", ""); name = name.replace(" X", ""); } i++; } else { found = true; // fake-found -- nothing here :( i = 0; } } } } else { System.err.println(">" + code + ">>>" + hash + ">>" + url + ">>" + name); } } // redirected will response title-page if (code == 302) { // write .html if (!html.exists()) { // read img from title page readImg(r.toString(), hash); FileUtils.writeStringToFile(html, r.toString()); return; } } // create fake html if (!html.exists()) { // System.err.println(html.getCanonicalPath()); FileUtils.writeStringToFile(html, hash); } } catch (Exception e) { System.err.println(e.toString()); } } // reads content from file[hash] // and // updates alt, title-url, cast private static void readMetaData(String hash) { String content = "", alt, title_url, img = "", cast = "", actors = "", desc = ""; try { File html = new File(getPath("work/" + hash + ".html")); if (html.exists()) { BufferedReader reader = new BufferedReader(new FileReader(html)); String line; while ((line = reader.readLine()) != null) { content += line; } //FileUtils.readFileToString(html, content); // imdb int idx; String s; s = "IMDb</title>"; idx = content.indexOf(s); if (idx > -1) { s = "<span class=\"title-extra\" itemprop=\"name\">"; idx = content.indexOf(s); if (idx > -1) { idx = idx + s.length(); alt = content.substring(idx, idx + 1000); alt = alt.substring(0, alt.indexOf("<i>")).trim(); alt = alt.substring(1, alt.length() - 1); } else { s = "<span class=\"itemprop\" itemprop=\"name\">"; idx = content.indexOf(s); if (idx > -1) { idx = idx + s.length(); alt = content.substring(idx, idx + 1000); alt = alt.substring(0, alt.indexOf("</span>")); } else { alt = ""; } } // insert alt name alt = alt.replace("'", ""); // no ' needed... Memory.update("entries", "alt", alt, "hash = '" + hash + "'"); // read title-url // <link rel="canonical" href="http://www.imdb.com/title/tt0331811/" /> s = "<link rel=\"canonical\" href=\""; idx = content.indexOf(s); if (idx > -1) { title_url = content.substring(idx + s.length()); s = "/\" />"; idx = title_url.indexOf(s); if (idx > -1) { title_url = title_url.substring(0, idx); // insert alt name title_url = title_url.replace("'", ""); // no ' needed... Memory.update("entries", "url", title_url, "hash = '" + hash + "'"); } } // read cast s = "<table class=\"cast_list\">"; idx = content.indexOf(s); if (idx > -1) { cast = content.substring(idx + s.length()); s = "</table>"; idx = cast.indexOf(s); if (idx > -1) { cast = cast.substring(0, idx); s = "title=\""; idx = cast.indexOf(s); while (idx > -1) { cast = cast.substring(idx + s.length()); actors += cast.substring(0, cast.indexOf("\"")); actors += ", "; s = "title=\""; idx = cast.indexOf(s); } if (actors.length() > 2) { actors = actors.substring(0, actors.length() - 2); Memory.update("entries", "actors", actors.replace("'", ""), "hash = '" + hash + "'"); } } } // read desc s = "<p itemprop=\"description\">"; idx = content.indexOf(s); if (idx > -1) { desc = content.substring(idx + s.length()); s = "</p>"; idx = desc.indexOf(s); if (idx > -1) { desc = desc.substring(0, idx); if (desc.length() > 2) { Memory.update("entries", "desc", desc.replace("'", ""), "hash = '" + hash + "'"); return; } } } /* s = "<div class=\"inline canwrap\" itemprop=\"description\">"; idx = content.indexOf(s); if (idx > -1) { desc = content.substring(idx+s.length()); s = "<p>"; idx = desc.indexOf(s); if (idx > -1) { desc = desc.substring(idx+s.length()); s = "<em"; idx = desc.indexOf(s); if (idx > -1) { desc = desc.substring(0, idx); if (desc.length() > 2) { Memory.update("entries", "desc", desc.trim().replace("'", ""), "hash = '" + hash + "'"); return; } } } } */ } // <link rel="canonical" href="https://www.themoviedb.org/movie/14161-2012"> s = " <link rel=\"canonical\" href=\""; idx = content.indexOf(s); if (idx > -1) { title_url = content.substring(idx + s.length()); s = "\""; idx = title_url.indexOf(s); if (idx > -1) { title_url = title_url.substring(0, idx); Memory.update("entries", "alt", "null", "hash = '" + hash + "'"); Memory.update("entries", "url", title_url, "hash = '" + hash + "'"); return; } } } // default if not returned before Memory.update("entries", "alt", "null", "hash = '" + hash + "'"); Memory.update("entries", "url", "null", "hash = '" + hash + "'"); } catch (Exception e) { System.err.println(e.toString()); } finally { // check if image is available File f = new File("www/images/work/" + hash + ".jpg"); if (!f.exists()) { Memory.update("entries", "alt", "null", "hash = '" + hash + "'"); Memory.update("entries", "url", "null", "hash = '" + hash + "'"); } } } private static void createScreenshots(String hash) { File f = new File("ffmpeg.sh"); if (!f.exists()) { return; } try { Runtime rt = Runtime.getRuntime(); LinkedList<String> tmp_fn = Memory.select("filepath", "entries", "hash = '" + hash + "'"); if (tmp_fn.size() > 0) { String fn = tmp_fn.get(0); //rt.exec("sh ./ffmpeg.sh " + hash + " \""" + fn + "\"""); Process p = new ProcessBuilder("sh", "./ffmpeg.sh", hash, fn).start(); System.out.println("Process (" + Thread.currentThread().getId() + ") started."); } } catch (Exception e) { System.err.println(e.toString()); } } public static void getMeta(String name, String hash) { // work .json and .html files if not exists downloadMetaData(name, hash); // needs a loooong time, for a beautiful collection ;) // read meta data from .html file and insert into memory readMetaData(hash); // create screenshots //createScreenshots(hash); // insert into image cache try { //ImageCache.insert("work/" + hash + ".jpg", Base64.getEncoder().encodeToString(FileUtils.readFileToByteArray(new File("www/images/work/" + hash + ".jpg")))); ImageCache.insert("work/" + hash + ".jpg", FileUtils.readFileToByteArray(new File("www/images/work/" + hash + ".jpg"))); } catch (IOException ex) { // print error not needed here } } } /** * * MEMORY * */ static class Memory { public Memory() { } static public LinkedList<String> select(String key, String table) { Measure.start(); LinkedList<String> r = new LinkedList<>(); try { ResultSet rs = s_m.executeQuery("SELECT " + key + " FROM " + table + " ORDER BY " + key + ";"); while (rs.next()) { r.add(rs.getString(1)); } } catch (Exception e) { System.err.println(e.toString()); } debug("SELECT " + key + " FROM " + table + " ORDER BY " + key + "; (" + Measure.resultMs() + ")"); return r; } static public LinkedList<String> select(String key, String table, String condition) { Measure.start(); if (condition.length() > 0) { condition = " WHERE " + condition; } LinkedList<String> r = new LinkedList<>(); try { ResultSet rs = s_m .executeQuery("SELECT " + key + " FROM " + table + condition + " ORDER BY " + key + ";"); while (rs.next()) { r.add(rs.getString(1)); } } catch (Exception e) { System.err.println(e.toString()); } debug("SELECT " + key + " FROM " + table + condition + " ORDER BY " + key + "; (" + Measure.resultMs() + ")"); return r; } static public LinkedList<String> selectAsJSON(String keys, String table, String order, String filter) { Measure.start(); if (filter.length() > 0) { filter = " WHERE " + filter; } if (order.length() > 0) { order = " ORDER BY " + order; } LinkedList<String> r = new LinkedList<>(); try { ResultSet rs = s_m.executeQuery("SELECT " + keys + " FROM " + table + filter + order + ";"); ResultSetMetaData meta = rs.getMetaData(); int cols = meta.getColumnCount(); String row = ""; while (rs.next()) { for (int i = 0; i < cols; i++) { row += meta.getColumnName(i + 1).toLowerCase() + ": '" + rs.getString(i + 1) + "', "; } row = row.substring(0, row.length() - 2); r.add("{" + row + "}"); row = ""; } } catch (Exception e) { System.err.println(e.toString()); } debug("SELECT " + keys + " FROM " + table + filter + order + "; (" + Measure.resultMs() + ")"); return r; } static public void insert(String table, String keys, String values) { Measure.start(); try { s_m.executeUpdate("INSERT INTO " + table + " (" + keys + ") VALUES (" + values + ");"); } catch (Exception e) { System.err.println(e.toString()); } debug("INSERT INTO " + table + " (" + keys + ") VALUES (" + values + "); (" + Measure.resultMs() + ")"); } static public void update(String table, String key, String value, String condition) { Measure.start(); try { if (condition.length() > 0) { condition = " WHERE " + condition; } s_m.executeUpdate("UPDATE " + table + " SET " + key + " = '" + value + "'" + condition + ";"); } catch (Exception e) { System.err.println(e.toString()); } debug("UPDATE " + table + " SET " + key + " = '" + value + "'" + condition + "; (" + Measure.resultMs() + ")"); } } /** * * SETTINGS * */ static class Settings { public Settings() { } static public int count(String key) { Measure.start(); try { ResultSet rs = s_p .executeQuery("SELECT COUNT(settingsindex) FROM settings WHERE key = '" + key + "';"); while (rs.next()) { debug("SELECT COUNT(settingsindex) FROM settings WHERE key = '" + key + "'; (" + Measure.resultMs() + ")"); return rs.getInt(1); } } catch (Exception e) { System.err.println(e.toString()); } debug("SELECT COUNT(settingsindex) FROM settings WHERE key = '" + key + "'; (" + Measure.resultMs() + ")"); return -1; } static public LinkedList<String> get(String key) { Measure.start(); try { ResultSet rs = s_p.executeQuery("SELECT value FROM settings WHERE key = '" + key + "';"); LinkedList<String> r = new LinkedList<>(); while (rs.next()) { r.add(rs.getString(1)); } debug("SELECT value FROM settings WHERE key = '" + key + "'; (" + Measure.resultMs() + ")"); return r; } catch (Exception e) { System.err.println(e.toString()); debug("SELECT value FROM settings WHERE key = '" + key + "'; (" + Measure.resultMs() + ")"); return null; } } static public void remove(String table, String key, String condition) { Measure.start(); if (condition.length() > 0) { condition = " WHERE key = '" + key + "' AND value = '" + condition + "'"; } try { s_p.executeUpdate("DELETE FROM " + table + condition); } catch (Exception e) { System.err.println(e.toString()); } debug("DELETE FROM " + table + condition + "(" + Measure.resultMs() + ")"); } static public void setOnce(String key, String value) { Measure.start(); try { if (count(key) == 0) { s_p.executeQuery("INSERT INTO settings (settingsindex, key, value) VALUES (" + System.currentTimeMillis() + ", '" + key + "', '" + value + "');"); } else { s_p.executeUpdate("UPDATE settings SET value = '" + value + "' WHERE key = '" + key + "';"); } } catch (Exception e) { System.err.println(e.toString()); } debug("INSERT INTO settings (settingsindex, key, value) VALUES (" + System.currentTimeMillis() + ", '" + key + "', '" + value + "'); (" + Measure.resultMs() + ")"); } static public void set(String key, String value) { Measure.start(); try { s_p.executeQuery("INSERT INTO settings (settingsindex, key, value) VALUES (" + System.currentTimeMillis() + ", '" + key + "', '" + value + "');"); } catch (Exception e) { System.err.println(e.toString()); } debug("INSERT INTO settings (settingsindex, key, value) VALUES (" + System.currentTimeMillis() + ", '" + key + "', '" + value + "'); (" + Measure.resultMs() + ")"); } static public void setURI(String uri) { set(Settings.getFromURI(uri, "key"), Settings.getFromURI(uri, "value")); } static public void setURIOnce(String uri) { setOnce(Settings.getFromURI(uri, "key"), Settings.getFromURI(uri, "value")); } static public LinkedList<String> getURI(String uri) { String key = uri.substring(uri.indexOf("key=") + 4); if (key.contains("&")) { key = key.substring(0, key.indexOf("&")); } return get(key); } static public String getFromURI(String uri, String key) { String value = ""; if (uri.contains(key + "=")) { value = uri.substring(uri.indexOf(key + "=") + key.length() + 1); if (value.contains("&")) { value = value.substring(0, value.indexOf("&")); } return value; } else { return value; } } } /** * * MEASURE * */ static class Measure { public Measure() { } static private Map<Long, Long> m = Collections.synchronizedMap(new HashMap<>()); static public void start() { System.out.println("Start: " + Thread.currentThread().getId()); startMs(); //startNano(); } static private void startMs() { m.put(Thread.currentThread().getId(), System.currentTimeMillis()); } static private void startNano() { m.put(Thread.currentThread().getId(), System.nanoTime()); } static public String resultMs() { String s = (System.currentTimeMillis() - m.get(Thread.currentThread().getId())) + " ms"; //m.remove(Thread.currentThread().getId()); return s; } static public String resultNano() { String s = (System.nanoTime() - m.get(Thread.currentThread().getId())) + " ns"; //m.remove(Thread.currentThread().getId()); return s; } } static class ImageCache { static private final Map<String, byte[]> images = new HashMap<>(); static public void read() throws IOException { // read images File dir = new File("./www/images/"); File[] files = dir.listFiles(); for (File f : files) { if (f.isDirectory()) { File[] files2 = f.listFiles(); for (File f2 : files2) { if (!f2.isDirectory()) { String fn = f2.toString().replace("\\", "/"); fn = fn.substring(fn.indexOf("images/") + 7); insert(fn, FileUtils.readFileToByteArray(f2)); } } } else { String fn = f.toString().replace("\\", "/"); fn = fn.substring(fn.indexOf("images/") + 7); //insert(f, Base64.getEncoder().encodeToString(FileUtils.readFileToByteArray(file.toFile()))); insert(fn, FileUtils.readFileToByteArray(f)); } } } static public boolean contains(String k) { return images.containsKey(k); } static public void insert(String k, byte[] v) { images.put(k, v); } static public byte[] get(int i) { return images.get(i); } static public byte[] get(String k) { return images.get(k); } } /** * * HANDLERS * */ /** * FileHandler */ static boolean is_mobile = false; static class FileHandler implements HttpHandler { @Override public void handle(HttpExchange t) { Measure.start(); // check header for mobile detection String ua = t.getRequestHeaders().get("User-Agent").get(0); if (ua.matches( "(?i).*((android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino).*") || ua.substring(0, 4).matches( "(?i)1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-")) { is_mobile = true; } String uri = t.getRequestURI().toString(); debug(Thread.currentThread().getId() + ">" + uri); if (uri.equals("/")) uri += "?file=index.html"; // read file try { String file = Settings.getFromURI(uri, "file"); // prevent . and .. if (file.startsWith(".")) { sendResponse(t, 403, "Forbidden"); return; } if (file.startsWith("..")) { sendResponse(t, 403, "Forbidden"); return; } // special file operations (dummy files that do not exist) if (file.contains("mobile_detection.java")) { sendResponse(t, 200, "<script type='text/javascript'>setMobile(" + is_mobile + ");</script>"); return; } if (!file.startsWith("/")) { file = "/" + file; } file = System.getProperty("user.dir") + "/www" + file; File f = new File(getPath(file)); if (file.endsWith(".jpg") || file.endsWith(".gif") || file.endsWith(".png")) { String suf = file.substring(file.lastIndexOf(".") + 1); String k = file.substring(file.indexOf("images/") + 7); //sendResponse(t, 200, "data:image/"+suf+";base64," + ImageCache.get(k)); sendResponse(t, 200, ImageCache.get(k), suf); return; } sendResponse(t, 200, FileUtils.readFileToString(new File(getPath(file)))); } catch (Exception e) { System.err.println(e.toString()); sendResponse(t, 404, "Not found."); } finally { debug(Thread.currentThread().getId() + ">FileHandler>>>" + Measure.resultMs()); } is_mobile = false; // if callers are mobile and desktop at the same time } } /** * ConfigHandler */ static boolean intense_imdb_work_done = false; static class ConfigHandler implements HttpHandler { private String getConfigPath() { StringBuilder content = new StringBuilder(1024); content.append("<script type=\"text/javascript\">"); LinkedList<String> paths = Settings.get("path"); for (String path : paths) { content.append("wh.push('"); content.append(path); content.append("');"); } content.append("getConfigPath();</script>"); return content.toString(); } private void deleteUnknownHashFiles() { try { LinkedList<String> entries = Memory.select("hash", "entries"); Path dir = FileSystems.getDefault().getPath("work/"); DirectoryStream<Path> stream = Files.newDirectoryStream(dir); // insert entries for (Path file : stream) { String hash = file.toString().replace("\\", "/") .substring(file.toString().lastIndexOf("/") + 1); hash = hash.substring(0, hash.lastIndexOf(".")); if (!entries.contains(hash)) { FileUtils.deleteQuietly(file.toFile()); } else { int a = 0; } } dir = FileSystems.getDefault().getPath("www/images/work/"); stream = Files.newDirectoryStream(dir); // insert entries for (Path file : stream) { String hash = file.toString().replace("\\", "/") .substring(file.toString().lastIndexOf("/") + 1); hash = hash.substring(0, hash.lastIndexOf(".")); if (!entries.contains(hash)) { if (!FileUtils.deleteQuietly(file.toFile())) { System.err.println("Unable to delete file '" + file.toString() + "'."); } } } } catch (Exception e) { System.err.println(e.toString()); } } private String readName(String fn, String name) { String old = name; try (Scanner in = new Scanner(System.in)) { //name = in.nextLine(); name = name.replace(" ", "_"); name = name.replaceAll("- 3D - ", ""); name = name.replaceAll("DVD9", ""); name = name.replaceAll("1080p", ""); name = name.replaceAll("720p", ""); name = name.replaceAll("BlueRay", ""); name = name.replaceAll("Remux", ""); name = name.replaceAll("REMASTERED", ""); name = name.replaceAll("DVD5", ""); name = name.replaceAll("x264", ""); name = name.replaceAll("DTSD", ""); name = name.replaceAll(".DL.", ""); name = name.replaceAll("DTS", ""); name = name.replaceAll("AC3D", ""); name = name.replaceAll("AVC", ""); name = name.replaceAll("UNTOUCHED", ""); name = name.replaceAll("PAL", ""); name = name.replaceAll("DVDR", ""); name = name.replaceAll("DVD", ""); name = name.replaceAll("COMPLETE.BLURAY", ""); name = name.replaceAll("HD2DVD", ""); name = name.replaceAll("XviD", ""); name = name.replaceAll("DTSHD", ""); name = name.replaceAll(".COMPLETE.", ""); name = name.replace("..", ""); name = name.trim(); return name; } catch (Exception e) { System.err.println(e.toString()); } // rename file File f = new File(fn); boolean ok = f.renameTo(new File(fn.replace(old, name))); return name; } private String getCleanName(String fn, String name) { // remove Thumbs.db if (name.equals("Thumbs.db")) { return ""; } // invalid suffixes String[] i_suf = { ".sub" }; for (String i_suf1 : i_suf) { if (name.endsWith(i_suf1)) { return ""; } } // min length 5 if (name.length() < 5) { return readName(fn, name); } // no whitespaces if (name.contains(" ")) { name = readName(fn, name); } // strip suffix String[] suf = { ".mkv", ".avi", ".mpg", ".mp4", ".iso", ".ts" }; for (String suf1 : suf) { if (name.contains(suf1)) { name = name.substring(0, name.indexOf(suf1)); } } // _(nnnn) if (!name.endsWith(")") || !name.substring(name.length() - 6, name.length() - 5).equals("(") || !name.substring(name.length() - 7, name.length() - 6).equals("_")) { return readName(fn, name); } return name; // ok } private void readEntries() { if (intense_imdb_work_done) { return; } // only do imdb work only once intense_imdb_work_done = true; LinkedList<String> l = Settings.getURI("key=path"); try { // remove entries s_m.executeUpdate("DELETE FROM entries;"); // symbolic link path checker (exists() needs to long if link target not available) HashMap<String, Boolean> dirs_exists = new HashMap<>(); for (String cur : l) { // insert entries File dir = new File(cur); File[] files = dir.listFiles(); for (File file : files) { // check is link Path p = file.toPath(); boolean file_exists = true; if (Files.isSymbolicLink(p)) { file = Files.readSymbolicLink(p).toFile(); int idx; String s = "/"; String path = file.toString().replace("\\", "/"); idx = path.lastIndexOf(s); if (idx > -1) { path = path.substring(0, idx); if (!dirs_exists.containsKey(path)) { file_exists = Files.exists(p); // needs a while dirs_exists.put(path, file_exists); } else { file_exists = dirs_exists.get(path); } } else { // invalid path?! file_exists = false; } } else { file_exists = file.exists(); } String hash, name = ""; String filepath = file.toString(); filepath = filepath.replace("'", ""); filepath = filepath.replace("\\", "/"); int idx; // name if ((idx = filepath.lastIndexOf("/")) > -1) { name = filepath.substring(idx + 1); } // only sweeeet and clean file names name = getCleanName(filepath, name); if (name.length() > 0) { name = name.replace("_", " ").replace("[", "(").replace("]", ")"); // hash MessageDigest md = MessageDigest.getInstance("MD5"); md.update(name.getBytes(), 0, name.getBytes().length); hash = new BigInteger(1, md.digest()).toString(16); Memory.insert("entries", "entriesindex, hash, filepath, name, f_exists", "" + System.currentTimeMillis() + ", '" + hash + "', '" + filepath + "', '" + name + "', " + file_exists); // alt & title-url MetaInfo.getMeta(name, hash); } } // read images into cache ImageCache.read(); // everything read, now cleanup work dirs //deleteUnknownHashFiles(); } } catch (SQLException | IOException | NoSuchAlgorithmException e) { System.err.println(e.toString()); } // could be set when /config/ triggered on false intense_imdb_work_done = true; } private void delete(String uri) { String condition = Settings.getFromURI(uri, "condition"); Settings.remove("settings", "path", condition); } private void seek() { new Thread() { public void run() { try { while (true) { int state = 10; StringBuilder r = new StringBuilder(); int code = 0; while (state < 80) { code = Http.get("http://127.0.0.1:8080/requests/status.xml?command=seek&val=" + state + "%25", r, null); if (code == 200) { String time = r.toString().substring(r.toString().indexOf("<time>")); String length = r.toString().substring(r.toString().indexOf("<length>")); } state += 10; Thread.sleep(2000L); } return; } } catch (InterruptedException e) { } } }.start(); } private void killMp() { // try to kill old process try { if (p != null) { p.destroy(); } } catch (Exception e) { // ignore } } Process p = null; @Override public void handle(HttpExchange t) throws IOException { //Measure.start(); String response = ""; String uri = t.getRequestURI().toString(); if (uri.contains("/config/?createDist")) { try { // create zip process Runtime rt = Runtime.getRuntime(); rt.exec("sh ./create_dist.sh"); } catch (Exception e) { System.err.println(e.toString()); } finally { sendResponse(t, 200, ""); debug("ConfigHandler>>>" + Measure.resultMs()); return; } } if (uri.contains("/config/?getConfigPath")) { sendResponse(t, 200, getConfigPath()); debug("ConfigHandler>>>" + Measure.resultMs()); return; } if (uri.contains("/config/?readEntries")) { killMp(); readEntries(); // count entries int with = Memory.select("url", "entries").size(); int without = Memory.select("url", "entries", "url = 'null'").size(); sendResponse(t, 200, "<script type=\"text/javascript\">calcQuality('" + with + "', '" + without + "');</script>"); debug("ConfigHandler>>>" + Measure.resultMs()); return; } if (uri.contains("/config/?stop")) { killMp(); sendResponse(t, 200, ""); debug("ConfigHandler>>>" + Measure.resultMs()); return; } if (uri.contains("/config/?seek")) { seek(); sendResponse(t, 200, "hui"); debug("ConfigHandler>>>" + Measure.resultMs()); return; } if (uri.contains("/config/?play=")) { killMp(); String filepath = Settings.getFromURI(uri, "play").replace("play_", ""); LinkedList<String> l = Settings.get("mediaplayer"); if (l.size() == 0) { sendResponse(t, 200, ""); debug("ConfigHandler>>>" + Measure.resultMs()); return; } String mp = l.get(0).replace("%20", " "); try { String line; p = Runtime.getRuntime().exec("/usr/bin/" + mp + " " + filepath); try (BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()))) { while ((line = input.readLine()) != null) { System.out.println(line); } } int c = p.waitFor(); int a = 0; } catch (IOException | InterruptedException err) { System.err.println(err.toString()); } sendResponse(t, 200, ""); debug("ConfigHandler>>>" + Measure.resultMs()); return; } if (uri.contains("key=") && !uri.contains("value=")) { LinkedList<String> l = Settings.getURI(uri); response = ""; for (String l1 : l) { response += l1; response += ", "; } if (response.length() > 2) { response = response.substring(0, response.length() - 2); } sendResponse(t, 200, response); return; } // everything ABOVE -> meta work will be skipped // everything BELOW -> meta work will be done intense_imdb_work_done = false; response = "<script type=\"text/javascript\">window.location.href='/?file=test.html';</script>"; if (uri.contains("/config/?delete")) { delete(uri); sendResponse(t, 200, response); debug("ConfigHandler>>>" + Measure.resultMs()); return; } if (uri.contains("value=")) { if (uri.contains("once")) { Settings.setURIOnce(uri); } else { Settings.setURI(uri); } } sendResponse(t, 200, response); //debug("ConfigHandler>>>"+Measure.resultMs()); } } /** * StorageHandler */ static boolean storageHandlerBusy = false; static class StorageHandler implements HttpHandler { private String printEntries(String uri, LinkedList<String> recs) { Measure.start(); // build filter condition String filter = ""; if (uri.contains("&filter=") || recs != null) { if (Settings.getFromURI(uri, "filter").equals("only_not_found")) { filter = "url = 'null'"; // check all work images exists LinkedList<String> hashes = Memory.select("hash", "entries"); for (String hash : hashes) { try { File f = new File("www/images/work/" + hash + ".jpg"); if (!f.exists()) { filter += " OR hash = '" + hash + "'"; } } catch (Exception e) { System.err.println(e.toString()); } } } else { if (recs != null) { String f; for (int i = 0; i < recs.size(); i++) { f = recs.get(i); filter += "LOWER(name) LIKE '%" + f + "%' OR LOWER(alt) LIKE '%" + f + "%' OR LOWER(url) LIKE '%" + f + "%' OR LOWER(actors) LIKE '%" + f + "%' OR LOWER(hash) LIKE '%" + f + "%'"; filter += " OR "; } if (filter.length() > 0) { filter = filter.substring(0, filter.length() - 4); } } else { String f = Settings.getFromURI(uri, "filter").toLowerCase().replace("%20", " "); if (!f.equals("search for movie title, alt title, imdb title or actor...")) { filter = "LOWER(name) LIKE '%" + f + "%' OR LOWER(alt) LIKE '%" + f + "%' OR LOWER(url) LIKE '%" + f + "%' OR LOWER(actors) LIKE '%" + f + "%' OR LOWER(hash) LIKE '%" + f + "%'"; } } } } String mode = "json"; StringBuilder response = new StringBuilder(100000); response.append("<script type=\"text/javascript\">"); // get mode if (uri.contains("&mode=")) { mode = Settings.getFromURI(uri, "mode"); if (mode.length() == 0) mode = "json"; } // mode json if (mode.equals("json")) { LinkedList<String> l = Memory.selectAsJSON("hash, filepath, name, alt, url, f_exists, desc, actors", "entries", "name", filter); for (String l1 : l) { response.append("entries.push(Object.toJSON(").append(l1).append("));"); } response.append("printEntriesCallback('json');"); } // mode direct if (mode.equals("direct")) { LinkedList<String> l = Memory.select("name", "entries"); response.append("$('wh_entries').innerHTML = '"); String bg_color; for (int i = 0; i < l.size(); i++) { if (i % 2 == 0) { bg_color = "yellow"; } else { bg_color = "red"; } response.append("<div style='background-color: ").append(bg_color).append(";'>") .append(l.get(i)).append("</div>"); } response.append("';printEntriesCallback('direct');"); } response.append("</script>"); try { debug("printEntries>" + Measure.resultMs()); } catch (Exception e) { System.err.println(e.toString()); } return response.toString(); } private LinkedList<String> related(String hash) { LinkedList<String> l = Memory.select("name", "entries", "hash = '" + hash + "'"); if (l.size() > 0) { // entry found String s; int idx; // read work/hash.html try { File f = new File("work/" + hash + ".html"); String content = FileUtils.readFileToString(f); s = "class=\"rec_slide\">"; idx = content.indexOf(s); if (idx > -1) { // valid html and recs found content = content.substring(idx + s.length()); LinkedList<String> recs = new LinkedList<>(); s = "data-tconst=\""; idx = content.indexOf(s); while (idx > -1) { content = content.substring(idx + s.length()); s = "\""; idx = content.indexOf(s); if (idx > -1) { s = content.substring(0, idx); if (!recs.contains(s)) { recs.add(s); } } s = "data-tconst=\""; idx = content.indexOf(s); } if (recs.size() > 0) { // recs found return recs; } } } catch (Exception e) { System.err.println(e.toString()); } /* // get recs from bing (also searched) s = l.get(0); idx = s.indexOf("("); if (idx > -1) { s = s.substring(0, idx).trim(); } s = s.replace(" ", "%20"); StringBuilder r = new StringBuilder(); Http.get("https://api.datamarket.azure.com/Bing/Search/v1/RelatedSearch?Query=%27" + s + "%27&Market=%27de-DE%27&$format=json", r, "OlkwRXEvNXJpNzRiME1KSDRHVlMxUjM4aWVaVlBNSkZVSTlMdjBFM2pPeHM="); */ } return null; } @Override public void handle(HttpExchange t) throws IOException { Measure.start(); String uri = t.getRequestURI().toString(); // url was set if (uri.contains("/update/?url")) { String hash = Settings.getFromURI(uri, "hash"); String url = Settings.getFromURI(uri, "url"); // re-read meta data MetaInfo.getMeta(url, hash); sendResponse(t, 200, "<script type=\"text/javascript\">window.location.href='/?file=test.html&scrollTo=" + hash + "';</script>"); } if (uri.startsWith("/select/?related")) { storageHandlerBusy = true; sendResponse(t, 200, printEntries(uri, related(Settings.getFromURI(uri, "hash")))); storageHandlerBusy = false; return; } if (uri.contains("/select/?printEntries")) { if (storageHandlerBusy) { // prevent flurry calls sendResponse(t, 200, ""); return; } storageHandlerBusy = true; sendResponse(t, 200, printEntries(uri, null)); storageHandlerBusy = false; return; } debug("StorageHandler>>>" + Measure.resultMs()); } } static class MiscHandler implements HttpHandler { private String getComplementary(String c) { if (c.startsWith("%23")) { c = c.substring(3, c.length()); } if (c.startsWith("#")) { c = c.substring(1, c.length()); } int r = Integer.valueOf(c.substring(0, 2), 16); int g = Integer.valueOf(c.substring(2, 4), 16); int b = Integer.valueOf(c.substring(4, 6), 16); r = ((r - 255) * -1); g = ((g - 255) * -1); b = ((b - 255) * -1); return String.format("#%02x%02x%02x", r, g, b); } private String getAvgColor(String hash) { try { BufferedImage img = ImageIO.read(new File("www/images/work/_" + hash + ".jpg")); long r = 0; long g = 0; long b = 0; long px_count = 0; long c = 0; for (int y = 0; y < img.getHeight(); y++) { for (int x = 0; x < img.getWidth(); x++) { c = img.getRGB(x, y); r += (c >> 16) & 0xff; g += (c >> 8) & 0xff; b += c & 0xff; px_count++; } } return String.format("#%02x%02x%02x", r / px_count, g / px_count, b / px_count); } catch (Exception e) { System.err.println(e.toString()); } return "#000"; // default } @Override public void handle(HttpExchange t) throws IOException { String uri = t.getRequestURI().toString(); if (uri.startsWith("/misc/?avgColor")) { sendResponse(t, 200, getAvgColor(Settings.getFromURI(uri, "hash"))); return; } if (uri.startsWith("/misc/?getComplementary")) { // #FF0000 -> #00FFFF // #00FF00 -> #FF00FF // #0000FF -> #FFFF00 sendResponse(t, 200, getComplementary(Settings.getFromURI(uri, "c"))); return; } sendResponse(t, 200, "<script type=\"text/javascript\"></script>"); } } static class ChatHandler implements HttpHandler { private String heardBeat() { StringBuilder r = new StringBuilder(); int c = Http.get("http://adda-srv:9982/?heardbeat", r, null); if (c == 200) { return r.toString(); } else { return ""; } } private String send(String u) { String v = Settings.getFromURI(u, "send"); StringBuilder r = new StringBuilder(); int c = Http.get("http://adda-srv:9982/?send=" + v, r, null); if (c == 200) { return r.toString(); } else { return ""; } } private String communicate(String s) { StringBuilder r = new StringBuilder(); int c = Http.get("http://adda-srv:9982/?communicate&euuid=" + s, r, null); if (c == 200) { return r.toString(); } else { return ""; } } private final LinkedList<String> messages = new LinkedList<>(); // (ip, messages) private String next() { StringBuilder r = new StringBuilder(); int c = Http.get("http://adda-srv:9982/?next", r, null); if (c == 200) { String s = r.toString(); if (s.length() > 0) { messages.add(s); } return s; } else { // unable to find adda-srv return "<Client xxx disconnected>"; } } @Override public void handle(HttpExchange t) throws IOException { String uri = t.getRequestURI().toString(); String s = Settings.get("communicate").get(0); if (uri.equals("/chat/?heardbeat") && s.equals("true")) { sendResponse(t, 200, heardBeat()); return; } if (uri.startsWith("/chat/?communicate")) { sendResponse(t, 200, communicate(Settings.getFromURI(uri, "euuid"))); return; } if (uri.startsWith("/chat/?send=") && s.equals("true")) { sendResponse(t, 200, send(uri)); return; } if (uri.equals("/chat/?next")) { sendResponse(t, 200, next()); return; } sendResponse(t, 200, "<script type=\"text/javascript\"></script>"); } } static public void sendResponse(HttpExchange t, int state, String r) { if (state != 200) System.err.println(r); try { byte[] bytes = r.getBytes(); Headers h = t.getResponseHeaders(); if (t.getRequestURI().toString().endsWith(".css")) { h.set("Content-Type", "text/css"); } else { h.set("Content-Type", "text/html"); } t.sendResponseHeaders(state, bytes.length); try (OutputStream os = t.getResponseBody()) { os.write(bytes); } } catch (Exception e) { System.err.println("BIG ERROR!!! " + e.toString()); } } static public void sendResponse(HttpExchange t, int state, byte[] bytes, String type) { if (state != 200) System.err.println(bytes); if (type != null) { if (type.equals("png") || type.equals("gif") || type.equals("jpg")) { type = "image/" + type; } } try { Headers h = t.getResponseHeaders(); h.set("Content-Type", type); t.sendResponseHeaders(state, bytes.length); try (OutputStream os = t.getResponseBody()) { os.write(bytes); } } catch (Exception e) { System.err.println("BIG ERROR!!! " + e.toString()); } } // statics static Connection mem; // memory db static Connection pers; // persistent db static Statement s_m; // connection memory static Statement s_p; // connection persistent static BasicDataSource d_m; // data source memory static BasicDataSource d_p; // data source persistent /** * @param args the command line arguments */ public static void main(String[] args) { try { Measure.start(); // create dbs // memory d_m = new BasicDataSource(); d_m.setDriverClassName("org.hsqldb.jdbc.JDBCDriver"); d_m.setUrl("jdbc:hsqldb:mem:emma"); d_m.setUsername("sa"); d_m.setPassword(""); mem = d_m.getConnection(); s_m = mem.createStatement(); s_m.executeUpdate( "CREATE TABLE entries (entriesindex BIGINT, hash VARCHAR(42), filepath VARCHAR(255), name VARCHAR(255), alt VARCHAR(255), url VARCHAR(255), img VARCHAR(255), actors VARCHAR(2048), f_exists BOOLEAN, desc VARCHAR(2048));"); // persistent d_p = new BasicDataSource(); d_p.setDriverClassName("org.hsqldb.jdbc.JDBCDriver"); d_p.setUrl("jdbc:hsqldb:file:settings"); d_p.setUsername("sa"); d_p.setPassword(""); pers = d_p.getConnection(); s_p = pers.createStatement(); s_p.executeUpdate( "CREATE TABLE IF NOT EXISTS settings (settingsindex BIGINT, key VARCHAR(255), value VARCHAR(255));"); // default settings Settings.setOnce("communicate", "false"); try { String line; Process p = Runtime.getRuntime().exec("sleep 0"); try (BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()))) { while ((line = input.readLine()) != null) { System.out.println(line); } } int c = p.waitFor(); int a = 0; } catch (IOException | InterruptedException err) { //err.printStackTrace(); } /* try { Logger LOG = LoggerFactory.getLogger(Emma.class); org.apache.http.client.HttpClient httpClient = new SimpleHttpClientBuilder().build(); HttpTools httpTools = new HttpTools(httpClient); TmdbFind find = new TmdbFind("ca7d0fb887a7be06bfee3a557f6e2238", httpTools); FindResults result = find.find("tt0468569", ExternalSource.IMDB_ID, "de"); System.out.println(result.toString()); } catch (Exception e) { System.err.println(e.toString()); } */ // build image cache ImageCache.read(); // create http server InetSocketAddress addr = new InetSocketAddress(9980); HttpServer server = HttpServer.create(addr, 0); server.createContext("/", new FileHandler()); server.createContext("/select", new StorageHandler()); server.createContext("/insert", new StorageHandler()); server.createContext("/update", new StorageHandler()); server.createContext("/delete", new StorageHandler()); server.createContext("/config", new ConfigHandler()); server.createContext("/chat", new ChatHandler()); server.createContext("/misc", new MiscHandler()); server.setExecutor(Executors.newFixedThreadPool(12)); server.start(); debug(">" + Measure.resultMs()); } catch (SQLException | IOException e) { System.err.println(e.toString()); } finally { } } }