HAlMon Initial Application

This commit is contained in:
Deon George 2011-07-19 15:57:37 +10:00
commit 217fa94867
21 changed files with 944 additions and 0 deletions

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "includes/kohana"]
path = includes/kohana
url = ssh://10.1.3.20/afs/local/git/lnkohana
[submodule "modules/lnApp"]
path = modules/lnApp
url = ssh://10.1.3.20/afs/local/git/lnapp

21
.htaccess Normal file
View File

@ -0,0 +1,21 @@
# Turn on URL rewriting
RewriteEngine On
# Installation directory
RewriteBase /
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Protect application and system files from being viewed
RewriteRule ^(?:application|modules|includes/kohana)\b.* index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to kh.php/URL
RewriteRule .* index.php/$0 [PT]

139
application/bootstrap.php Normal file
View File

@ -0,0 +1,139 @@
<?php defined('SYSPATH') or die('No direct script access.');
// -- Environment setup --------------------------------------------------------
// Load the core Kohana class
require SYSPATH.'classes/kohana/core'.EXT;
if (is_file(APPPATH.'classes/kohana'.EXT))
{
// Application extends the core
require APPPATH.'classes/kohana'.EXT;
}
else
{
// Load empty core extension
require SYSPATH.'classes/kohana'.EXT;
}
/**
* Set the default time zone.
*
* @see http://kohanaframework.org/guide/using.configuration
* @see http://php.net/timezones
*/
date_default_timezone_set('Australia/Melbourne');
/**
* Set the default locale.
*
* @see http://kohanaframework.org/guide/using.configuration
* @see http://php.net/setlocale
*/
setlocale(LC_ALL, 'en_US.utf-8');
/**
* Enable the Kohana auto-loader.
*
* @see http://kohanaframework.org/guide/using.autoloading
* @see http://php.net/spl_autoload_register
*/
spl_autoload_register(array('Kohana', 'auto_load'));
/**
* Enable the Kohana auto-loader for unserialization.
*
* @see http://php.net/spl_autoload_call
* @see http://php.net/manual/var.configuration.php#unserialize-callback-func
*/
ini_set('unserialize_callback_func', 'spl_autoload_call');
// -- Configuration and initialization -----------------------------------------
/**
* Set the default language
*/
I18n::lang('en-us');
/**
* Set Kohana::$environment if a 'KOHANA_ENV' environment variable has been supplied.
*
* Note: If you supply an invalid environment name, a PHP warning will be thrown
* saying "Couldn't find constant Kohana::<INVALID_ENV_NAME>"
*/
if (isset($_SERVER['KOHANA_ENV']))
{
Kohana::$environment = constant('Kohana::'.strtoupper($_SERVER['KOHANA_ENV']));
}
/**
* Initialize Kohana, setting the default options.
*
* The following options are available:
*
* - string base_url path, and optionally domain, of your application NULL
* - string index_file name of your index file, usually "index.php" index.php
* - string charset internal character set used for input and output utf-8
* - string cache_dir set the internal cache directory APPPATH/cache
* - boolean errors enable or disable error handling TRUE
* - boolean profile enable or disable internal profiling TRUE
* - boolean caching enable or disable internal caching FALSE
*/
Kohana::init(array(
'base_url' => '',
'index_file' => '',
'caching' => TRUE,
'cache_dir' => '/dev/shm/halmon',
));
/**
* Attach the file write to logging. Multiple writers are supported.
*/
Kohana::$log->attach(new Log_File(APPPATH.'logs'));
/**
* Attach a file reader to config. Multiple readers are supported.
*/
Kohana::$config->attach(new Config_File);
/**
* Enable modules. Modules are referenced by a relative or absolute path.
*/
Kohana::modules(array(
'auth' => SMDPATH.'auth', // Basic authentication
'cache' => SMDPATH.'cache', // Caching with multiple backends
// 'codebench' => SMDPATH.'codebench', // Benchmarking tool
'database' => SMDPATH.'database', // Database access
// 'image' => SMDPATH.'image', // Image manipulation
'orm' => SMDPATH.'orm', // Object Relationship Mapping
// 'unittest' => SMDPATH.'unittest', // Unit testing
'userguide' => SMDPATH.'userguide', // User guide and API documentation
'email' => SMDPATH.'email', // Email Module
));
/**
* Enable specalised interfaces
*/
Route::set('sections', '<directory>/<controller>(/<action>(/<id>(/<sid>)))',
array(
'directory' => '('.implode('|',Kohana::config('config.method_directory')).')'
));
// Static file serving (CSS, JS, images)
Route::set('default/media', 'media(/<file>)', array('file' => '.+'))
->defaults(array(
'controller' => 'welcome',
'action' => 'media',
'file' => NULL,
));
/**
* Set the routes. Each route must have a minimum of a name, a URI and a set of
* defaults for the URI.
*/
Route::set('default', '(<controller>(/<action>(/<id>)))', array('id' => '[a-zA-Z0-9_.-]+'))
->defaults(array(
'controller' => 'welcome',
'action' => 'index',
));
?>

