This commit is contained in:
Stefan Schwarz 2020-08-15 16:34:23 +02:00
parent 09a3f096c7
commit 288f193754
7 changed files with 53 additions and 17 deletions

1
Cargo.lock generated
View file

@ -1060,6 +1060,7 @@ dependencies = [
"askama_tide",
"async-std",
"chrono",
"serde",
"sqlx",
"tide",
]

View file

@ -6,11 +6,12 @@ edition = "2018"
[dependencies]
anyhow = "1.0"
argh = "0.1.3"
argh = "0.1"
askama_tide = "0.10"
askama = { version = "0.10", features = ["with-tide"]}
async-std = { version = "1.6", features = ["attributes"] }
chrono = "0.4"
serde = "1.0"
sqlx = { version = "0.4.0-beta.1", features = ["mysql", "chrono", "macros"] }
tide = "0.13"

View file

@ -4,9 +4,10 @@ use std::net::IpAddr;
type QueryAs<'q, T> =
sqlx::query::QueryAs<'q, sqlx::MySql, T, <sqlx::MySql as HasArguments<'q>>::Arguments>;
type Query<'q> = sqlx::query::Query<'q, sqlx::MySql, <sqlx::MySql as HasArguments<'q>>::Arguments>;
#[derive(sqlx::FromRow, Debug)]
pub struct Entry {
pub struct Device {
pub id: i32,
pub macaddr: String,
pub nickname: String,
@ -26,7 +27,7 @@ pub enum PrivacyLevel {
DontLog = 4,
}
impl<'q> Entry {
impl<'q> Device {
pub fn all() -> QueryAs<'q, Self> {
sqlx::query_as("SELECT * FROM mac_to_nick")
}
@ -34,21 +35,37 @@ impl<'q> Entry {
pub fn for_user(user: &'q str) -> QueryAs<'q, Self> {
sqlx::query_as(
"
SELECT
SELECT DISTINCT
mtn.*,
IF(al.iplong != NULL, TRUE, FALSE) present
IF(al.iplong, TRUE, FALSE) present
FROM
mac_to_nick mtn,
mac_to_nick mtn
LEFT JOIN
alive_hosts al
ON
mtn.macaddr = al.macaddr
AND al.erfda > NOW() - INTERVAL 24 DAY
WHERE
al.macaddr = mtn.macaddr
AND nickname = ?
GROUP BY
mtn.macaddr
nickname = ?
ORDER BY
al.erfda DESC
",
)
.bind(user)
}
pub fn register(mac: &'q str, user: &'q str) -> Query<'q> {
sqlx::query(
"
INSERT
INTO mac_to_nick
(macaddr, nickname, descr, privacy, created)
VALUES
(?, ?, ?, ?, NOW())
",
)
.bind(mac)
}
}
impl PrivacyLevel {
@ -79,11 +96,14 @@ SELECT DISTINCT
al.macaddr macaddr,
al.iplong iplong
FROM
alive_hosts al,
alive_hosts al
NATURAL LEFT JOIN
mac_to_nick mtn
WHERE
mtn.nickname IS NULL
AND al.erfda > NOW() - INTERVAL 24 DAY
ORDER BY
al.erfda DESC
",
)
}

View file

@ -37,6 +37,7 @@ async fn main() -> Result<(), io::Error> {
let mut app = tide::with_state(State { pool });
app.at("/").get(routes::index);
app.at("/register").post(routes::register);
app.at("/healthz").get(routes::healthz);
app.at("/static").serve_dir("static/")?;

View file

@ -1,12 +1,15 @@
use crate::db;
use crate::templates;
use tide::prelude::*;
const USER: &str = "foosinn";
pub async fn healthz(_request: crate::Request) -> tide::Result {
Ok("ok".into())
}
pub async fn index(request: crate::Request) -> tide::Result {
let my = db::Entry::for_user("foosinn")
let my = db::Device::for_user(USER)
.fetch_all(&request.state().pool)
.await
.map_err(|err| dbg!(err))?;
@ -16,3 +19,13 @@ pub async fn index(request: crate::Request) -> tide::Result {
.map_err(|err| dbg!(err))?;
Ok(templates::IndexTemplate::new(my, unassinged).into())
}
#[derive(Deserialize)]
struct RegisterForm {
macaddr: String,
}
pub async fn register(mut request: crate::Request) -> tide::Result {
let form: RegisterForm = request.body_form().await?;
unimplemented!();
}

View file

@ -4,12 +4,12 @@ use askama::Template;
#[derive(Template, Default)]
#[template(path = "index.html")]
pub struct IndexTemplate {
my: Vec<db::Entry>,
my: Vec<db::Device>,
unassinged: Vec<db::AliveDevice>,
}
impl IndexTemplate {
pub fn new(my: Vec<db::Entry>, unassinged: Vec<db::AliveDevice>) -> Self {
pub fn new(my: Vec<db::Device>, unassinged: Vec<db::AliveDevice>) -> Self {
Self { my, unassinged }
}
}

View file

@ -19,8 +19,8 @@
<div class="p-2">
<h2 class="underline">Your Devices:</h2>
{% for device in my %}
<div class="grid grid-cols-3 grid-gap-1 p-1">
<div class="font-mono">{{ device.macaddr }}</div>
<div class="grid grid-cols-3 grid-gap-1">
<div class="font-mono">{{ device.macaddr }} {{ device.present }}</div>
<div>
<input class="focus:shadow-outline border border-gray-300 px-2"
value="{{ device.descr }}"/>
@ -52,7 +52,7 @@
<div class="p-2">
<h2 class="underline">Unregistred Devices:</h2>
{% for device in unassinged %}
<div class="grid grid-cols-4 grid-gap-1 p-1">
<div class="grid grid-cols-4 grid-gap-1 p-2">
<div class="font-mono">{{ device.macaddr }}</div>
<div class="font-mono">{{ device.ip() }}</div>
<div>