work
This commit is contained in:
parent
09a3f096c7
commit
288f193754
7 changed files with 53 additions and 17 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1060,6 +1060,7 @@ dependencies = [
|
||||||
"askama_tide",
|
"askama_tide",
|
||||||
"async-std",
|
"async-std",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"serde",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"tide",
|
"tide",
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,11 +6,12 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
argh = "0.1.3"
|
argh = "0.1"
|
||||||
askama_tide = "0.10"
|
askama_tide = "0.10"
|
||||||
askama = { version = "0.10", features = ["with-tide"]}
|
askama = { version = "0.10", features = ["with-tide"]}
|
||||||
async-std = { version = "1.6", features = ["attributes"] }
|
async-std = { version = "1.6", features = ["attributes"] }
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
|
serde = "1.0"
|
||||||
sqlx = { version = "0.4.0-beta.1", features = ["mysql", "chrono", "macros"] }
|
sqlx = { version = "0.4.0-beta.1", features = ["mysql", "chrono", "macros"] }
|
||||||
tide = "0.13"
|
tide = "0.13"
|
||||||
|
|
||||||
|
|
40
src/db.rs
40
src/db.rs
|
@ -4,9 +4,10 @@ use std::net::IpAddr;
|
||||||
|
|
||||||
type QueryAs<'q, T> =
|
type QueryAs<'q, T> =
|
||||||
sqlx::query::QueryAs<'q, sqlx::MySql, T, <sqlx::MySql as HasArguments<'q>>::Arguments>;
|
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)]
|
#[derive(sqlx::FromRow, Debug)]
|
||||||
pub struct Entry {
|
pub struct Device {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub macaddr: String,
|
pub macaddr: String,
|
||||||
pub nickname: String,
|
pub nickname: String,
|
||||||
|
@ -26,7 +27,7 @@ pub enum PrivacyLevel {
|
||||||
DontLog = 4,
|
DontLog = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'q> Entry {
|
impl<'q> Device {
|
||||||
pub fn all() -> QueryAs<'q, Self> {
|
pub fn all() -> QueryAs<'q, Self> {
|
||||||
sqlx::query_as("SELECT * FROM mac_to_nick")
|
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> {
|
pub fn for_user(user: &'q str) -> QueryAs<'q, Self> {
|
||||||
sqlx::query_as(
|
sqlx::query_as(
|
||||||
"
|
"
|
||||||
SELECT
|
SELECT DISTINCT
|
||||||
mtn.*,
|
mtn.*,
|
||||||
IF(al.iplong != NULL, TRUE, FALSE) present
|
IF(al.iplong, TRUE, FALSE) present
|
||||||
FROM
|
FROM
|
||||||
mac_to_nick mtn,
|
mac_to_nick mtn
|
||||||
|
LEFT JOIN
|
||||||
alive_hosts al
|
alive_hosts al
|
||||||
|
ON
|
||||||
|
mtn.macaddr = al.macaddr
|
||||||
|
AND al.erfda > NOW() - INTERVAL 24 DAY
|
||||||
WHERE
|
WHERE
|
||||||
al.macaddr = mtn.macaddr
|
nickname = ?
|
||||||
AND nickname = ?
|
ORDER BY
|
||||||
GROUP BY
|
al.erfda DESC
|
||||||
mtn.macaddr
|
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.bind(user)
|
.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 {
|
impl PrivacyLevel {
|
||||||
|
@ -79,11 +96,14 @@ SELECT DISTINCT
|
||||||
al.macaddr macaddr,
|
al.macaddr macaddr,
|
||||||
al.iplong iplong
|
al.iplong iplong
|
||||||
FROM
|
FROM
|
||||||
alive_hosts al,
|
alive_hosts al
|
||||||
|
NATURAL LEFT JOIN
|
||||||
mac_to_nick mtn
|
mac_to_nick mtn
|
||||||
WHERE
|
WHERE
|
||||||
mtn.nickname IS NULL
|
mtn.nickname IS NULL
|
||||||
AND al.erfda > NOW() - INTERVAL 24 DAY
|
AND al.erfda > NOW() - INTERVAL 24 DAY
|
||||||
|
ORDER BY
|
||||||
|
al.erfda DESC
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ async fn main() -> Result<(), io::Error> {
|
||||||
|
|
||||||
let mut app = tide::with_state(State { pool });
|
let mut app = tide::with_state(State { pool });
|
||||||
app.at("/").get(routes::index);
|
app.at("/").get(routes::index);
|
||||||
|
app.at("/register").post(routes::register);
|
||||||
app.at("/healthz").get(routes::healthz);
|
app.at("/healthz").get(routes::healthz);
|
||||||
app.at("/static").serve_dir("static/")?;
|
app.at("/static").serve_dir("static/")?;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
use crate::db;
|
use crate::db;
|
||||||
use crate::templates;
|
use crate::templates;
|
||||||
|
use tide::prelude::*;
|
||||||
|
|
||||||
|
const USER: &str = "foosinn";
|
||||||
|
|
||||||
pub async fn healthz(_request: crate::Request) -> tide::Result {
|
pub async fn healthz(_request: crate::Request) -> tide::Result {
|
||||||
Ok("ok".into())
|
Ok("ok".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn index(request: crate::Request) -> tide::Result {
|
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)
|
.fetch_all(&request.state().pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| dbg!(err))?;
|
.map_err(|err| dbg!(err))?;
|
||||||
|
@ -16,3 +19,13 @@ pub async fn index(request: crate::Request) -> tide::Result {
|
||||||
.map_err(|err| dbg!(err))?;
|
.map_err(|err| dbg!(err))?;
|
||||||
Ok(templates::IndexTemplate::new(my, unassinged).into())
|
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!();
|
||||||
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@ use askama::Template;
|
||||||
#[derive(Template, Default)]
|
#[derive(Template, Default)]
|
||||||
#[template(path = "index.html")]
|
#[template(path = "index.html")]
|
||||||
pub struct IndexTemplate {
|
pub struct IndexTemplate {
|
||||||
my: Vec<db::Entry>,
|
my: Vec<db::Device>,
|
||||||
unassinged: Vec<db::AliveDevice>,
|
unassinged: Vec<db::AliveDevice>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IndexTemplate {
|
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 }
|
Self { my, unassinged }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<h2 class="underline">Your Devices:</h2>
|
<h2 class="underline">Your Devices:</h2>
|
||||||
{% for device in my %}
|
{% for device in my %}
|
||||||
<div class="grid grid-cols-3 grid-gap-1 p-1">
|
<div class="grid grid-cols-3 grid-gap-1">
|
||||||
<div class="font-mono">{{ device.macaddr }}</div>
|
<div class="font-mono">{{ device.macaddr }} {{ device.present }}</div>
|
||||||
<div>
|
<div>
|
||||||
<input class="focus:shadow-outline border border-gray-300 px-2"
|
<input class="focus:shadow-outline border border-gray-300 px-2"
|
||||||
value="{{ device.descr }}"/>
|
value="{{ device.descr }}"/>
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<h2 class="underline">Unregistred Devices:</h2>
|
<h2 class="underline">Unregistred Devices:</h2>
|
||||||
{% for device in unassinged %}
|
{% 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.macaddr }}</div>
|
||||||
<div class="font-mono">{{ device.ip() }}</div>
|
<div class="font-mono">{{ device.ip() }}</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue