Package me.mabra.hellonzb.httpserver.nioengine

Source Code of me.mabra.hellonzb.httpserver.nioengine.HttpJythonHandler

/*******************************************************************************
* HelloNzb -- The Binary Usenet Tool
* Copyright (C) 2010-2013 Matthias F. Brandstetter
* https://sourceforge.net/projects/hellonzb/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/

package me.mabra.hellonzb.httpserver.nioengine;

import me.mabra.hellonzb.AppConnector;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.python.core.*;
import org.python.util.PythonInterpreter;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


/**
* Handle Python pages for the HelloNzb Web Server via built-in Jython.
*
* @author Matthias F. Brandstetter
*/
public class HttpJythonHandler
{
  private final PythonInterpreter jython;

  private HashMap<String, String> resourceFiles;


  public HttpJythonHandler()
  {
    resourceFiles = new HashMap<String, String>();

    // init. Jython
    PySystemState.initialize();
    PySystemState sys = Py.getSystemState();
    sys.path.append(new PyString(System.getProperty("user.dir") + File.separator + "web" + File.separator + "python"));
    jython = new PythonInterpreter(null, sys);
  }

  public void addResource(String uri, String path)
  {
    resourceFiles.put(uri, path);
  }

  public void messageReceived(HttpServerHandler parentHandler, MessageEvent e, HttpRequest request) throws IOException
  {
    // get name of file to handle
    String path = null;
    String page = parentHandler.requestedPage();
    for(String key : resourceFiles.keySet())
    {
      if(page.startsWith(key))
      {
        path = resourceFiles.get(key);
        break;
      }
    }
    if(path == null)
    {
      System.err.println("Can't locate resource file to page " + page);
      parentHandler.pageNotFound(e);
      return;
    }
    File resource = new File(path);
    if(!resource.isFile() || !resource.canRead())
    {
      System.err.println("Can't access resource file " + path);
      throw new IOException(); // TODO
    }

    // retrieve parameters and pass them to the AppConnector
    AppConnector._instance()._setQueryParams(parentHandler.getQueryParams());

    // call Jython to generate HTML response
    StringBuilder jythonResp = callJython(resource);

    // redirect called from Python script?
    String response = jythonResp.toString();
    if(response.startsWith("Redirect:"))
    {
      parentHandler.redirect(e, response.split("\\:")[1]);
      return;
    }

    // send Jython-generated HTML response back to client
    parentHandler.writeResponse(e, "text/html", response);
  }

  private StringBuilder callJython(File script)
  {
    StringBuilder response = new StringBuilder();

    resetJython();
    AppConnector._instance()._resetHttpOutBuf();
    AppConnector._instance()._resetRedirect();

    try
    {
      // call Jython interpreter with Python source file
      InputStream is = new FileInputStream(script);
      jython.execfile(is);
      is.close();

      // redirect called from Python?
      String redirect = AppConnector._instance()._getRedirect();
      if(redirect != null)
      {
        response.append("Redirect:" + redirect);
      }
      else
      {
        // no redirect, parse output from Python file
        ArrayList<String> httpOut = AppConnector._instance()._getHttpOutBuf();
        for(String line : httpOut)
          response.append(line);
      }
    }
    catch(PyException ex)
    {
      AppConnector._instance()._getLogger().printStackTrace(ex);
      for(String line : jythonErrorToHTML(ex))
        response.append(line);
    }
    catch(Exception ex)
    {
      AppConnector._instance()._getLogger().printStackTrace(ex);
    }

    return response;
  }

  private void resetJython()
  {
    List<String> scriptLocals = new ArrayList<String>();
    PyObject locals = jython.getLocals();
    for(PyObject item : locals.__iter__().asIterable())
      scriptLocals.add(item.toString());
    for(String string : scriptLocals)
      jython.set(string, null);
  }

  private ArrayList<String> jythonErrorToHTML(PyException err)
  {
    ArrayList<String> html = new ArrayList<String>();

    html.add("<html><head><title>Jython Error</title></head><body>");
    html.add("<h3>Python Code generated an Error</h3><pre>");
    for(String line : err.toString().split("\n"))
      html.add(line);
    html.add("</pre></body></html>");

    return html;
  }
}













































TOP

Related Classes of me.mabra.hellonzb.httpserver.nioengine.HttpJythonHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.