Add modules to repository

This commit is contained in:
Sebastian Kinne
2017-11-16 16:42:22 +11:00
commit d0aa1e38ef
707 changed files with 96750 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
<!-- This HTML has bootstrap classes such as "col-md-12" and "jumbotron". For more information, see http://getbootstrap.com/css/ -->
<!-- This HTML makes use of AngularJS data-bindings and controllers. For more information, see https://docs.angularjs.org/api/ -->
<!-- Don't forget to look at the module.js and module.php files too! -->
<!-- This HTML is a template for generated modules via the Module Maker. -->
<div class="col-md-12" ng-controller="ExampleController"> <!-- This special argument wires the HTML to your controller (in module.js) -->
<div class="jumbotron" style="border-radius: 7px;">
<div class="container">
<h1>{{ greeting }}</h1> <!-- This is an AngularJS data binding -->
<p>{{ content }}</p> <!-- They represent the $scope.xxxxx inside of your module.js -->
</div>
</div>
</div>

View File

@@ -0,0 +1,18 @@
/* This is our AngularJS controller, called "ExampleController". */
registerController('ExampleController', ['$api', '$scope', function($api, $scope) {
/* It is good practice to 'initialize' your variables with nothing */
$scope.greeting = "";
$scope.content = "";
/* Use the API to send a request to your module.php */
$api.request({
module: '_MODULE_NAME', //Your module name
action: 'getContents' //Your action defined in module.php
}, function(response) {
if (response.success === true) { //If the response has an index called "success" that returns the boolean "true", then:
$scope.greeting = response.greeting; // Set the variable $scope.greeting to the response index "greeting"
$scope.content = response.content; // Set the variable $scope.content to the response index "content".
}
console.log(response) //Log the response to the console, this is useful for debugging.
});
}]);

View File

@@ -0,0 +1,27 @@
<?php namespace pineapple;
/* The class name must be the name of your module, without spaces. */
/* It must also extend the "Module" class. This gives your module access to API functions */
class _MODULE_NAME extends Module
{
public function route()
{
switch ($this->request->action) {
case 'getContents': // If you request the action "getContents" from your Javascript, this is where the PHP will see it, and use the correct function
$this->getContents(); // $this->getContents(); refers to your private function that contains all of the code for your request.
break; // Break here, and add more cases after that for different requests.
}
}
private function getContents() // This is the function that will be executed when you send the request "getContents".
{
$this->response = array("success" => true, // define $this->response. We can use an array to set multiple responses.
"greeting" => "Hey there!",
"content" => "This is the HTML template for your new module! The example shows you the basics of using HTML, AngularJS and PHP to seamlessly pass information to and from Javascript and PHP and output it to HTML.");
}
}

112
ModuleMaker/api/module.php Normal file
View File

