diff --git a/dist/pvv.sql b/dist/pvv.sql
index 3fc32f0..38cb495 100644
--- a/dist/pvv.sql
+++ b/dist/pvv.sql
@@ -38,15 +38,12 @@ CREATE TABLE "motd" (
INSERT INTO motd (title, content)
VALUES ("MOTD ./dev.sh", "du kan endre motd i admin panelet");
-CREATE TABLE "doors" (
-"name" TEXT PRIMARY KEY,
-"open" BOOLEAN,
-"description" TEXT
+CREATE TABLE "door" (
+"time" INTEGER PRIMARY KEY,
+"open" BOOLEAN
);
-INSERT INTO doors(name, open, description) VALUES
-("koserommet", FALSE, "Døra inn til koserommet på stripa"),
-("terminalrommet", FALSE, "Døra inn til terminalrommet på stripa");
-
+INSERT INTO door (time, open)
+VALUES (0, FALSE);
INSERT INTO users (uname, groups)
diff --git a/dist/pvv_mysql.sql b/dist/pvv_mysql.sql
index 797f4f0..1e327c3 100644
--- a/dist/pvv_mysql.sql
+++ b/dist/pvv_mysql.sql
@@ -40,11 +40,8 @@ INSERT INTO motd (title, content)
VALUES ("MOTD ./dev.sh", "du kan endre motd i admin panelet");
*/
-CREATE TABLE doors (
-`name` VARCHAR(20) PRIMARY KEY,
-`open` BOOLEAN,
-`description` TEXT
+CREATE TABLE door (
+`time` INTEGER PRIMARY KEY,
+`open` BOOLEAN
);
-INSERT INTO doors(name, open, description) VALUES
-("koserommet", FALSE, "Døra inn til koserommet på stripa"),
-("terminalrommet", FALSE, "Døra inn til terminalrommet på stripa");
+INSERT INTO door(time, open) VALUES (0, FALSE);
\ No newline at end of file
diff --git a/dist/sql_config_example.php b/dist/sql_config_example.php
index 99c13c9..af802f3 100644
--- a/dist/sql_config_example.php
+++ b/dist/sql_config_example.php
@@ -3,3 +3,4 @@ $dbDsn = 'sqlite:'.__DIR__.DIRECTORY_SEPARATOR.'pvv.sqlite';
$dbUser = null;
$dbPass = null;
+$doorSensorSecret = "OGJiZTdjZDctMmFkNy00ZjZjLTk3OGItOTA3NzU3ZDM2Yjlm";
\ No newline at end of file
diff --git a/src/pvv/side/door.php b/src/pvv/side/door.php
new file mode 100644
index 0000000..2a868ee
--- /dev/null
+++ b/src/pvv/side/door.php
@@ -0,0 +1,74 @@
+pdo = $pdo;
+ }
+
+ public function getAll() {
+ $query = 'SELECT time, open FROM door ORDER BY time DESC';
+ $statement = $this->pdo->prepare($query);
+ $statement->execute();
+
+ $doorEvents = [];
+ foreach($statement->fetchAll() as $row){
+ $doorEvents[] = [
+ 'time' => (int)$row['time'],
+ 'open' => (bool)$row['open']
+ ];
+ }
+
+ return $doorEvents;
+ }
+
+ public function getEntriesAfter($startTime) {
+ $query = 'SELECT time, open FROM door WHERE time > :startTime ORDER BY time DESC';
+ $statement = $this->pdo->prepare($query);
+ $statement->bindParam(':startTime', $startTime, PDO::PARAM_STR);
+ $statement->execute();
+
+ $doorEvents = [];
+ foreach($statement->fetchAll() as $row){
+ $doorEvents[] = [
+ 'time' => (int)$row['time'],
+ 'open' => (bool)$row['open']
+ ];
+ }
+
+ return $doorEvents;
+ }
+
+ public function getCurrent() {
+ $query = 'SELECT time, open FROM door ORDER BY time DESC LIMIT 1';
+ $statement = $this->pdo->prepare($query);
+ $statement->execute();
+ $row = $statement->fetch();
+ return [
+ 'time' => (int)$row['time'],
+ 'open' => (bool)$row['open']
+ ];
+ }
+
+ private function removeOld() {
+ $firstValidTime = time() - 60*60*24*7; //One week before now
+ $query = 'DELETE FROM door WHERE time < :firstValid';
+ $statement = $this->pdo->prepare($query);
+ $statement->bindParam(':firstValid', $firstValidTime, PDO::PARAM_STR);
+ $statement->execute();
+ }
+
+ public function createEvent($time, $open) {
+ $query = 'INSERT INTO door(time, open) VALUES (:time, :open)';
+ $statement = $this->pdo->prepare($query);
+ $statement->bindParam(':time', $time, PDO::PARAM_STR);
+ $statement->bindParam(':open', $open, PDO::PARAM_STR);
+ $statement->execute();
+
+ $this->removeOld();
+ }
+}
diff --git a/src/pvv/side/doors.php b/src/pvv/side/doors.php
deleted file mode 100644
index ab511ce..0000000
--- a/src/pvv/side/doors.php
+++ /dev/null
@@ -1,79 +0,0 @@
-pdo = $pdo;
- }
-
- public function getAll() {
- $query = 'SELECT name, open, description FROM doors ORDER BY open DESC, name ASC';
- $statement = $this->pdo->prepare($query);
- $statement->execute();
-
- $doors = [];
- foreach($statement->fetchAll() as $row){
- $doors[] = [
- 'name' => $row['name'],
- 'open' => (int)$row['open'],
- 'description' => $row['description'],
- ];
- }
-
- return $doors;
- }
-
- public function getByName($name){
- $query = 'SELECT name, open, description FROM doors WHERE name=:name';
- $statement = $this->pdo->prepare($query);
- $statement->bindParam(':name', $name, PDO::PARAM_STR);
- $statement->execute();
-
- $row = $statement->fetch();
- if (!$row) {
- return false;
- }
-
- return [
- 'name' => $row['name'],
- 'open' => (int)$row['open'],
- 'description' => $row['description'],
- ];
- }
-
- public function setDoorState($name, $open) {
- $query = 'UPDATE doors SET open=:open WHERE name=:name';
- $statement = $this->pdo->prepare($query);
- $statement->bindParam(':name', $name, PDO::PARAM_STR);
- $statement->bindParam(':open', $open, PDO::PARAM_INT);
- $statement->execute();
- }
-
-
- public function createDoor($name, $description) {
- $query = 'INSERT INTO doors(name, open, description) VALUES (:name, TRUE, :desc)';
- $statement = $this->pdo->prepare($query);
- $statement->bindParam(':name', $name, PDO::PARAM_STR);
- $statement->bindParam(':desc', $description, PDO::PARAM_STR);
- $statement->execute();
- }
-
- public function updateDoorDescription($name, $description) {
- $query = 'UPDATE doors SET descriptin=:desc WHERE name=:name';
- $statement = $this->pdo->prepare($query);
- $statement->bindParam(':name', $name, PDO::PARAM_STR);
- $statement->bindParam(':desc', $description, PDO::PARAM_STR);
- $statement->execute();
- }
-
- public function deleteDoor($name) {
- $query = 'DELETE FROM doors WHERE name = :name;';
- $statement = $this->pdo->prepare($query);
- $statement->bindParam(':name', $name, PDO::PARAM_STR);
- $statement->execute();
- }
-}
diff --git a/www/css/style.css b/www/css/style.css
index c1d0f00..33f2541 100644
--- a/www/css/style.css
+++ b/www/css/style.css
@@ -153,6 +153,16 @@ nav #usermenu li:first-child:hover {
background: transparent;
}
+#doorIndicator {
+ border-radius: 5px;
+ padding: 8px 8px;
+ margin: 4px 4px;
+}
+#doorIndicator > p > abbr[title] { text-decoration: none; border-bottom: none; cursor: inherit; }
+.doorIndicator_OPEN { border: 2px solid green; }
+.doorIndicator_CLOSED { border: 2px dotted red; }
+.doorStateMobileOnly { display: none; }
+
@media(max-width: 800px){
nav #menu, nav #menu li.active, nav #menu_toggle, nav #login {
position: absolute;
@@ -226,6 +236,9 @@ nav #usermenu li:first-child:hover {
margin-left: 1em !important;
margin-right: 1em !important;
}
+ .doorStateMobileOnly {
+ display: inline;
+ }
}
body {
@@ -346,3 +359,4 @@ article p {
textarea.boxinput {
resize: vertical;
}
+
diff --git a/www/door/index.php b/www/door/index.php
index 4dfb883..76c81b9 100644
--- a/www/door/index.php
+++ b/www/door/index.php
@@ -1,49 +1,73 @@
getByName($_GET["name"]);
- if (!$out) {
- echo '{"error": true, "reason": "not found"}';
- http_response_code(404);
- exit();
+$door = new \pvv\side\Door($pdo);
+
+if($_SERVER['REQUEST_METHOD'] === 'POST') {
+ if (isset($_SERVER["HTTP_AUTHORIZATION"])) {
+ list($type, $data) = explode(" ", $_SERVER["HTTP_AUTHORIZATION"], 2);
+ if (strcasecmp($type, "Bearer") == 0) {
+ if (hash_equals($data, $doorSensorSecret)) {
+ handleSetState();
+ } else {
+ echo '{"status": "error", "message": "Invalid authentication key"}';
+ die();
+ }
+ } else {
+ echo '{"status": "error", "message": "Invalid authentication method"}';
+ die();
}
+ } else {
+ echo '{"status": "error", "message": "Missing authentication"}';
+ die();
}
- else {
- $out = $doors->getAll();
- }
-}
-elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
- if (isset($_POST["name"]) and isset($_POST["open"]) ) {
- $out = $doors->setDoorState($_POST["name"], (strtolower($_POST["open"])==="true")?1:0);
-
- $out = $doors->getByName($_POST["name"]);
- if (!$out) {
- echo '{"error": true, "reason": "not found"}';
- http_response_code(404);
- exit();
+} elseif ($_SERVER['REQUEST_METHOD'] === 'GET') {
+
+ if (isset($_GET["period"])) {
+ $period = (string)htmlspecialchars($_GET["period"]);
+ if ($period == "day") {
+ $startTime = time() - (60*60*24);
+ } else if ($period == "week") {
+ $startTime = time() - (60*60*24*7);
+ } else {
+ echo '{"status": "error", "message": "Invalid period"}';
+ die();
}
- }
- else {
- echo '{"error": true, "reason": "missing either \"name\" or \"open\" argument"}';
- http_response_code(404);
- exit();
+
+ $lines = $door->getEntriesAfter($startTime);
+ echo json_encode([
+ 'status' => "OK",
+ 'entries' => $lines
+ ]);
+ } else {
+ //Only last entry
+ $line = (object)$door->getCurrent();
+ echo json_encode([
+ 'status' => "OK",
+ 'time' => $line->time,
+ 'open' => $line->open
+ ]);
}
}
-function utf8ize($d) {
- if (is_array($d)) {
- foreach ($d as $k => $v) {
- $d[$k] = utf8ize($v);
- }
- } else if (is_string ($d)) {
- return utf8_encode($d);
- }
- return $d;
-}
-echo json_encode(utf8ize($out));
+function handleSetState() {
+ global $door;
+
+ $jsonobj = file_get_contents('php://input');
+ $event = json_decode($jsonobj);
+
+ if ((!isset($event->time)) || (!is_numeric($event->time))) {
+ echo '{"status": "error", "message": "Invalid timestamp"}';
+ die();
+ }
+ if ((!isset($event->isDoorOpen)) || (!is_bool($event->isDoorOpen))) {
+ echo '{"status": "error", "message": "Invalid door state"}';
+ die();
+ }
+
+ $door->createEvent((int)($event->time), (bool)($event->isDoorOpen));
+ echo '{"status": "OK"}';
+}
\ No newline at end of file
diff --git a/www/index.php b/www/index.php
index a73c7a8..4822a2b 100644
--- a/www/index.php
+++ b/www/index.php
@@ -7,6 +7,12 @@ $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$motdfetcher = new \pvv\side\MOTD($pdo);
$motd = $motdfetcher->getMOTD();
+
+$door = new \pvv\side\Door($pdo);
+$doorEntry = (object)($door->getCurrent());
+$isDoorOpen = $doorEntry->open;
+if (date("Y-m-d") == date("Y-m-d", $doorEntry->time)) { $doorTime = date("H:i", $doorEntry->time);
+} else { $doorTime = date("H:i d/m", $doorEntry->time);}
?>
@@ -63,6 +69,10 @@ $motd = $motdfetcher->getMOTD();
Døren er åpen.
+(Oppdatert )
+