View File

@ -0,0 +1,100 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class is handling Ademco Contact ID Events
*
* @package HAM
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class ContactID {
// Raw event ID
private $id = '';
private $acct;
private $sub;
private $qualifier;
private $type;
private $area;
private $alarm;
private $checksum;
private $datetime;
public function event($id,$dt,$cf='',$cn='') {
// @todo This shouldnt stop program execution, rather it should generate an email to an admin
if (! $this->check($id))
throw new Kohana_Exception('ContactID event :event is not valid',array(':event'=>$id));
// Process event trigger
$this->id = $id;
$this->acct = substr($id,0,4);
$this->sub = substr($id,4,2);
$this->qualifier = substr($id,6,1);
$this->type = substr($id,7,3);
$this->area = substr($id,10,2);
$this->info = substr($id,12,3);
$this->checksum = substr($id,15,1);
$this->datetime = $dt;
// Check the event is from a valid account
// @todo This shouldnt stop program execution, rather it should generate an email to an admin
$ao = ORM::factory('account',array('alarmphone'=>$cf,'siteid'=>$this->acct));
if (! $ao->loaded())
throw new Kohana_Exception('Event from unknown account :id is not valid',array(':id'=>$ao->id));
$eo = ORM::factory('event');
$eo->account_id = $ao->id;
$eo->alarmevent = $id;
$eo->datetime = $dt;
$eo->save();
// @todo This shouldnt stop program execution, rather it should generate an email to an admin
if (! $eo->saved())
throw new Kohana_Exception('ContactID event :event is not valid',array(':event'=>$id));
return $this;
}
public function __get($k) {
if (isset($this->{$k}))
return $this->{$k};
else
throw new Kohana_Exception('Unknown property :property',array(':property'=>$k));;
}
// Check that this event is valid
private function check($id) {
$checksum_map = array(
'0'=>10,
'1'=>1,
'2'=>2,
'3'=>3,
'4'=>4,
'5'=>5,
'6'=>6,
'7'=>7,
'8'=>8,
'9'=>9,
'*'=>11,
'#'=>12,
'A'=>13,
'B'=>14,
'C'=>15,
);
if (strlen($id) != 16)
throw new Kohana_Exception('ContactID event :event has an invalid length :length',array(':event'=>$id,':length'=>strlen($id)));
// Our checksum should be mod15
$c = $t = 0;
while ($c<strlen($id))
$t += $checksum_map[substr($id,$c++,1)];
if ($t%15 === 0)
return TRUE;
else
return FALSE;
}
}
?>

View File

@ -0,0 +1,113 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* HomeALarmMONitor Receive an Event
*
* @package HAM
* @subpackage CLI/Event
* @category Controllers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Controller_Task_Event extends Controller_Template {
/**
* Read in the events
*/
public function action_index() {
$dh = opendir(Kohana::config('config.event_dir'));
$fp = Kohana::config('config.event_file_prefix');
while ($f = readdir($dh)) {
if (preg_match("/^{$fp}/",$f)) {
$eventfile = sprintf('%s/%s',Kohana::config('config.event_dir'),$f);
if ($events = $this->event_file(file_get_contents($eventfile))) {
// Delete the event file, so that it isnt processed again
if (Kohana::config('config.event_file_keep'))
rename($eventfile,Kohana::config('config.event_dir').'/processed-'.$f);
else
unlink($eventfile);
// Trigger
$eo = new Events($events);
$eo->trigger();
} else
rename($eventfile,Kohana::config('config.event_dir').'/bad-'.$f);
}
}
}
private function event_file($file) {
$meta = $event = FALSE;
$et = $cf = $cn = $dt = NULL;
$good = TRUE;
$events = array();
foreach (explode("\n",$file) as $line) {
// Ignore out blank lines
if (! trim($line))
continue;
if (preg_match('/^\[metadata\]/',$line)) {
$meta = TRUE;
$event = FALSE;
continue;
} elseif (preg_match('/^\[events\]/',$line)) {
$meta = FALSE;
$event = TRUE;
continue;
}
if ($meta) {
list ($k,$v) = explode('=',$line,2);
switch ($k) {
case 'PROTOCOL':
switch ($v) {
case 'ADEMCO_CONTACT_ID':
$et = 'ContactID';
break;
default:
throw new Kohana_Exception('Unknown protocol :protocol',array(':protocol'=>$v));
}
break;
case 'CALLINGFROM':
$cf = $v;
break;
case 'CALLERNAME':
$cn = $v;
break;
case 'TIMESTAMP':
$dt = $v;
break;
default:
printf('Extra data in event file - meta section (%s)',$line);
}
} elseif ($event) {
if (! $et)
throw new Kohana_Exception('Event data without any protocol');
$eo = new $et;
if (! $eo->event($line,$dt,$cf,$cn))
$good = FALSE;
else
array_push($events,$eo);
}
}
return $events;
}
}
?>

