Переглянути джерело

Completely Refactor MVC Model

Refactor the MVC model to be more PHP-ish and include the twig
templating library. This base commit is substantially better than the
oprevious and provides a solid foundation for faster iterations of
development and inclusion of new content.
pull/123/head
Justin Karimi 3 роки тому
джерело
коміт
8ed8c983dd
39 змінених файлів з 503 додано та 392 видалено
  1. +1
    -0
      templates/webpanel/.gitignore
  2. +16
    -0
      templates/webpanel/App/Config.php
  3. +13
    -0
      templates/webpanel/App/Controllers/CapturesController.php
  4. +13
    -0
      templates/webpanel/App/Controllers/PassesController.php
  5. +1
    -1
      templates/webpanel/App/Lang/ar.php
  6. +1
    -1
      templates/webpanel/App/Lang/de.php
  7. +1
    -1
      templates/webpanel/App/Lang/en.php
  8. +1
    -1
      templates/webpanel/App/Lang/es.php
  9. +1
    -1
      templates/webpanel/App/Lang/sr.php
  10. +18
    -0
      templates/webpanel/App/Views/Captures/index.html
  11. +17
    -0
      templates/webpanel/App/Views/Captures/pagination.html
  12. +19
    -0
      templates/webpanel/App/Views/Passes/index.html
  13. +53
    -0
      templates/webpanel/App/Views/base.html
  14. +33
    -0
      templates/webpanel/Lib/Controller.php
  15. +56
    -0
      templates/webpanel/Lib/Router.php
  16. +25
    -0
      templates/webpanel/Lib/View.php
  17. +0
    -7
      templates/webpanel/capture.php
  18. +0
    -7
      templates/webpanel/captures.php
  19. +11
    -0
      templates/webpanel/composer.json
  20. +205
    -0
      templates/webpanel/composer.lock
  21. +0
    -7
      templates/webpanel/config.php
  22. +0
    -9
      templates/webpanel/controllers/capture_controller.php
  23. +0
    -15
      templates/webpanel/controllers/captures_controller.php
  24. +0
    -7
      templates/webpanel/controllers/pass_controller.php
  25. +0
    -7
      templates/webpanel/index.php
  26. +0
    -110
      templates/webpanel/models/db_conn.php
  27. +0
    -0
      templates/webpanel/public/assets/css/captures.css
  28. +0
    -0
      templates/webpanel/public/assets/css/footer.css
  29. +0
    -0
      templates/webpanel/public/assets/css/header.css
  30. +0
    -0
      templates/webpanel/public/assets/css/pass_list.css
  31. +0
    -0
      templates/webpanel/public/assets/web_img/favicon.ico
  32. +0
    -0
      templates/webpanel/public/assets/web_img/logo-small.png
  33. +18
    -0
      templates/webpanel/public/index.php
  34. +0
    -60
      templates/webpanel/views/all_captures.php
  35. +0
    -39
      templates/webpanel/views/capture.php
  36. +0
    -14
      templates/webpanel/views/footer.php
  37. +0
    -47
      templates/webpanel/views/header.php
  38. +0
    -17
      templates/webpanel/views/pagination.php
  39. +0
    -41
      templates/webpanel/views/pass_list.php

+ 1
- 0
templates/webpanel/.gitignore Переглянути файл

@@ -0,0 +1 @@
vendor

+ 16
- 0
templates/webpanel/App/Config.php Переглянути файл

@@ -0,0 +1,16 @@
<?php

namespace App;

class Config {
# base directory for sqlite database
const DB_DIR = '/home/pi/raspberry-noaa/';

# see files in App/Lang directory for available translations
const LANG = 'en';

# use https://www.php.net/manual/en/timezones.php
const TIMEZONE = 'America/New_York';
}

?>

+ 13
- 0
templates/webpanel/App/Controllers/CapturesController.php Переглянути файл

@@ -0,0 +1,13 @@
<?php

namespace App\Controllers;

use Lib\View;

class CapturesController extends \Lib\Controller {
public function indexAction($args) {
View::renderTemplate('Captures/index.html', $args);
}
}

?>

