All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tinymediamanager.scraper.kodi.KodiUrl Maven / Gradle / Ivy

There is a newer version: 3.0
Show newest version
/*
 * Copyright 2012 - 2018 Manuel Laggner
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.tinymediamanager.scraper.kodi;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tinymediamanager.scraper.http.CachedUrl;
import org.tinymediamanager.scraper.http.Url;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * This represents the "smart" url of the Kodi metadata.
 * 
 * @author Manuel Laggner, Myron Boyle
 * 
 */
class KodiUrl {
  private static final Logger LOGGER = LoggerFactory.getLogger(KodiUrl.class);

  private String              urlString;
  private Url                 url;
  private String              functionName;
  private KodiScraper         scraper;

  public KodiUrl(Element url) {
    updateFromElement(url);
  }

  public KodiUrl(String url) {
    if (StringUtils.isBlank(url)) {
      return;
    }

    if (url.trim().contains("url syntax
      try {
        url = StringEscapeUtils.unescapeHtml4(url);
        url = StringEscapeUtils.unescapeXml(url);
        url = StringEscapeUtils.unescapeXml(url);
        url = StringEscapeUtils.unescapeXml(url);
        url = url.replaceAll("\\&", "\\&");

        DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
        DocumentBuilder parser = f.newDocumentBuilder();
        Document d = parser.parse(new ByteArrayInputStream(url.getBytes()));
        Element e = (Element) d.getElementsByTagName("url").item(0);
        updateFromElement(e);
      }
      catch (Exception e) {
        throw new RuntimeException("Invalid xml url: " + url, e);
      }
    }
    else {
      this.urlString = url.trim();
    }
    LOGGER.trace("KodiUrl using Url from String: " + urlString);
  }

  public KodiUrl(String url, KodiScraper kodiScraper) {
    this(url);
    this.scraper = kodiScraper;
  }

  public KodiUrl(Element url, KodiScraper kodiScraper) {
    this(url);
    this.scraper = kodiScraper;
  }

  private void updateFromElement(Element e) {
    urlString = e.getTextContent();
    if (urlString != null) {
      urlString = urlString.trim();
    }
    LOGGER.trace("KodiUrl using Url from Xml: " + urlString);
    functionName = e.getAttribute("function");
    // TODO: pull in post, spoof, etc.
  }

  private Url getUrl() throws Exception {
    if (url == null) {
      url = new CachedUrl(urlString);
      // TODO: Add in the referer, etc
    }

    return url;
  }

  public InputStream getInputStream() throws Exception {
    // check if this is a function lookup, and if so, then let's process this as such.
    if (scraper != null && !StringUtils.isEmpty(getFunctionName())) {
      KodiScraperProcessor processor = new KodiScraperProcessor(scraper);
      LOGGER.debug("Processing Url Function: " + getFunctionName() + " with Url: " + urlString);
      // we have a function to process
      // TODO: Set spoof and post attributes...
      KodiUrl xurl = new KodiUrl(urlString);
      String results = processor.executeFunction(getFunctionName(), new String[] { "", xurl.getTextContent() });
      if (results == null)
        results = "";
      return new ByteArrayInputStream(results.getBytes());
    }
    else {
      // TODO: Check for posting, caching, etc
      Url u = getUrl();

      if (urlString.contains(".zip")) {
        LOGGER.debug("Converting ZipFile to Text content for url: " + urlString);
        // turn the zip contents into a text file
        ZipInputStream zis = new ZipInputStream(u.getInputStream());
        ZipEntry ze = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int MAX_LEN = 2048;
        byte buf[] = new byte[MAX_LEN];
        while ((ze = zis.getNextEntry()) != null) {
          LOGGER.debug("Adding Zip Entry: " + ze.getName() + " to Text content");
          int len = 0;
          while ((len = zis.read(buf)) > 0) {
            baos.write(buf, 0, len);
          }
        }
        baos.flush();
        zis.close();
        LOGGER.debug("Returing Text Context as inputstream...");
        return new ByteArrayInputStream(baos.toByteArray());
      }
      else {
        return u.getInputStream();
      }
    }
  }

  public String toExternalForm() {
    return urlString;
  }

  public String getFunctionName() {
    return functionName;
  }

  public String getTextContent() throws Exception {
    InputStream is = getInputStream();
    if (is == null) {
      LOGGER.error("InputStream was NULL!!!");
      return "";
    }
    // return IOUtils.toString(getInputStream()); // why call 2 times and not recycle IS?
    return IOUtils.toString(is, "UTF-8"); // let's try ;)
  }

  @Override
  public String toString() {
    return "KodiUrl[" + urlString + "]";
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy