<commit_before>/*************************************************************************
 *   Copyright (C) 2011-2013 by <NAME>                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of Teapotnet.                                     *
 *                                                                       *
 *   Teapotnet is free software: you can redistribute it and/or modify   *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   Teapotnet 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 Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with Teapotnet.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

#include "tpn/interface.h"
#include "tpn/html.h"
#include "tpn/user.h"
#include "tpn/store.h"
#include "tpn/splicer.h"
#include "tpn/config.h"
#include "tpn/directory.h"
#include "tpn/mime.h"

namespace tpn
{

Interface *Interface::Instance = NULL;

Interface::Interface(int port) :
		Http::Server(port)
{

}

Interface::~Interface(void)
{

}

void Interface::add(const String &prefix, HttpInterfaceable *interfaceable)
{
	Assert(interfaceable != NULL);
	
	String cprefix(prefix);
	if(cprefix.empty() || cprefix[0] != '/')
		cprefix = "/" + cprefix;
	
	mMutex.lock();
	mPrefixes.insert(cprefix, interfaceable);
	mMutex.unlock();
}

void Interface::remove(const String &prefix, HttpInterfaceable *interfaceable)
{
	mMutex.lock();
	HttpInterfaceable *test = NULL;
	if(mPrefixes.get(prefix, test) && (!interfaceable || test == interfaceable))
		mPrefixes.erase(prefix);
	mMutex.unlock();
}

void Interface::process(Http::Request &request)
{
	Address remoteAddr = request.sock->getRemoteAddress();
  	
	LogDebug("Interface", "Request for URL \""+request.fullUrl+"\"");
	
	// URL must begin with /
	if(request.url.empty() || request.url[0] != '/') throw 404;
	
	if(request.url == "/")
	{
		if(request.method == "POST")
		{
			String name, password, tracker;
			request.post.get("name", name);
			request.post.get("password", password);
			request.post.get("tracker", tracker);
			
			if(name.contains('@'))
				tracker = name.cut('@');
			
			User *user = NULL;
			try {
				if(request.post.contains("create") && !User::Exist(name))
				{
					user = new User(name, password, tracker);
				}
				else {
					user = User::Authenticate(name, password);
					if(user && !tracker.empty())
						user->setTracker(tracker);
				}
			}
			catch(const Exception &e)
			{
				Http::Response response(request, 200);
				response.send();
				
				Html page(response.sock);
				page.header("Error", false, "/");
				page.text(e.what());
				page.footer();
				return;
			}
			
			if(!user) throw 401;	// TODO
			
			String token = user->generateToken("auth");
				
			Http::Response response(request, 303);
			response.headers["Location"] = "/" + user->name();
			response.cookies["auth_"+user->name()] = token;
			response.send();
			return;
		}
	
/*
#ifdef ANDROID
		if(!user && remoteAddr.isLocal() && User::Count() == 1)
		{
			Array<String> names;
			User::GetNames(names);
			user = User::Get(names[0]);
			
			if(user)
			{
				Http::Response response(request, 303);
				response.headers["Location"] = "/" + user->name();
				response.send();
				return;
			}
		}
#endif
*/
		Http::Response response(request, 200);
		response.send();
		
		Html page(response.sock);
		page.header("Teapotnet - Login", true);
		page.open("div","login");
		page.open("div","logo");
		page.openLink("/");
		page.image("/logo.png", "Teapotnet");
		page.closeLink();
		page.close("div");
		
		page.openForm("/", "post");
		page.open("table");
		page.open("tr");
		page.open("td",".label"); page.label("name", "Name"); page.close("td");
		page.open("td"); page.input("text", "name"); page.close("td"); 
		page.open("td"); page.link("#", "Change trackers", "trackerlink"); page.close("td");
		page.close("tr");<commit_msg>Fixed page title<commit_after>/*************************************************************************
 *   Copyright (C) 2011-2013 by <NAME>                       *
 *   paul-louis (at) ageneau (dot) org                                   *
 *                                                                       *
 *   This file is part of Teapotnet.                                     *
 *                                                                       *
 *   Teapotnet is free software: you can redistribute it and/or modify   *
 *   it under the terms of the GNU Affero General Public License as      *
 *   published by the Free Software Foundation, either version 3 of      *
 *   the License, or (at your option) any later version.                 *
 *                                                                       *
 *   Teapotnet 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 Affero General Public License for more details.                 *
 *                                                                       *
 *   You should have received a copy of the GNU Affero General Public    *
 *   License along with Teapotnet.                                       *
 *   If not, see <http://www.gnu.org/licenses/>.                         *
 *************************************************************************/