View File

@ -0,0 +1,74 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class is used to handle alarm events just received
*
* @package HAM
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Events {
private $acct;
private $events = array();
public function __construct(array $events) {
foreach ($events as $event) {
// Set our accounts
if (is_null($this->acct))
$this->acct = $event->acct;
elseif ($this->acct != $event->acct)
throw new Kohana_Exception('Events are for multiple accounts, unable to handle this.');
}
// Save our events
$this->events = $events;
}
public function trigger() {
$ao = ORM::factory('account',array('siteid'=>$this->acct));
if (! $ao->loaded())
throw new Kohana_Exception('No site configuration for :siteid?',array(':siteid'=>$this->acct));
if (! $ao->model->model)
throw new Kohana_Exception('No configured Alarm Model for Alarm ID :id',array(':id'=>$ao->model->id));
$ac = sprintf('Panel_%s',$ao->model->model);
if (! class_exists($ac))
throw new Kohana_Exception('Unable to handle events for Alarm :model',array(':model'=>$ao->model->model));
$panel = new $ac($this->events);
foreach ($panel->trigger() as $event) {
$to = $ao->trigger->trigger($event['alarm']);
if (! $to->loaded())
continue;
// We need to email this event
if ($to->email) {
$e = Email::connect();
$sm = Swift_Message::newInstance();
$sm->setSubject('Notice from your alarm');
$sm->setBody(sprintf('Alarm: %s. Received: %s',$event['desc'],date('d-m-Y h:i:s',$event['date'])),'text/plain');
$sm->setTo($to->contact->email);
$sm->setFrom('noreply@leenooks.net');
$e->send($sm);
}
// We need to sms this event
if ($to->sms) {
printf('Alarm: %s, SMS: %s, Email: %s, To: %s (%s)',
$alo->description,
$to->sms,
$to->email,
$to->contact->email,$to->contact->phone);
echo "\n";
}
}
}
}
?>

View File

@ -0,0 +1,20 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
*
* @package HAM
* @subpackage Accounts
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Account extends ORM {
protected $_has_one = array(
'model'=>array('foreign_key'=>'id'),
);
protected $_has_many = array(
'trigger'=>array('far_key'=>'id'),
);
}
?>

View File

@ -0,0 +1,14 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
*
* @package HAM
* @subpackage Alarms
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Alarm extends ORM {
}
?>

View File

@ -0,0 +1,14 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
*
* @package HAM
* @subpackage Contacts
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Contact extends ORM {
}
?>

View File

@ -0,0 +1,14 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
*
* @package HAM
* @subpackage Events
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Event extends ORM {
}
?>

View File

@ -0,0 +1,17 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
*
* @package HAM
* @subpackage Models
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Model extends ORM {
protected $_has_many = array(
'alarm'=>array('far_key'=>'id'),
);
}
?>

View File

@ -0,0 +1,21 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
*
* @package HAM
* @subpackage Trigger
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Trigger extends ORM {
protected $_has_one = array(
'contact'=>array('foreign_key'=>'id'),
);
public function trigger($code) {
return $this->where('alarm','=',$code)->or_where('alarm','=',null)->find();
}
}
?>

View File

