Adding click statistics

closes #2
This commit is contained in:
Dietrich 2021-02-09 21:30:11 +01:00
parent 32a2151ba0
commit d3465b4e10
Signed by: dietrich
GPG Key ID: 9F3C20C0F85DF67C
6 changed files with 96 additions and 8 deletions

View File

@ -0,0 +1,3 @@
-- This file should undo anything in `up.sql`
DROP TABLE clicks;

View File

@ -0,0 +1,13 @@
-- Your SQL goes here
CREATE TABLE clicks
(
id INTEGER PRIMARY KEY NOT NULL,
link INT NOT NULL,
created_at TIMESTAMP NOT NULL,
FOREIGN KEY
(link)
REFERENCES links
(id)
);

View File

@ -1,6 +1,6 @@
use crate::{forms::LinkForm, ServerError};
use super::schema::{links, users};
use super::schema::{clicks, links, users};
use argonautica::Hasher;
use diesel::{Insertable, Queryable};
use dotenv::dotenv;
@ -89,3 +89,31 @@ impl NewLink {
}
}
}
#[derive(Serialize, Debug, Queryable)]
pub struct Click {
pub id: i32,
pub link: i32,
pub created_at: chrono::NaiveDateTime,
}
#[derive(Serialize, Insertable)]
#[table_name = "clicks"]
pub struct NewClick {
pub link: i32,
pub created_at: chrono::NaiveDateTime,
}
impl NewClick {
pub fn new(link_id: i32) -> Self {
Self {
link: link_id,
created_at: chrono::Local::now().naive_utc(),
}
}
}
#[derive(Serialize, Debug, Queryable)]
pub struct Count {
count: i32,
}

View File

@ -1,3 +1,11 @@
table! {
clicks (id) {
id -> Integer,
link -> Integer,
created_at -> Timestamp,
}
}
table! {
links (id) {
id -> Integer,
@ -18,6 +26,7 @@ table! {
}
}
joinable!(clicks -> links (link));
joinable!(links -> users (author));
allow_tables_to_appear_in_same_query!(links, users,);
allow_tables_to_appear_in_same_query!(clicks, links, users,);

View File

@ -1,6 +1,5 @@
use std::time::SystemTime;
use crate::ServerError;
use actix_identity::Identity;
use actix_web::{
http::header::{CacheControl, CacheDirective, ContentType, Expires},
@ -14,7 +13,8 @@ use qrcode::{render::svg, QrCode};
use tera::{Context, Tera};
use super::forms::LinkForm;
use super::models::{Link, LoginUser, NewLink, NewUser, User};
use super::models::{Count, Link, LoginUser, NewClick, NewLink, NewUser, User};
use crate::ServerError;
fn establish_connection() -> Result<SqliteConnection, ServerError> {
dotenv().ok();
@ -49,11 +49,30 @@ pub(crate) async fn index(
tera: web::Data<Tera>,
id: Identity,
) -> Result<HttpResponse, ServerError> {
use super::schema::links::dsl::links;
use super::schema::users::dsl::users;
use super::schema::clicks;
use super::schema::links;
use super::schema::users;
if let Some(id) = id.identity() {
let connection = establish_connection()?;
let all_links: Vec<(Link, User)> = links.inner_join(users).load(&connection)?;
let query = links::dsl::links
.inner_join(users::dsl::users)
.left_join(clicks::dsl::clicks)
.group_by(links::id)
.select((
(
links::id,
links::title,
links::target,
links::code,
links::author,
links::created_at,
),
(users::id, users::username, users::email, users::password),
(diesel::dsl::sql::<diesel::sql_types::Integer>(
"COUNT(clicks.id)",
),),
));
let all_links: Vec<(Link, User, Count)> = query.load(&connection)?;
let mut data = Context::new();
data.insert("name", &id);
@ -367,7 +386,16 @@ pub(crate) async fn redirect(
let link = links.filter(code.eq(&data.0)).first::<Link>(&connection);
match link {
Ok(link) => Ok(redirect_builder(&link.target)),
Ok(link) => {
use super::schema::clicks;
let new_click = NewClick::new(link.id);
let connection = establish_connection()?;
diesel::insert_into(clicks::table)
.values(&new_click)
.execute(&connection)?;
Ok(redirect_builder(&link.target))
}
Err(NotFound) => {
let mut data = Context::new();
data.insert("title", "Wurde gelöscht");

View File

@ -19,10 +19,14 @@
<th>
Benutzername
</th>
<th>
Statistik
</th>
</tr>
{% for links_user in links_per_users %}
{% set l = links_user[0] %}
{% set u = links_user[1] %}
{% set c = links_user[2] %}
<tr>
<td>
<a href="/admin/view/link/{{l.code}}"><span>{{l.code}}</span>
@ -37,6 +41,9 @@
<a href="/admin/view/profile/{{u.id}}"><small>{{ u.username }}</small>
</a>
</td>
<td>
{{ c.count }}
</td>
</tr>
{% endfor %}
</table>