@@ -0,0 +1,112 @@
<?php namespace pineapple;
/**
* Foxtrot (C) 2016 <foxtrotnull@gmail.com>
**/
class ModuleMaker extends Module
{
public function route()
{
switch ($this->request->action) {
case 'generateModule':
$this->generateModule();
break;
case 'getInstalledModules':
$this->getInstalledModules();
break;
case 'removeModule':
$this->removeModule();
break;
}
}
private function generateModule()
{
/* Make life easier */
$moduleTitle = $this->request->moduleTitle;
$moduleDescription = $this->request->moduleDesc;
$moduleVersion = $this->request->moduleVersion;
$moduleAuthor = str_replace(' ', '', $this->request->moduleAuthor);
$moduleName = str_replace(' ', '', $moduleTitle);
$modulePath = "/pineapple/modules/{$moduleName}";
$templates = "/pineapple/modules/ModuleMaker/Extra";
/* Check whether the user has acceptable input and check if the module already exists */
if(empty($moduleTitle)){
$this->error = "The module name cannot be empty.";
} elseif (file_exists($modulePath)) {
$this->error = "A module with this name already exists.";
} elseif(empty($moduleDescription)){
$this->error = "You must specify a description.";
} elseif(!is_numeric($moduleVersion)){
$this->error = "Module version must be in the form of X.X";
} elseif(substr_count($moduleVersion, '.') <1 || substr_count($moduleVersion, '.') >1){
$this->error = "Module version must only contain one period.";
} elseif(empty($moduleAuthor)){
$this->error = "You must supply an Author.";
}
/* If an error is set, return early */
if($this->error){
return;
}
if(substr_count($moduleVersion, '.') <1){
}
/* If the user passes all the above checks, proceed to create the module */
mkdir("{$modulePath}");
mkdir("{$modulePath}/js/");
mkdir("{$modulePath}/api/");
copy("{$templates}/module.html", "{$modulePath}/module.html");
copy("{$templates}/module.js", "{$modulePath}/js/module.js");
exec("sed -i 's/_MODULE_NAME/{$moduleName}/g' {$modulePath}/js/module.js");
copy("{$templates}/module.php", "{$modulePath}/api/module.php");
exec("sed -i 's/_MODULE_NAME/{$moduleName}/g' {$modulePath}/api/module.php");
/* Create a module.info with the data the user has input */
file_put_contents("{$modulePath}/module.info", json_encode(array("title" => $moduleTitle, "description" => $moduleDescription, "version" => $moduleVersion, "author" => $moduleAuthor), JSON_PRETTY_PRINT));
/* Once the module has been created, set the response to success */
$this->response = array("success" => true);
}
private function getInstalledModules()
{
$modules = array();
$modulesDirectories = scandir('/pineapple/modules');
foreach ($modulesDirectories as $moduleDirectory) {
if ($moduleDirectory[0] === ".") {
continue;
}
if (file_exists("/pineapple/modules/{$moduleDirectory}/module.info")) {
$moduleData = json_decode(file_get_contents("/pineapple/modules/{$moduleDirectory}/module.info"));
$module = array();
$module['title'] = $moduleData->title;
$module['author'] = $moduleData->author;
$module['version'] = $moduleData->version;
$module['description'] = $moduleData->description;
if (isset($moduleData->system)) {
$module['type'] = "System";
} else {
$module['type'] = "GUI";
}
$modules[$moduleDirectory] = $module;
}
}
$this->response = array("installedModules" => $modules);
}
}

71
ModuleMaker/js/module.js Normal file
View File

@@ -0,0 +1,71 @@
// Foxtrot (C) 2016 <foxtrotnull@gmail.com>
registerController('ModuleMakerGenerator', ['$api', '$scope', '$timeout', function($api, $scope, $timeout) {
$scope.moduleTitle = "";
$scope.moduleDesc = "";
$scope.moduleVersion = "";
$scope.moduleAuthor = "";
$scope.generateSuccess = false;
$scope.generateFailure = "";
$scope.generateModule = (function() {
$api.request({
module: 'ModuleMaker',
action: 'generateModule',
moduleTitle: $scope.moduleTitle,
moduleDesc: $scope.moduleDesc,
moduleVersion: $scope.moduleVersion,
moduleAuthor: $scope.moduleAuthor
}, function(response) {
if (response.success === true) {
$scope.generateSuccess = true;
$scope.moduleTitle = "";
$scope.moduleDesc = "";
$scope.moduleVersion = "";
$scope.moduleAuthor = "";
$timeout(function(){
$scope.generateSuccess = false;
}, 2000);
} else {
$scope.generateFailure = response.error;
$timeout(function(){
$scope.generateFailure = "";
}, 5000);
}
});
});
}])
registerController('ModuleMakerManager', ['$api', '$scope', '$timeout', function($api, $scope, $timeout) {
$scope.installedModules = "";
$scope.removedModule = "";
$scope.getInstalledModules = (function() {
$api.request({
module: "ModuleMaker",
action: "getInstalledModules"
}, function(response) {
$scope.installedModules = response.installedModules;
console.log(response);
});
});
$scope.removeModule = (function(name) {
$api.request({
module: 'ModuleManager',
action: 'removeModule',
moduleName: name
}, function(response) {
if (response.success === true) {
$scope.getInstalledModules();
$scope.removedModule = true;
$api.reloadNavbar();
$timeout(function(){
$scope.removedModule = false;
}, 2000);
}
});
});
$scope.getInstalledModules();
}])