@ -0,0 +1,69 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class overrides Kohana's ORM
*
* @package lnApp/Modifications
* @category Classes
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class ORM extends Kohana_ORM {
protected $_table_names_plural = TRUE;
protected $_model_names_plural = FALSE;
private $_object_formated = array();
private $_formated = FALSE;
// Our filters used to display values in a friendly format
protected $_display_filters = array();
// Override check() so that it doesnt throw an exception.
// @todo Need to figure out how to show the items that fail validation
final public function check(Validation $extra_validation = NULL) {
// Determine if any external validation failed
$extra_errors = ($extra_validation AND ! $extra_validation->check());
// Always build a new validation object
$this->_validation();
$array = $this->_validation;
if (($this->_valid = $array->check()) === FALSE OR $extra_errors)
{
return FALSE;
}
return $this;
}
/**
* Format fields for display purposes
*
* @param string column name
* @return mixed
*/
private function _format() {
foreach ($this->_display_filters as $column => $formats)
$this->_object_formated[$column] = $this->run_filter($column,$this->__get($column),array($column=>$formats));
$this->_formated = TRUE;
}
/**
* Return a formated columns, as per the model definition
*/
public function display($column) {
// Trigger a load of the record.
$value = $this->__get($column);
// If some of our fields need to be formated for display purposes.
if ($this->_loaded AND ! $this->_formated AND $this->_display_filters)
$this->_format();
if (isset($this->_object_formated[$column]))
return $this->_object_formated[$column];
else
return HTML::nbsp($value);
}
}
?>

View File

@ -0,0 +1,21 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides the base for Alarm Panel models
*
* @package HAM
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
abstract class Panel {
protected $events = array();
public function __construct(array $events) {
$this->events = $events;
}
abstract public function trigger();
}
?>

View File

@ -0,0 +1,88 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class looks after Ness D8/Clipsal panel events
*
* @package HAM
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Panel_NessD8 extends Panel {
public function trigger() {
$return = array();
foreach ($this->events as $eo) {
$i = count($return);
$return[$i]['date'] = $eo->datetime;
$return[$i]['alarm'] = $eo->type;
if ($eo->sub != 18) {
$return[$i]['desc'] = sprintf('Unknown Alarm: %s',$eo->id);
continue;
}
switch ($eo->type) {
// Alarm
case 130:
switch ($eo->qualifier) {
case 1: $action = 'Alarm'; break;
case 3: $action = 'Reset'; break;
default: $action = 'Unknown';
}
$return[$i]['desc'] = sprintf('Alarm (%s) (Area %s) (%s)',$action,$eo->area,$eo->info);
break;
// Exit Installer Mode
case 306:
switch ($eo->qualifier) {
case 1: $action = 'Exit Installer Mode'; break;
default: $action = 'Unknown';
}
$return[$i]['desc'] = sprintf('Auto Exclude (%s) (Area %s) (%s)',$action,$eo->area,$eo->info);
break;
// Auto Exclude
case 380:
switch ($eo->qualifier) {
case 1: $action = 'Disarmed'; break;
case 3: $action = 'Armed'; break;
default: $action = 'Unknown';
}
$return[$i]['desc'] = sprintf('Auto Exclude (%s) (Area %s) (%s)',$action,$eo->area,$eo->info);
break;
// Arm/Disarm Call
case 402:
switch ($eo->qualifier) {
case 1: $action = 'Disarmed'; break;
case 3: $action = 'Armed'; break;
default: $action = 'Unknown';
}
// @todo Change this to include the user name.
$user = substr($eo->info,1,2)==58 ? 'Short Cut' : substr($eo->info,1,2);
// @todo Change this to include the area name.
$return[$i]['desc'] = sprintf('Panel %s (Area %s) (By %s)',$action,$eo->area,$user);
break;
// Test Call
case 602:
$return[$i]['desc'] = 'Test Call';
break;
default:
$return[$i]['desc'] = sprintf('Unknown Alarm: %s',$eo->id);
}
}
return $return;
}
}
?>

View File

@ -0,0 +1,32 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* HAM system default configurable items.
*
* @package HAM
* @category Configuration
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
return array(
'cache_type' => 'file',
'date_format' => 'd-m-Y',
'email_admin_only'=> array(
'method'=>array('wurley@users.sf.net'=>'Deon George'),
),
'event_dir' => '/var/spool/asterisk/tmp/alarm/',
'event_file_prefix'=>'event-',
'event_file_keep' => TRUE,
'method_directory'=> array( // Out method paths for the different functions
'task',
),
'method_security' => TRUE, // Enables Method Security. Setting to false means any method can be run without authentication
'site' => array(
),
'site_debug' => FALSE,
'site_mode' => array(
)
);
?>

View File

@ -0,0 +1,58 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
return array
(
'default' => array
(
'type' => 'mysql',
'connection' => array(
/**
* The following options are available for MySQL:
*
* string hostname server hostname, or socket
* string database database name
* string username database username
* string password database password
* boolean persistent use persistent connections?
*
* Ports and sockets may be appended to the hostname.
*/
'hostname' => 'localhost',
'database' => 'database',
'username' => 'username',
'password' => 'password',
'persistent' => FALSE,
),
'table_prefix' => '',
'charset' => 'utf8',
'caching' => FALSE,
'profiling' => TRUE,
),
'alternate' => array(
'type' => 'pdo',
'connection' => array(
/**
* The following options are available for PDO:
*
* string dsn Data Source Name
* string username database username
* string password database password
* boolean persistent use persistent connections?
*/
'dsn' => 'mysql:host=localhost;dbname=kohana',
'username' => 'root',
'password' => 'r00tdb',
'persistent' => FALSE,
),
/**
* The following extra options are available for PDO:
*
* string identifier set the escaping identifier
*/
'table_prefix' => '',
'charset' => 'utf8',
'caching' => FALSE,
'profiling' => TRUE,
),
);
?>