+ 13
- 0
templates/webpanel/App/Controllers/PassesController.php Переглянути файл

@@ -0,0 +1,13 @@
<?php

namespace App\Controllers;

use Lib\View;

class PassesController extends \Lib\Controller {
public function indexAction($args) {
View::renderTemplate('Passes/index.html', $args);
}
}

?>

templates/webpanel/i18n/ar.php → templates/webpanel/App/Lang/ar.php Переглянути файл

@@ -1,5 +1,5 @@
<?php
$lang = array(
return array(
"captures" => "يلتقط",
"elev" => "الإرتفاع",
"images" => "الصور",

templates/webpanel/i18n/de.php → templates/webpanel/App/Lang/de.php Переглянути файл

@@ -1,5 +1,5 @@
<?php
$lang = array(
return array(
"captures" => "Erfasst",
"elev" => "Erhebung",
"images" => "Bilder",

templates/webpanel/i18n/en.php → templates/webpanel/App/Lang/en.php Переглянути файл

@@ -1,5 +1,5 @@
<?php
$lang = array(
return array(
"captures" => "Captures",
"elev" => "Elevation",
"images" => "Images",

templates/webpanel/i18n/es.php → templates/webpanel/App/Lang/es.php Переглянути файл

@@ -1,5 +1,5 @@
<?php
$lang = array(
return array(
"captures" => "Capturas",
"elev" => "Elevación",
"images" => "Imagenes",

templates/webpanel/i18n/sr.php → templates/webpanel/App/Lang/sr.php Переглянути файл

@@ -1,5 +1,5 @@
<?php
$lang = array(
return array(
"captures" => "Hvatanja",
"elev" => "Visina",
"images" => "Slike",

+ 18
- 0
templates/webpanel/App/Views/Captures/index.html Переглянути файл

@@ -0,0 +1,18 @@
{% extends "base.html" %}

{% block body %}
<link rel="stylesheet" type="text/css" href="assets/css/captures.css">

<nav aria-label="page" id="pagination" class="mb-0">
{% include('Captures/pagination.html') %}
</nav>

<div class="page-count-summary mb-0 mx-2 my-1">
{{ "#{lang['page']} #{cur_page} #{lang['of']} #{page_count}" }}
</div>

<nav aria-label="page" id="pagination" class="d-md-none mb-0">
{% include('Captures/pagination.html') %}
</nav>

{% endblock %}

+ 17
- 0
templates/webpanel/App/Views/Captures/pagination.html Переглянути файл

@@ -0,0 +1,17 @@
<nav aria-label="page" id="pagination" class="mb-0">
<ul class="pagination pagination-sm justify-content-center mb-0 mx-2">
<li class="page-item{% if cur_page <= 1 %} disabled {% endif %}">
<a class="page-link" href="{{ "?page=#{cur_page-1}" }}" aria-label="{{ lang['prev'] }}">
<span aria-hiden="true">&laquo;</span>
<span>{{ lang['prev'] }}</span>
</a>
</li>

<li class="page-item{% if cur_page >= page_count %} disabled {% endif %}">
<a class="page-link" href="{{ "?page=#{cur_page+1}" }}" aria-label="{{ lang['next'] }}">
<span>{{ lang['next'] }}</span>
<span aria-hiden="true">&raquo;</span>
</a>
</li>
</ul>
</nav>

+ 19
- 0
templates/webpanel/App/Views/Passes/index.html Переглянути файл

@@ -0,0 +1,19 @@
{% extends "base.html" %}

{% block body %}
<link rel="stylesheet" type="text/css" href="assets/css/pass_list.css">

<table class="table table-bordered table-sm table-striped" id="passes">
<thead class="thead-dark">
<tr class="text-center">
<th scope="col">{{ lang['satellite'] }}</th>
<th scope="col">{{ lang['pass_start'] }}</th>
<th scope="col">{{ lang['pass_end'] }}</th>
<th scope="col">{{ lang['max_elev'] }}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>

{% endblock %}

+ 53
- 0
templates/webpanel/App/Views/base.html Переглянути файл

@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">

<link rel="stylesheet" type="text/css" href="assets/css/header.css">
<link rel="stylesheet" type="text/css" href="assets/css/footer.css">

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<title>Raspberry NOAA V2</title>

<link rel="shortcut icon" href="assets/web_img/favicon.ico" type="image/x-icon"/>
</head>
<body>
<header class="mb-3">
<div class="navbar navbar-expand navbar-dark bg-dark">
<ul class="navbar-nav mr-auto">
<li class="nav-item {% if page == 'passes' %} active {% endif %}">
<a class="nav-link" href="passes">{{ lang['passes'] }}</a>
</li>
<li class="nav-item {% if page == 'captures' or page == 'capture' %} active {% endif%}">
<a class="nav-link" href="captures">{{ lang['captures'] }}</a>
</li>
</ul>
<span class="navbar-text timezone">
<em>
{{ constant('App\\Config::TIMEZONE') }}<br>
(UTC{{ 'now'|date('P') }})
</em>
</span>
</div>
</header>

<div class="container">
{% block body %}
{% endblock %}
</div>

<footer class="footer text-center">
<div class="contaienr">
<a href="https://github.com/reynico/raspberry-noaa"><img class="img-footer" src="assets/web_img/logo-small.png"></a>
</div>
</footer>

<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script>
</body>
</html>

+ 33
- 0
templates/webpanel/Lib/Controller.php Переглянути файл

@@ -0,0 +1,33 @@
<?php

namespace Lib;

abstract class Controller {
public function __construct($name) {
$this->name = $name;
}

# mapping to provide a before and after functionality
public function __call($name, $args) {
$method = $name . 'Action';
$path = explode('\\', get_called_class());

if (method_exists($this, $method)) {
if ($this->before() !== false) {
# add the page name for navigation control
$args = array_merge($args, array(array('page' => $this->name)));

call_user_func_array([$this, $method], $args);
$this->after();
}
} else {
echo '404 - method ' . $method . ' not found<br>';
}
}

protected function before() { }

protected function after() { }
}

?>

+ 56
- 0
templates/webpanel/Lib/Router.php Переглянути файл

@@ -0,0 +1,56 @@
<?php

namespace Lib;

class Router {
private $controller = null;
private $action = null;
private $params = array();

# default constructor and check for validity of request
public function __construct() {
$this->convertUrl();
$this->handleRequest();
}

# split URL into controller, action, and params components
public function convertUrl() {
if (isset($_SERVER['REQUEST_URI'])) {
# remove leading/trailing slashes, and exclude query params
$uri_parts = explode('?', $_SERVER['REQUEST_URI'], 2);
$url = rtrim($uri_parts[0], '/');
$url = ltrim($url, '/');

# filter for malicious input
$url = filter_var($url, FILTER_SANITIZE_URL);

# separate path components and store the
# the controller, action, and any parameters
$url = explode('/', $url);
$this->controller = (isset($url[0]) and $url[0] != '') ? $url[0] : 'passes';
$this->action = (isset($url[1]) and $url[1] != '') ? $url[1] : 'index';
$this->params = (isset($uri_parts[1]) and $uri_parts[1] != '') ? $uri_parts[1] : null;
}
}

# based on request path, attempt to route to correct location
public function handleRequest() {
# attempt to build and call controller action
$controller_name = ucfirst($this->controller) . 'Controller';
$controller_file = __DIR__ . '/../App/Controllers/' . $controller_name . '.php';

if (file_exists($controller_file)) {
# construct instance of controller
include_once($controller_file);
$full_controller_name = "App\\Controllers\\" . $controller_name;
$this->controller = new $full_controller_name($this->controller);

# TODO: Pass parameters
$this->controller->{$this->action}();
} else {
echo '404 - could not find controller<br>';
}
}
}

?>

+ 25
- 0
templates/webpanel/Lib/View.php Переглянути файл

@@ -0,0 +1,25 @@
<?php

namespace Lib;

use App\Config;

class View {
# render a template using twig
public static function renderTemplate($template, $args = []) {
static $twig = null;

# include i18n language file for global inclusion
$lang = include(__DIR__ . '/../App/Lang/' . Config::LANG . '.php');

if ($twig === null) {
$loader = new \Twig\Loader\FilesystemLoader(dirname(__DIR__) . '/App/Views');
$twig = new \Twig\Environment($loader);
$twig->addGlobal('lang', $lang);
}

echo $twig->render($template, $args);
}
}

?>

+ 0
- 7
templates/webpanel/capture.php Переглянути файл

@@ -1,7 +0,0 @@
<?php
# "Capture" showing list of all images for a particular capture
include_once('views/header.php');
$pass_id = isset($_GET['id']) ? intval($_GET['id']) : 1;
require('controllers/capture_controller.php');
include_once('views/footer.php')
?>

+ 0
- 7
templates/webpanel/captures.php Переглянути файл

@@ -1,7 +0,0 @@
<?php
# "Captures" showing grid of all captured images
include_once('views/header.php');
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
require('controllers/captures_controller.php');
include_once('views/footer.php')
?>

+ 11
- 0
templates/webpanel/composer.json Переглянути файл

@@ -0,0 +1,11 @@
{
"require": {
"twig/twig": "~3.0"
},
"autoload": {
"psr-4": {
"Lib\\": "Lib/",
"App\\": "App/"
}
}
}

+ 205
- 0
templates/webpanel/composer.lock Переглянути файл

@@ -0,0 +1,205 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "d8b0017452a0ac0413ba7a9ee3d5d3e8",
"packages": [
{
"name": "symfony/polyfill-ctype",
"version": "v1.22.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
"reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"time": "2021-01-07T16:49:33+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.22.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
"reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"time": "2021-01-07T16:49:33+00:00"
},
{
"name": "twig/twig",
"version": "v3.2.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "f795ca686d38530045859b0350b5352f7d63447d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/f795ca686d38530045859b0350b5352f7d63447d",
"reference": "f795ca686d38530045859b0350b5352f7d63447d",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3"
},
"require-dev": {
"psr/container": "^1.0",
"symfony/phpunit-bridge": "^4.4.9|^5.0.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
}
},
"autoload": {
"psr-4": {
"Twig\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Twig Team",
"role": "Contributors"
},
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com",
"role": "Project Founder"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
"homepage": "https://twig.symfony.com",
"keywords": [
"templating"
],
"time": "2021-01-05T15:40:36+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}

+ 0
- 7
templates/webpanel/config.php Переглянути файл

@@ -1,7 +0,0 @@
<?php
return (object) array(
'db_dir' => '/home/pi/raspberry-noaa/', # base directory for sqlite database
'lang' => 'en', # see files in i18n/ directory for available translations
'timezone' => 'America/New_York' # use https://www.php.net/manual/en/timezones.php
);
?>

+ 0
- 9
templates/webpanel/controllers/capture_controller.php Переглянути файл

@@ -1,9 +0,0 @@
<?php
$configs = include('config.php');
require('models/db_conn.php');
$db_conn = new Conn($configs->db_dir);
if ($pass_id < 1) $pass_id = 1;
$enhancements = $db_conn->getEnhancements($pass_id);
$path = $db_conn->getImagePath($pass_id);
require('views/capture.php');
?>

+ 0
- 15
templates/webpanel/controllers/captures_controller.php Переглянути файл

@@ -1,15 +0,0 @@
<?php
$img_per_page = 18;

$configs = include('config.php');
require('models/db_conn.php');
$db_conn = new Conn($configs->db_dir);
$page_count = $db_conn->totalPages($img_per_page);

# adjust for under/over paging
if ($page < 1) $page = 1;
if ($page > $page_count) $page = $page_count;

$images = $db_conn->getImages($page, $img_per_page);
require('views/all_captures.php');
?>

+ 0
- 7
templates/webpanel/controllers/pass_controller.php Переглянути файл

@@ -1,7 +0,0 @@
<?php
$configs = include('config.php');
require('models/db_conn.php');
$db_conn = new Conn($configs->db_dir);
$passes = $db_conn->getPasses();
require('views/pass_list.php');
?>

+ 0
- 7
templates/webpanel/index.php Переглянути файл

@@ -1,7 +0,0 @@
<?php
# "Passes" showing table of all scheduled passes (and landing page)
include_once('views/header.php');
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
require('controllers/pass_controller.php');
include_once('views/footer.php')
?>

+ 0
- 110
templates/webpanel/models/db_conn.php Переглянути файл

@@ -1,110 +0,0 @@
<?php
class Conn {
private $con;

# default constructor
public function __construct(string $db_dir) {
$this->con = new SQLite3($db_dir . 'panel.db');
}

# get scheduled pass list information
public function getPasses() {
$today = strtotime(date('Y-m-d', time()));
$query = $this->con->query("SELECT sat_name,
is_active,
pass_start,
pass_end,
max_elev
FROM predict_passes
WHERE (pass_start > $today)
ORDER BY pass_start ASC;");
$passes = [];
$i = 0;

while ($row = $query->fetchArray()) {
$passes[$i] = $row;
$i++;
}

return $passes;
}

# get total number of pages to display images given the
# passed number of images per page
public function totalPages($img_per_page) {
$decoded_passes = $this->con->querySingle("SELECT count()
FROM decoded_passes;");
return ceil($decoded_passes/$img_per_page);
}

# get a list of images for the given page and total number
# of configured images per page
public function getImages($page, $img_per_page) {
$query = $this->con->prepare("SELECT decoded_passes.id,
predict_passes.pass_start,
file_path,
sat_type,
predict_passes.sat_name,
predict_passes.max_elev
FROM decoded_passes
INNER JOIN predict_passes
ON predict_passes.pass_start = decoded_passes.pass_start
ORDER BY decoded_passes.pass_start DESC LIMIT ? OFFSET ?;");
$query->bindValue(1, $img_per_page);
$query->bindValue(2, $img_per_page * ($page-1));
$result = $query->execute();

$images = [];
$i = 0;
while ($row = $result->fetchArray()) {
$images[$i] = $row;
$i++;
}

return $images;
}

# get the enhancements for the particular capture
public function getEnhancements($id) {
$query = $this->con->prepare('SELECT daylight_pass,
sat_type,
img_count
FROM decoded_passes
WHERE id = ?;');
$query->bindValue(1, $id);
$result = $query->execute();
$pass = $result->fetchArray();

# build enhancement paths based on satellite type
switch($pass['sat_type']) {
case 0: // Meteor-M2
$enhancements = ['-122-rectified.jpg'];
break;
case 1: // NOAA
if ($pass['daylight_pass'] == 1) {
$enhancements = ['-ZA.jpg','-MCIR.jpg','-MCIR-precip.jpg','-MSA.jpg','-MSA-precip.jpg','-HVC.jpg','-HVC-precip.jpg','-HVCT.jpg','-HVCT-precip.jpg'];
} else {
$enhancements = ['-ZA.jpg','-MCIR.jpg','-MCIR-precip.jpg'];
}
break;
case 2: // ISS
for ($x = 0; $x <= $pass['img_count']-1; $x++) {
$enhancements[] = "-$x.png";
}
break;
}
return $enhancements;
}

# get the image path for the specific image
public function getImagePath($id) {
$query = $this->con->prepare('SELECT file_path
FROM decoded_passes
WHERE id = ?;');
$query->bindValue(1, $id);
$result = $query->execute();
$image = $result->fetchArray();
return $image['file_path'];
}
}
?>

templates/webpanel/css/captures.css → templates/webpanel/public/assets/css/captures.css Переглянути файл


templates/webpanel/css/footer.css → templates/webpanel/public/assets/css/footer.css Переглянути файл


templates/webpanel/css/header.css → templates/webpanel/public/assets/css/header.css Переглянути файл


templates/webpanel/css/pass_list.css → templates/webpanel/public/assets/css/pass_list.css Переглянути файл


templates/webpanel/assets/web_img/favicon.ico → templates/webpanel/public/assets/web_img/favicon.ico Переглянути файл


templates/webpanel/assets/web_img/logo-small.png → templates/webpanel/public/assets/web_img/logo-small.png Переглянути файл


+ 18
- 0
templates/webpanel/public/index.php Переглянути файл

@@ -0,0 +1,18 @@
<?php

# composer auto-loading
require dirname(__DIR__) . '/vendor/autoload.php';

use App\Config;

# error handling
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);

include(__DIR__ . '/../Lib/Router.php');

# handle route dispatching
$router = new Lib\Router();

?>

+ 0
- 60
templates/webpanel/views/all_captures.php Переглянути файл

@@ -1,60 +0,0 @@
<link rel="stylesheet" type="text/css" href="css/captures.css">

<nav aria-label="page" id="pagination" class="mb-0">
<?php include('views/pagination.php'); ?>
</nav>

<div class="page-count-summary mb-0 mx-2 my-1">
<?php echo $lang['page'] . " " . $page . " " . $lang['of'] . " " . $page_count; ?>
</div>

<?php
$col_count=0;
$i = 0;
$img_count = count($images);

foreach ($images as $image) {
if ($col_count % 3 == 0) {
echo "<div class=\"card-group capture-image-cards\">";
}

// automatically append filename conventions
switch($image['sat_type']) {
case 0: // Meteor-M2
$ending = "-122-rectified.jpg";
break;
case 1: // NOAA
$ending = "-MCIR.jpg";
break;
case 2: // ISS
$ending = "-0.png";
break;
}

# build image path
$img_path = "/images/thumb/" . $image['file_path'] . $ending;

// output image and details, with link to respective enhancement images
echo "<div class=\"card bg-light m-2 p-2 image-card\">";
echo " <a href=\"capture.php?id=" . $image['id'] . "\"><img class=\"card-img-top\" src=\"" . $img_path . "\" alt=\"img\"></a>";
echo " <div class=\"card-body\">";
echo " <h5 class=\"card-title\">" . $image['sat_name'] . "</h5>";
echo " <p class=\"card-text\">";
echo " <strong>" . $lang['elev'] . ":</strong> " . $image['max_elev'] . "&#176;<br>";
echo " <strong>" . $lang['pass_start'] . ":</strong> " . date('m/d/Y H:i:s', $image['pass_start']);
echo " </p>";
echo " </div>";
echo "</div>";

$i++;
$col_count++;

if ($col_count % 3 == 0 or $i >= $img_count) {
echo "</div>";
}
}
?>

<nav aria-label="page" id="pagination" class="d-md-none mb-0">
<?php include('views/pagination.php'); ?>
</nav>

+ 0
- 39
templates/webpanel/views/capture.php Переглянути файл

@@ -1,39 +0,0 @@
<link rel="stylesheet" type="text/css" href="css/captures.css">

<?php
$col_count=0;
$i = 0;
$img_count = count($enhancements);

foreach ($enhancements as $enhancement) {
if ($col_count % 3 == 0) {
echo "<div class=\"card-group capture-image-cards\">";
}

# build image path and enhancement text
$img_path = "/images/" . $path . $enhancement;
$thumb_path = "/images/thumb/" . $path . $enhancement;
$enhancement_text = "Unknown";
preg_match("/-(.*).jpg/", $enhancement, $m);
if (isset($m[1])) {
$enhancement_text = $m[1];
}

// output image and details, with link to respective enhancement images
echo "<div class=\"card bg-light m-2 p-2 image-card\">";
echo " <a href=\"" . $img_path . "\"><img class=\"card-img-top\" src=\"" . $thumb_path . "\" alt=\"img\"></a>";
echo " <div class=\"card-body\">";
echo " <p class=\"card-text\">";
echo " <strong>Enhancement: </strong>" . $enhancement_text;
echo " </p>";
echo " </div>";
echo "</div>";

$i++;
$col_count++;

if ($col_count % 3 == 0 or $i >= $img_count) {
echo "</div>";
}
}
?>

+ 0
- 14
templates/webpanel/views/footer.php Переглянути файл

@@ -1,14 +0,0 @@
</div>

<footer class="footer text-center">
<div class="contaienr">
<a href="https://github.com/reynico/raspberry-noaa"><img class="img-footer" src="assets/web_img/logo-small.png"></a>
</div>
</footer>

<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script>
</body>
</html>

+ 0
- 47
templates/webpanel/views/header.php Переглянути файл

@@ -1,47 +0,0 @@
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$page = basename($_SERVER['PHP_SELF']);
$configs = include('config.php');
date_default_timezone_set($configs->timezone);
$lang = $configs->lang;
include_once('i18n/' . $lang . '.php');
?>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">

<link rel="stylesheet" type="text/css" href="css/header.css">
<link rel="stylesheet" type="text/css" href="css/footer.css">

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<title>Raspberry NOAA V2</title>

<link rel="shortcut icon" href="assets/web_img/favicon.ico" type="image/x-icon"/>
</head>
<body>
<header class="mb-3">
<div class="navbar navbar-expand navbar-dark bg-dark">
<ul class="navbar-nav mr-auto">
<li class="nav-item <?php if($page == 'index.php'){ echo 'active'; }?>">
<a class="nav-link" href="index.php"><?php echo $lang['passes']; ?></a>
</li>
<li class="nav-item <?php if($page == 'captures.php' or $page == 'capture.php'){ echo 'active'; }?>">
<a class="nav-link" href="captures.php"><?php echo $lang['captures']; ?></a>
</li>
</ul>
<span class="navbar-text timezone">
<em>
<?php echo $configs->timezone; ?><br>
(UTC<?php echo date('P'); ?>)
</em>
</span>
</div>
</header>
<div class="container">

+ 0
- 17
templates/webpanel/views/pagination.php Переглянути файл

@@ -1,17 +0,0 @@
<nav aria-label="page" id="pagination" class="mb-0">
<ul class="pagination pagination-sm justify-content-center mb-0 mx-2">
<li class="page-item<?php if ($page <= 1) { echo " disabled"; } ?>">
<a class="page-link" href="<?php echo "?page=" . ($page-1); ?>" aria-label="<?php echo $lang['prev']; ?>">
<span aria-hiden="true">&laquo;</span>
<span><?php echo $lang['prev']; ?></span>
</a>
</li>

<li class="page-item<?php if ($page >= $page_count) { echo " disabled"; } ?>">
<a class="page-link" href="<?php echo "?page=" . ($page+1); ?>" aria-label="<?php echo $lang['next']; ?>">
<span><?php echo $lang['next']; ?></span>
<span aria-hiden="true">&raquo;</span>
</a>
</li>
</ul>
</nav>

+ 0
- 41
templates/webpanel/views/pass_list.php Переглянути файл

@@ -1,41 +0,0 @@
<link rel="stylesheet" type="text/css" href="css/pass_list.css">

<table class="table table-bordered table-sm table-striped" id="passes">
<thead class="thead-dark">
<tr class="text-center">
<th scope="col"><?php echo $lang['satellite']; ?></th>
<th scope="col"><?php echo $lang['pass_start']; ?></th>
<th scope="col"><?php echo $lang['pass_end']; ?></th>
<th scope="col"><?php echo $lang['max_elev']; ?></th>
</tr>
</thead>
<tbody>
<?php
$now = date('H:i:s', time());

# account for no passes currently scheduled
if (count($passes) <= 0) {
echo "<tr><td colspan=\"4\" class=\"no-passes\">0 " . $lang['passes'] . "</td></tr>";
} else {
foreach ($passes as $pass) {
$pass_start = date('H:i:s', $pass['pass_start']);
$pass_end = date('H:i:s', $pass['pass_end']);

# gray out anything that has already run or did not run because there
# was another overlapping capture but is now in the past
if ($pass['is_active'] == false or $pass_end < $now) {
echo "<tr class='inactive'>";
} else {
echo "<tr>";
}

echo "<td scope=\"row\">". $pass['sat_name'] ."</td>";
echo "<td scope=\"row\" class=\"text-center\">" . $pass_start ."</td>";
echo "<td scope=\"row\" class=\"text-center\">" . $pass_end . "</td>";
echo "<td scope=\"row\" class=\"text-center\">" . $pass['max_elev'] ."&#176;</td>";
echo "</tr>";
}
}
?>
</tbody>
</table>

Завантаження…
Відмінити
Зберегти