#include "tpn/interface.h"
#include "tpn/html.h"
#include "tpn/user.h"
#include "tpn/store.h"
#include "tpn/splicer.h"
#include "tpn/config.h"
#include "tpn/directory.h"
#include "tpn/mime.h"

namespace tpn
{

Interface *Interface::Instance = NULL;

Interface::Interface(int port) :
		Http::Server(port)
{

}

Interface::~Interface(void)
{

}

void Interface::add(const String &prefix, HttpInterfaceable *interfaceable)
{
	Assert(interfaceable != NULL);
	
	String cprefix(prefix);
	if(cprefix.empty() || cprefix[0] != '/')
		cprefix = "/" + cprefix;
	
	mMutex.lock();
	mPrefixes.insert(cprefix, interfaceable);
	mMutex.unlock();
}

void Interface::remove(const String &prefix, HttpInterfaceable *interfaceable)
{
	mMutex.lock();
	HttpInterfaceable *test = NULL;
	if(mPrefixes.get(prefix, test) && (!interfaceable || test == interfaceable))
		mPrefixes.erase(prefix);
	mMutex.unlock();
}

void Interface::process(Http::Request &request)
{
	Address remoteAddr = request.sock->getRemoteAddress();
  	
	LogDebug("Interface", "Request for URL \""+request.fullUrl+"\"");
	
	// URL must begin with /
	if(request.url.empty() || request.url[0] != '/') throw 404;
	
	if(request.url == "/")
	{
		if(request.method == "POST")
		{
			String name, password, tracker;
			request.post.get("name", name);
			request.post.get("password", password);
			request.post.get("tracker", tracker);
			
			if(name.contains('@'))
				tracker = name.cut('@');
			
			User *user = NULL;
			try {
				if(request.post.contains("create") && !User::Exist(name))
				{
					user = new User(name, password, tracker);
				}
				else {
					user = User::Authenticate(name, password);
					if(user && !tracker.empty())
						user->setTracker(tracker);
				}
			}
			catch(const Exception &e)
			{
				Http::Response response(request, 200);
				response.send();
				
				Html page(response.sock);
				page.header("Error", false, "/");
				page.text(e.what());
				page.footer();
				return;
			}
			
			if(!user) throw 401;	// TODO
			
			String token = user->generateToken("auth");
				
			Http::Response response(request, 303);
			response.headers["Location"] = "/" + user->name();
			response.cookies["auth_"+user->name()] = token;
			response.send();
			return;
		}
	
/*
#ifdef ANDROID
		if(!user && remoteAddr.isLocal() && User::Count() == 1)
		{
			Array<String> names;
			User::GetNames(names);
			user = User::Get(names[0]);
			
			if(user)
			{
				Http::Response response(request, 303);
				response.headers["Location"] = "/" + user->name();
				response.send();
				return;
			}
		}
#endif
*/
		Http::Response response(request, 200);
		response.send();
		
		Html page(response.sock);
		page.header("Login - Teapotnet", true);
		page.open("div","login");
		page.open("div","logo");
		page.openLink("/");
		page.image("/logo.png", "Teapotnet");
		page.closeLink();
		page.close("div");
		
		page.openForm("/", "post");
		page.open("table");
		page.open("tr");
		page.open("td",".label"); page.label("name", "Name"); page.close("td");
		page.open("td"); page.input("text", "name"); page.close("td"); 
		page.open("td"); page.link("#", "Change trackers", "trackerlink"); page.close("td");
		page.close("tr");
{'fraction_non_alphanumeric': 0.1849366144668158, 'fraction_numerical': 0.006604879088100564, 'mean_word_length': 2.402682131206959, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 30, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3347140', 'n_tokens_mistral': 3183, 'n_tokens_neox': 2748, 'n_words': 629}