View File

1
includes/kohana Submodule

@ -0,0 +1 @@
Subproject commit f96694b18fdaa9bd6310debca71427068fe24046

121
index.php Normal file
View File

@ -0,0 +1,121 @@
<?php
/**
* The directory in which your application specific resources are located.
* The application directory must contain the bootstrap.php file.
*
* @see http://kohanaframework.org/guide/about.install#application
*/
$application = 'application';
/**
* The directory in which your modules are located.
*
* @see http://kohanaframework.org/guide/about.install#modules
*/
$modules = 'modules';
/**
* The directory in which upstream Kohana resources (modules) are located.
*/
$sysmodules = 'includes/kohana/modules';
/**
* The directory in which the Kohana resources are located. The system
* directory must contain the classes/kohana.php file.
*
* @see http://kohanaframework.org/guide/about.install#system
*/
$system = 'includes/kohana/system';
/**
* The default extension of resource files. If you change this, all resources
* must be renamed to use the new extension.
*
* @see http://kohanaframework.org/guide/about.install#ext
*/
define('EXT', '.php');
/**
* Set the PHP error reporting level. If you set this in php.ini, you remove this.
* @see http://php.net/error_reporting
*
* When developing your application, it is highly recommended to enable notices
* and strict warnings. Enable them by using: E_ALL | E_STRICT
*
* In a production environment, it is safe to ignore notices and strict warnings.
* Disable them by using: E_ALL ^ E_NOTICE
*
* When using a legacy application with PHP >= 5.3, it is recommended to disable
* deprecated notices. Disable with: E_ALL & ~E_DEPRECATED
*/
error_reporting(E_ALL | E_STRICT);
/**
* End of standard configuration! Changing any of the code below should only be
* attempted by those with a working knowledge of Kohana internals.
*
* @see http://kohanaframework.org/guide/using.configuration
*/
// Set the full path to the docroot
define('DOCROOT', realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR);
// Make the application relative to the docroot, for symlink'd index.php
if ( ! is_dir($application) AND is_dir(DOCROOT.$application))
$application = DOCROOT.$application;
// Make the modules relative to the docroot, for symlink'd index.php
if ( ! is_dir($modules) AND is_dir(DOCROOT.$modules))
$modules = DOCROOT.$modules;
// Make the system relative to the docroot, for symlink'd index.php
if ( ! is_dir($sysmodules) AND is_dir(DOCROOT.$sysmodules))
$sysmodules = DOCROOT.$sysmodules;
// Make the system relative to the docroot, for symlink'd index.php
if ( ! is_dir($system) AND is_dir(DOCROOT.$system))
$system = DOCROOT.$system;
// Define the absolute paths for configured directories
define('APPPATH', realpath($application).DIRECTORY_SEPARATOR);
define('MODPATH', realpath($modules).DIRECTORY_SEPARATOR);
define('SMDPATH', realpath($sysmodules).DIRECTORY_SEPARATOR);
define('SYSPATH', realpath($system).DIRECTORY_SEPARATOR);
// Clean up the configuration vars
unset($application, $modules, $sysmodules, $system);
if (file_exists('install'.EXT))
{
// Load the installation check
return include 'install'.EXT;
}
/**
* Define the start time of the application, used for profiling.
*/
if ( ! defined('KOHANA_START_TIME'))
{
define('KOHANA_START_TIME', microtime(TRUE));
}
/**
* Define the memory usage at the start of the application, used for profiling.
*/
if ( ! defined('KOHANA_START_MEMORY'))
{
define('KOHANA_START_MEMORY', memory_get_usage());
}
// Bootstrap the application
require APPPATH.'bootstrap'.EXT;
/**
* Execute the main request. A source of the URI can be passed, eg: $_SERVER['PATH_INFO'].
* If no source is specified, the URI will be automatically detected.
*/
echo Request::factory()
->execute()
->send_headers()
->body();

1
modules/lnApp Submodule

@ -0,0 +1 @@
Subproject commit 9e191ab0be69f296ae3cd2f079aafa80210f6928