118
ModuleMaker/module.html Normal file
View File

@@ -0,0 +1,118 @@
<!-- Foxtrot (C) 2016 <foxtrotnull@gmail.com> -->
<div>
<div class="row">
<div class="col-md-7">
<div class="panel panel-default" ng-controller="ModuleMakerGenerator">
<div class="panel-heading">
<h3 class="panel-title">Generate
<button type="button" class="close pull-right" data-toggle="modal" data-target="#information" aria-label="Close"><span aria-hidden="true">i</span></button>
</h3>
</div>
<div class="panel-body">
<form class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">Title</label>
<div class="col-sm-7">
<input type="text" class="form-control" ng-model="moduleTitle" placeholder="Some Module">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Description</label>
<div class="col-sm-7">
<input type="text" class="form-control" ng-model="moduleDesc" placeholder="This is an example module">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Version</label>
<div class="col-sm-7">
<input type="text" class="form-control" ng-model="moduleVersion" placeholder="1.0">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Author</label>
<div class="col-sm-7">
<input type="text" class="form-control" ng-model="moduleAuthor" placeholder="Author">
</div>
</div>
<div class="form-group">
<div class="col-sm-7 col-md-offset-2">
<button class="btn btn-success" ng-click="generateModule();">Generate</button>
</div>
</div>
</form>
<p class="well well-sm alert-success" ng-show="generateSuccess">Successfully generated module <b>{{moduleName}}</b></p>
<p class="well well-sm alert-danger" ng-show="generateFailure">{{generateFailure}}</p>
</div>
</div>
<div id="information" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Information</h4>
</div>
<div class="modal-body">
<h3>module.html</h3>
<p>This folder contains the HTML for your module to be displayed within the UI. The HTML, Javascript and PHP all work together to create a responsive and dynamic module.</p>
<h3>module.info</h3>
<p>This simple JSON file contains the basic information about your module, such as name, version and author.</p>
<h3>js/</h3>
<p>The js folder contains all of the Javascript for your module. Note that you do not need to include jquery or bootstrap libraries as they are already built into the UI.</p>
<h3>api/</h3>
<p>The api folder contains the PHP for your module. The <b>module.php</b> file must contain a class that extends the <b>Module</b> class.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default" ng-controller="ModuleMakerManager">
<div class="panel-heading">
<h3 class="panel-title" title="Modules are stored at /pineapple/modules">Manage
<button type="button" ng-click="getInstalledModules();" class="close pull-right"aria-label="Refresh"><span aria-hidden="true">&#8635;</span></button>
</h3>
</div>
<div class="table-responsive table-dropdown">
<table class="table">
<thead>
<tr>
<th>Module</th>
<th>Version</th>
<th>Description</th>
<th>Author</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(moduleName, module) in installedModules" ng-hide="(module['type'] === 'System')">
<td>
{{ module['title'] }}
</td>
<td>
{{ module['version'] }}
</td>
<td>
{{ module['description'] }}
</td>
<td>
{{ module['author'] }}
</td>
<td>
<button type="button" class="btn btn-danger btn-xs btn-fixed-length" ng-click="removeModule(moduleName)">Remove</button>
</td>
</tr>
</tbody>
</table>
</div>
<p class="well well-sm alert-success" ng-show="removedModule">Successfully removed module</p>
</div>
</div>
</div>
</div>

10
ModuleMaker/module.info Normal file
View File

@@ -0,0 +1,10 @@
{
"author": "Foxtrot",
"description": "An easy way to generate modules.",
"devices": [
"nano",
"tetra"
],
"title": "Module Maker",
"version": "1.0"
}