init medias folder
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,7 +9,6 @@ Cargo.lock
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
/medias
|
||||
persistence-db
|
||||
tmp/*
|
||||
static/sourcefiles/
|
||||
|
||||
@@ -14,8 +14,8 @@ services:
|
||||
- MODE_INSTALL=DEV # DEV, PROD
|
||||
- RUST_BACKTRACE=1
|
||||
- TMPDIR=/usr/src/myapp/tmp
|
||||
- GOOGLE_CLIENT_ID=723424966880-015kn0qncavlgbj4j3k1ggs3arn7tdkd.apps.googleusercontent.com
|
||||
- GOOGLE_CLIENT_SECRET=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
|
||||
- GOOGLE_CLIENT_ID=1041713159432-vad6qp7ce7p9iid9qjdiopi7n6ajvmtv.apps.googleusercontent.com
|
||||
- GOOGLE_CLIENT_SECRET=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
|
||||
depends_on:
|
||||
- dr_who_website-db
|
||||
labels:
|
||||
|
||||
26
k-9_url
26
k-9_url
@@ -1,26 +0,0 @@
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e1-regeneration/54d111ea69702d0707150800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e2-liberation/54d1122969702d04c9700800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e3-the-korven/54d1124369702d04ca100800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e4-the-bounty-hunter/54d1127e69702d04c9740800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e5-sirens-of-ceres/54d1129669702d07071c0800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e6-fear-itself/54d113a069702d04c9830800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e7-the-fall-of-the-house-of-gryffen/54d1142f69702d04c98b0800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e8-jaws-of-orthrus/54d1144169702d07072f0800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e9-dream-eaters/54d1145769702d04c98d0800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e10-curse-of-anubis/54d1146969702d04c9910800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e11-oroborus/54d1147c69702d04ca2c0800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e12-alien-avatar/54d1148e69702d04ca2f0800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e13-aeolian/54d114ac69702d0707380800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e14-the-last-oak-tree/54d114c069702d04ca390800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e15-black-hunger/54d114e769702d04c99a0800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e16-the-cambridge-spy/54d1151269702d04ca3e0800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e17-lost-library-of-ukko/54d1152469702d04c99f0800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e18-mutant-copper/54d1153769702d0707420800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e19-the-custodians/54d1154969702d04c9a40800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e20-taphony-and-the-time-loop/54d1155c69702d04ca450800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e21-robot-gladiators/54d1157069702d0707460800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e22-mind-snap/54d1158469702d0707490800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e23-angel-of-the-north/54d115a669702d07074c0800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e24-the-last-precinct/54d115bb69702d04c9ac0800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e25-hound-of-the-korven/54d115cf69702d04ca4a0800
|
||||
youtube-dl https://www.shoutfactorytv.com/k-9/k-9-s1-e26-the-eclipse-of-the-korven/54d115e969702d04c9ae0800
|
||||
0
medias/DB/bd
Normal file
0
medias/DB/bd
Normal file
0
medias/Podcast/podcast
Normal file
0
medias/Podcast/podcast
Normal file
0
medias/Romans/romans
Normal file
0
medias/Romans/romans
Normal file
0
medias/Series/Class/class
Normal file
0
medias/Series/Class/class
Normal file
0
medias/Series/DrWho Classic/drwhoclassic
Normal file
0
medias/Series/DrWho Classic/drwhoclassic
Normal file
0
medias/Series/DrWho/drwho
Normal file
0
medias/Series/DrWho/drwho
Normal file
0
medias/Series/K-9/k9
Normal file
0
medias/Series/K-9/k9
Normal file
0
medias/Series/Torchwood/torchwood
Normal file
0
medias/Series/Torchwood/torchwood
Normal file
@@ -7,7 +7,5 @@ create table users(
|
||||
email VARCHAR(255) NOT NULL DEFAULT '',
|
||||
google VARCHAR(255) NOT NULL DEFAULT '',
|
||||
email_valid VARCHAR(255) NOT NULL DEFAULT '',
|
||||
data VARCHAR(255) NOT NULL DEFAULT ''
|
||||
data TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
|
||||
insert into users(username, password, salt) values ('adminkey', '', '');
|
||||
|
||||
76
src/main.rs
76
src/main.rs
@@ -25,7 +25,7 @@ use diesel::prelude::*;
|
||||
pub mod schema;
|
||||
use schema::users;
|
||||
pub mod models;
|
||||
use models::{User, Project, Entity};
|
||||
use models::{User};
|
||||
|
||||
use walkdir::{DirEntry, WalkDir};
|
||||
|
||||
@@ -44,48 +44,6 @@ use uuid::Uuid;
|
||||
use std::fs::File;
|
||||
use std::io::{self, prelude::*, BufReader};
|
||||
|
||||
struct Ws {}
|
||||
|
||||
impl Actor for Ws {
|
||||
type Context = ws::WebsocketContext<Self>;
|
||||
|
||||
fn started(&mut self, ctx: &mut Self::Context) {}
|
||||
}
|
||||
|
||||
/// Handler for ws::Message message
|
||||
impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for Ws {
|
||||
fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {
|
||||
match msg {
|
||||
Ok(ws::Message::Ping(msg)) => {
|
||||
println!("msg: {:?}", msg);
|
||||
ctx.pong(&msg)
|
||||
}
|
||||
Ok(ws::Message::Text(text)) => {
|
||||
// println!("text: {:?}", text);
|
||||
// ctx.text(text);
|
||||
let str = &text.to_string();
|
||||
if str == &"Coucou le serveur !".to_string() {
|
||||
// println!("text: {:?}", str);
|
||||
// println!("user: {:?}", User::find(1).unwrap());
|
||||
return ctx.text(text);
|
||||
}
|
||||
ctx.text(text)
|
||||
}
|
||||
Ok(ws::Message::Binary(bin)) => {
|
||||
println!("bin: {:?}", bin);
|
||||
ctx.binary(bin)
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/ws")]
|
||||
async fn websocket(req: HttpRequest, stream: web::Payload) -> impl Responder {
|
||||
let resp = ws::start(Ws {}, &req, stream);
|
||||
// println!("{:#?}", &ws);
|
||||
resp
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
async fn index(tmpl: Data<Tera>, id: Identity) -> impl Responder {
|
||||
@@ -95,19 +53,30 @@ async fn index(tmpl: Data<Tera>, id: Identity) -> impl Responder {
|
||||
let user_session = result_user.unwrap();
|
||||
context.insert("user", &user_session);
|
||||
}
|
||||
let projects = Project::find_by_public(true).unwrap();
|
||||
let mut projects_json = Vec::<serde_json::Value>::new();
|
||||
for project in projects {
|
||||
projects_json.push(project.to_json());
|
||||
}
|
||||
context.insert("projects_json",&projects_json);
|
||||
response::template(tmpl, "index.html.twig", &context)
|
||||
}
|
||||
|
||||
#[get("/home")]
|
||||
async fn home(tmpl: Data<Tera>, id: Identity) -> impl Responder {
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct ParamsMedias {
|
||||
q: String,
|
||||
}
|
||||
|
||||
#[get("/medias")]
|
||||
async fn medias(req: HttpRequest, tmpl: Data<Tera>, id: Identity) -> impl Responder {
|
||||
let mut context = Context::new();
|
||||
response::template(tmpl, "home.html.twig", &context)
|
||||
let result_user = get_user_session(&id);
|
||||
if !result_user.is_err() {
|
||||
let user_session = result_user.unwrap();
|
||||
context.insert("user", &user_session);
|
||||
}
|
||||
let params_result = web::Query::<ParamsMedias>::from_query(req.query_string());
|
||||
if params_result.is_err() {
|
||||
return response::redirect("/");
|
||||
}
|
||||
let params = params_result.unwrap();
|
||||
context.insert("path", ¶ms.q);
|
||||
response::template(tmpl, "medias.html.twig", &context)
|
||||
}
|
||||
|
||||
async fn not_found(req: HttpRequest, tmpl: Data<Tera>, id: Identity) -> impl Responder {
|
||||
@@ -130,6 +99,7 @@ async fn main() -> std::io::Result<()> {
|
||||
))
|
||||
.wrap(middleware::Logger::default())
|
||||
.service(index)
|
||||
.service(medias)
|
||||
.service(user_controller::login)
|
||||
.service(user_controller::post_login)
|
||||
.service(user_controller::post_auth)
|
||||
@@ -148,8 +118,6 @@ async fn main() -> std::io::Result<()> {
|
||||
.service(user_controller::profile_post)
|
||||
.service(user_controller::delete)
|
||||
.service(user_controller::user_deleted)
|
||||
.service(websocket)
|
||||
.service(home)
|
||||
.service(Files::new("/static", folder_static))
|
||||
.default_service(web::route().to(not_found))
|
||||
})
|
||||
|
||||
33
src/media_controller.rs
Normal file
33
src/media_controller.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
#![allow(unused)]
|
||||
use actix_files::{Files, NamedFile};
|
||||
use actix_form_data::{Error, Field};
|
||||
use actix_identity::Identity;
|
||||
use actix_identity::{CookieIdentityPolicy, IdentityService};
|
||||
use actix_multipart::Multipart;
|
||||
use actix_web::{
|
||||
cookie::Cookie, get, http, middleware, post, web, web::Data, web::Form, web::Path as Pathweb,
|
||||
App, HttpRequest, HttpResponse, HttpServer, Responder,
|
||||
};
|
||||
|
||||
use lettre::transport::smtp::commands::Mail;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::format;
|
||||
use std::{fs::*, string};
|
||||
use std::path::*;
|
||||
use std::sync::mpsc::Sender;
|
||||
use tera::{Context, Tera};
|
||||
|
||||
use super::models::User;
|
||||
use diesel::prelude::*;
|
||||
|
||||
use walkdir::{DirEntry, WalkDir};
|
||||
use serde_json::{json, Serializer, Value};
|
||||
|
||||
use super::response;
|
||||
use super::util::*;
|
||||
|
||||
use futures_util::TryStreamExt as _;
|
||||
use std::io::Write;
|
||||
use tempfile::tempfile;
|
||||
use uuid::Uuid;
|
||||
564
src/models.rs
564
src/models.rs
@@ -23,6 +23,7 @@ pub struct User {
|
||||
pub email: String,
|
||||
pub google: String,
|
||||
pub email_valid: String,
|
||||
pub data: String
|
||||
}
|
||||
|
||||
impl User {
|
||||
@@ -63,6 +64,7 @@ impl User {
|
||||
users::dsl::email_valid.eq(uuid),
|
||||
users::dsl::email.eq(email),
|
||||
users::dsl::google.eq("".to_string()),
|
||||
users::dsl::data.eq("{}".to_string()),
|
||||
))
|
||||
.get_result(&db());
|
||||
if !result.is_err() {
|
||||
@@ -84,7 +86,7 @@ impl User {
|
||||
}
|
||||
|
||||
pub fn find_all() -> Result<Vec<Self>, String> {
|
||||
let result = users::dsl::users.get_results::<User>(&db());
|
||||
let result = users::dsl::users.get_results::<Self>(&db());
|
||||
if !result.is_err() {
|
||||
let users = result.unwrap();
|
||||
return Ok(users);
|
||||
@@ -196,36 +198,9 @@ impl User {
|
||||
self.salt = sha256::digest(y.to_string())
|
||||
}
|
||||
|
||||
pub fn get_projects(&self) -> Result<Vec<Project>, String> {
|
||||
let result = projects::dsl::projects
|
||||
.filter(projects::dsl::creator_id.eq(&self.id))
|
||||
.get_results::<Project>(&db());
|
||||
if !result.is_err() {
|
||||
let projects = result.unwrap();
|
||||
return Ok(projects);
|
||||
}
|
||||
Err(format!("Project {} not fetched", self.id))
|
||||
}
|
||||
|
||||
pub fn get_project_accesss(&self) -> Result<Vec<ProjectAccess>, String> {
|
||||
let result = project_accesss::dsl::project_accesss
|
||||
.filter(project_accesss::dsl::user_id.eq(&self.id))
|
||||
.get_results::<ProjectAccess>(&db());
|
||||
if !result.is_err() {
|
||||
let project_accesss = result.unwrap();
|
||||
return Ok(project_accesss);
|
||||
}
|
||||
Err(format!("ProjectAccesss {} not fetched", self.id))
|
||||
}
|
||||
|
||||
pub fn delete(self) -> Result<String, String> {
|
||||
let id = self.id.clone();
|
||||
let name = self.username.clone();
|
||||
let result_projects = self.get_projects();
|
||||
let projects = result_projects.unwrap();
|
||||
for project in projects {
|
||||
project.delete();
|
||||
}
|
||||
let filter_user = users::dsl::users.filter(users::dsl::id.eq(&id));
|
||||
let result_del_user = diesel::delete(filter_user)
|
||||
.returning(users::dsl::username)
|
||||
@@ -238,539 +213,6 @@ impl User {
|
||||
|
||||
pub fn to_json(self) -> Value {
|
||||
let mut user_value = json!(self);
|
||||
let project_accesss = self.get_project_accesss().unwrap();
|
||||
let mut project_accesss_json = Vec::new();
|
||||
for project_access in project_accesss {
|
||||
project_accesss_json.push(project_access.to_json());
|
||||
}
|
||||
user_value["project_accesss"] = json!(project_accesss_json);
|
||||
user_value["projects"] = json!(self.get_projects().unwrap());
|
||||
user_value
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Queryable, Identifiable, Insertable, serde::Serialize)]
|
||||
pub struct Project {
|
||||
pub id: i32,
|
||||
pub creator_id: i32,
|
||||
pub uuid: String,
|
||||
pub name: String,
|
||||
pub password: String,
|
||||
pub time_limit: SystemTime,
|
||||
pub premium: i32,
|
||||
pub is_public: bool,
|
||||
pub image: String,
|
||||
pub origin_filename: String,
|
||||
pub description: String,
|
||||
pub data: String,
|
||||
}
|
||||
impl Project {
|
||||
const FREE: i32 = 0;
|
||||
const PAID: i32 = 1;
|
||||
|
||||
pub fn create(
|
||||
name: String,
|
||||
origin_filename: String,
|
||||
password: String,
|
||||
user: &User,
|
||||
) -> Result<Self, String> {
|
||||
let result = diesel::insert_into(projects::table)
|
||||
.values((
|
||||
projects::dsl::origin_filename.eq(origin_filename),
|
||||
projects::dsl::creator_id.eq(user.id),
|
||||
projects::dsl::uuid.eq(Uuid::new_v4().to_string()),
|
||||
projects::dsl::name.eq(name),
|
||||
projects::dsl::password.eq(password),
|
||||
projects::dsl::time_limit
|
||||
.eq(SystemTime::now() + Duration::new(60 * 60 * 24 * 5, 0)), // calcul pour 5 jour en seconde
|
||||
projects::dsl::premium.eq(Project::FREE),
|
||||
projects::dsl::is_public.eq(true),
|
||||
projects::dsl::description.eq("".to_string()),
|
||||
projects::dsl::data.eq("{}".to_string()),
|
||||
))
|
||||
.get_result(&db());
|
||||
if !result.is_err() {
|
||||
let project = result.unwrap();
|
||||
return Ok(project);
|
||||
}
|
||||
Err(format!("Project not created"))
|
||||
}
|
||||
|
||||
pub fn find(id: i32) -> Result<Self, String> {
|
||||
let result = projects::dsl::projects
|
||||
.filter(projects::dsl::id.eq(id))
|
||||
.get_result::<Self>(&db());
|
||||
if !result.is_err() {
|
||||
let project = result.unwrap();
|
||||
return Ok(project);
|
||||
}
|
||||
Err(format!("User {} not found", id))
|
||||
}
|
||||
|
||||
pub fn find_by_uuid(uuid: &str) -> Result<Self, String> {
|
||||
let result = projects::dsl::projects
|
||||
.filter(projects::dsl::uuid.eq(&uuid))
|
||||
.get_result::<Self>(&db());
|
||||
if !result.is_err() {
|
||||
let project = result.unwrap();
|
||||
return Ok(project);
|
||||
}
|
||||
Err(format!("Project {} not find", &uuid))
|
||||
}
|
||||
|
||||
pub fn find_by_public(is_public: bool) -> Result<Vec<Self>, String> {
|
||||
let result = projects::dsl::projects
|
||||
.filter(projects::dsl::is_public.eq(&is_public))
|
||||
.get_results::<Project>(&db());
|
||||
if !result.is_err() {
|
||||
let projects = result.unwrap();
|
||||
return Ok(projects);
|
||||
}
|
||||
Err(format!("User {} not found", &is_public))
|
||||
}
|
||||
|
||||
pub fn update(self) -> Result<Self, String> {
|
||||
let filter = projects::dsl::projects.filter(projects::dsl::id.eq(self.id));
|
||||
let result = diesel::update(filter)
|
||||
.set((
|
||||
projects::dsl::image.eq(self.image),
|
||||
projects::dsl::origin_filename.eq(self.origin_filename),
|
||||
projects::dsl::creator_id.eq(self.creator_id),
|
||||
projects::dsl::uuid.eq(self.uuid),
|
||||
projects::dsl::name.eq(self.name),
|
||||
projects::dsl::password.eq(self.password),
|
||||
projects::dsl::time_limit.eq(self.time_limit),
|
||||
projects::dsl::premium.eq(self.premium),
|
||||
projects::dsl::is_public.eq(self.is_public),
|
||||
projects::dsl::data.eq(self.data),
|
||||
projects::dsl::description.eq(self.description),
|
||||
))
|
||||
.get_result::<Self>(&db());
|
||||
if !result.is_err() {
|
||||
let project = result.unwrap();
|
||||
return Ok(project);
|
||||
}
|
||||
Err(format!("Project {} not update", self.id))
|
||||
}
|
||||
|
||||
pub fn get_entitys(&self) -> Result<Vec<Entity>, String> {
|
||||
let result = entitys::dsl::entitys
|
||||
.filter(entitys::dsl::project_id.eq(&self.id))
|
||||
.get_results::<Entity>(&db());
|
||||
if !result.is_err() {
|
||||
let entitys = result.unwrap();
|
||||
return Ok(entitys);
|
||||
}
|
||||
Err(format!("Project entitys {} not fetched", self.id))
|
||||
}
|
||||
|
||||
pub fn get_creator(&self) -> Result<User, String> {
|
||||
User::find(self.creator_id)
|
||||
}
|
||||
|
||||
pub fn get_project_accesss(&self) -> Result<Vec<ProjectAccess>, String> {
|
||||
let result = project_accesss::dsl::project_accesss
|
||||
.filter(project_accesss::dsl::project_id.eq(&self.id))
|
||||
.get_results::<ProjectAccess>(&db());
|
||||
if !result.is_err() {
|
||||
let project_accesss = result.unwrap();
|
||||
return Ok(project_accesss);
|
||||
}
|
||||
Err(format!("ProjectAccesss {} not fetched", self.id))
|
||||
}
|
||||
|
||||
pub fn delete(self) -> Result<String, String> {
|
||||
let result_file = std::fs::remove_dir_all(Path::new("medias").join(self.uuid));
|
||||
let filter_entity = entitys::dsl::entitys.filter(entitys::dsl::project_id.eq(&self.id));
|
||||
let result_del_entity = diesel::delete(filter_entity)
|
||||
.returning(entitys::dsl::name)
|
||||
.get_results::<String>(&db());
|
||||
if result_del_entity.is_err() {
|
||||
return Err(format!("Project delete could not remove entity in db()"));
|
||||
}
|
||||
let filter_project = projects::dsl::projects.filter(projects::dsl::id.eq(&self.id));
|
||||
let result_del_project = diesel::delete(filter_project)
|
||||
.returning(projects::dsl::name)
|
||||
.get_result::<String>(&db());
|
||||
if result_del_project.is_err() {
|
||||
return Err(format!("Project delete could not remove project in db()"));
|
||||
}
|
||||
return Ok("Project was deleted".to_string());
|
||||
}
|
||||
|
||||
pub fn get_logs(&self) -> String {
|
||||
let path = Path::new("./medias")
|
||||
.join(self.uuid.clone())
|
||||
.join("cmd_logs.txt");
|
||||
if path.exists() {
|
||||
return String::from_utf8_lossy(&std::fs::read(&path).unwrap()).to_string();
|
||||
}
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
const CONVERTION: i32 = 0;
|
||||
const COMPLETE: i32 = 1;
|
||||
const CRASHED: i32 = 2;
|
||||
|
||||
pub fn get_status(&self) -> i32 {
|
||||
let path = Path::new("./medias")
|
||||
.join(self.uuid.clone())
|
||||
.join("cmd_logs.txt");
|
||||
if path.exists() {
|
||||
let metadata = std::fs::metadata(path).unwrap();
|
||||
let modified_time = metadata.modified().unwrap().elapsed().unwrap().as_secs();
|
||||
// println!("{} > 10", modified_time);
|
||||
if modified_time > 300 {
|
||||
return Project::CRASHED;
|
||||
}
|
||||
return Project::CONVERTION;
|
||||
}
|
||||
Project::COMPLETE
|
||||
}
|
||||
|
||||
pub const ACCESSREAD: i32 = 0;
|
||||
pub const ACCESSWRITE: i32 = 1;
|
||||
|
||||
pub fn test_access(&self, result_user: &Result<User, String>, access_type: i32) -> bool {
|
||||
if access_type == Project::ACCESSREAD && self.is_public {
|
||||
return true;
|
||||
}
|
||||
else if access_type == Project::ACCESSREAD && !result_user.is_err() {
|
||||
let user = result_user.as_ref().unwrap();
|
||||
if user.id == self.creator_id {
|
||||
return true;
|
||||
}
|
||||
let result_pa = ProjectAccess::find(user.id,self.id);
|
||||
if(!result_pa.is_err()){
|
||||
let pa = result_pa.unwrap();
|
||||
if(pa.access_type == Project::ACCESSREAD || pa.access_type == Project::ACCESSWRITE){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if access_type == Project::ACCESSWRITE && !result_user.is_err() {
|
||||
let user = result_user.as_ref().unwrap();
|
||||
if user.id == self.creator_id {
|
||||
return true;
|
||||
}
|
||||
let result_pa = ProjectAccess::find(user.id,self.id);
|
||||
if(!result_pa.is_err()){
|
||||
let pa = result_pa.unwrap();
|
||||
if(pa.access_type == Project::ACCESSWRITE){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn to_json(&self) -> Value {
|
||||
let mut project_value = json!(self);
|
||||
project_value["entitys"] = json!(self.get_entitys().unwrap());
|
||||
project_value["creator"] = json!(self.get_creator().unwrap());
|
||||
project_value["cmd_logs"] = json!(self.get_logs());
|
||||
project_value["status"] = json!(self.get_status());
|
||||
project_value["data"] = self.get_data();
|
||||
let project_accesss = self.get_project_accesss().unwrap();
|
||||
let mut project_accesss_json = Vec::new();
|
||||
for project_access in project_accesss {
|
||||
project_accesss_json.push(project_access.to_json());
|
||||
}
|
||||
project_value["project_accesss"] = json!(project_accesss_json);
|
||||
project_value
|
||||
}
|
||||
|
||||
pub fn duplicate(&self) -> Result<Self, String> {
|
||||
let user = User::find(self.creator_id)?;
|
||||
let mut project = Project::create(self.name.clone()+"_copy", self.origin_filename.clone(), self.password.clone(), &user)?;
|
||||
project.description = self.description.clone();
|
||||
project.is_public = self.is_public.clone();
|
||||
project = project.update().unwrap();
|
||||
let copy_result = copy_dir_all(Path::new("./medias").join(self.uuid.clone()), Path::new("./medias").join(project.uuid.clone()));
|
||||
if copy_result.is_err() {
|
||||
return Err(format!("You cannot copy {} in {}",self.uuid,project.uuid));
|
||||
}
|
||||
copy_result.unwrap();
|
||||
let entitys = self.get_entitys()?;
|
||||
for e in entitys {
|
||||
let entity = e.duplicate(&project);
|
||||
}
|
||||
return Ok(project);
|
||||
}
|
||||
|
||||
pub fn set_data(&mut self, object: &Value) {
|
||||
self.data = object.to_string();
|
||||
}
|
||||
|
||||
pub fn get_data(&self) -> Value {
|
||||
serde_json::from_str(self.data.as_str()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Queryable, Identifiable, Insertable, serde::Serialize)]
|
||||
pub struct Entity {
|
||||
pub id: i32,
|
||||
pub project_id: i32,
|
||||
pub name: String,
|
||||
pub type_entity: i32,
|
||||
pub data: String,
|
||||
pub parent_id: Option<i32>,
|
||||
}
|
||||
impl Entity {
|
||||
pub const POTREE: i32 = 0;
|
||||
pub const MODELE: i32 = 1;
|
||||
pub const IMAGE360: i32 = 2;
|
||||
pub const POTREEITEM: i32 = 3;
|
||||
pub const GROUP: i32 = 3;
|
||||
|
||||
pub fn create(name: String, type_entity: i32, project: &Project) -> Result<Self, String> {
|
||||
let result = diesel::insert_into(entitys::table)
|
||||
.values((
|
||||
entitys::dsl::project_id.eq(project.id),
|
||||
entitys::dsl::name.eq(name),
|
||||
entitys::dsl::type_entity.eq(type_entity),
|
||||
entitys::dsl::data.eq(json!({}).to_string()),
|
||||
entitys::dsl::parent_id.eq(None::<i32>),
|
||||
))
|
||||
.get_result(&db());
|
||||
if !result.is_err() {
|
||||
let entity = result.unwrap();
|
||||
return Ok(entity);
|
||||
}
|
||||
Err(format!("Entity not created"))
|
||||
}
|
||||
|
||||
pub fn duplicate(&self , project: &Project) -> Result<Self, String> {
|
||||
let result = diesel::insert_into(entitys::table)
|
||||
.values((
|
||||
entitys::dsl::project_id.eq(project.id),
|
||||
entitys::dsl::name.eq(self.name.clone()),
|
||||
entitys::dsl::type_entity.eq(self.type_entity),
|
||||
entitys::dsl::data.eq(self.data.clone()),
|
||||
entitys::dsl::parent_id.eq(None::<i32>),
|
||||
))
|
||||
.get_result(&db());
|
||||
if !result.is_err() {
|
||||
let entity = result.unwrap();
|
||||
return Ok(entity);
|
||||
}
|
||||
Err(format!("Entity not created"))
|
||||
}
|
||||
|
||||
pub fn find(id: i32) -> Result<Self, String> {
|
||||
let result = entitys::dsl::entitys
|
||||
.filter(entitys::dsl::id.eq(id))
|
||||
.get_result::<Self>(&db());
|
||||
if !result.is_err() {
|
||||
let entity = result.unwrap();
|
||||
return Ok(entity);
|
||||
}
|
||||
Err(format!("User {} not found", id))
|
||||
}
|
||||
|
||||
pub fn update(self) -> Result<Self, String> {
|
||||
let filter = entitys::dsl::entitys.filter(entitys::dsl::id.eq(self.id));
|
||||
let result = diesel::update(filter)
|
||||
.set((
|
||||
entitys::dsl::project_id.eq(self.project_id),
|
||||
entitys::dsl::name.eq(self.name),
|
||||
entitys::dsl::type_entity.eq(self.type_entity),
|
||||
entitys::dsl::data.eq(self.data),
|
||||
entitys::dsl::parent_id.eq(self.parent_id),
|
||||
))
|
||||
.get_result::<Self>(&db());
|
||||
if !result.is_err() {
|
||||
let entity = result.unwrap();
|
||||
return Ok(entity);
|
||||
}
|
||||
Err(format!("Project {} not update", self.id))
|
||||
}
|
||||
|
||||
pub fn set_data(&mut self, object: &Value) {
|
||||
self.data = object.to_string();
|
||||
}
|
||||
|
||||
pub fn get_data(&self) -> Value {
|
||||
serde_json::from_str(self.data.as_str()).unwrap()
|
||||
}
|
||||
|
||||
pub fn get_project(&self) -> Result<Project, String> {
|
||||
let result = projects::dsl::projects
|
||||
.filter(projects::dsl::id.eq(self.project_id))
|
||||
.get_result::<Project>(&db());
|
||||
if !result.is_err() {
|
||||
let project = result.unwrap();
|
||||
return Ok(project);
|
||||
}
|
||||
Err(format!("User {} not found", self.project_id))
|
||||
}
|
||||
|
||||
pub fn find_by_name_and_project(name: String, project_id: i32) -> Vec<Entity> {
|
||||
let result = entitys::dsl::entitys
|
||||
.filter(entitys::dsl::name.eq(&name))
|
||||
.filter(entitys::dsl::project_id.eq(&project_id))
|
||||
.get_results::<Entity>(&db());
|
||||
if !result.is_err() {
|
||||
let entitys = result.unwrap();
|
||||
return entitys;
|
||||
}
|
||||
Vec::<Entity>::new()
|
||||
}
|
||||
|
||||
pub fn delete(self) -> Result<String, String> {
|
||||
let id = self.id.clone();
|
||||
let name = self.name.clone();
|
||||
let result_project = self.get_project();
|
||||
if result_project.is_err() {
|
||||
return Err(format!("Entity delete could not find project"));
|
||||
}
|
||||
let project = result_project.unwrap();
|
||||
let entity_with_same_file = Entity::find_by_name_and_project(self.name, self.project_id);
|
||||
|
||||
if self.type_entity != Entity::POTREEITEM && entity_with_same_file.len() <= 1 {
|
||||
let entity_path = Path::new("medias").join(project.uuid).join(&name);
|
||||
if entity_path.exists() && entity_path.is_dir() {
|
||||
let result_file = std::fs::remove_dir_all(entity_path);
|
||||
if result_file.is_err() {
|
||||
return Err(format!("Entity delete could not remove folder"));
|
||||
}
|
||||
} else if entity_path.exists() {
|
||||
let result_file = std::fs::remove_file(entity_path);
|
||||
if result_file.is_err() {
|
||||
return Err(format!("Entity delete could not remove file"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let filter_entity = entitys::dsl::entitys.filter(entitys::dsl::id.eq(&id));
|
||||
let result_del_entity = diesel::delete(filter_entity)
|
||||
.returning(entitys::dsl::name)
|
||||
.get_result::<String>(&db());
|
||||
if result_del_entity.is_err() {
|
||||
return Err(format!("Entity delete could not remove project in db()"));
|
||||
}
|
||||
return Ok("Entity was deleted".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Queryable, Identifiable, Insertable, serde::Serialize)]
|
||||
pub struct ProjectAccess {
|
||||
pub id: i32,
|
||||
pub user_id: i32,
|
||||
pub project_id: i32,
|
||||
pub access_type: i32,
|
||||
}
|
||||
impl ProjectAccess {
|
||||
|
||||
pub fn create(
|
||||
user: &User,
|
||||
project: &Project,
|
||||
access: i32,
|
||||
) -> Result<Self, String> {
|
||||
let project_access_result = ProjectAccess::find(user.id, project.id);
|
||||
if !project_access_result.is_err(){
|
||||
let mut project_access = project_access_result.unwrap();
|
||||
project_access.access_type = access;
|
||||
project_access = project_access.update().unwrap();
|
||||
return Ok(project_access);
|
||||
}
|
||||
if ProjectAccess::find(user.id, project.id).is_err() {
|
||||
let result = diesel::insert_into(project_accesss::table)
|
||||
.values((
|
||||
project_accesss::dsl::user_id.eq(user.id),
|
||||
project_accesss::dsl::project_id.eq(project.id),
|
||||
project_accesss::dsl::access_type.eq(access),
|
||||
))
|
||||
.get_result(&db());
|
||||
let pa_project = project_accesss::dsl::project_accesss
|
||||
.filter(project_accesss::dsl::project_id.eq(project.id))
|
||||
.get_results::<ProjectAccess>(&db())
|
||||
.unwrap();
|
||||
if !result.is_err() {
|
||||
let project_access = result.unwrap();
|
||||
return Ok(project_access);
|
||||
}
|
||||
}
|
||||
Err(format!("Project_Access not created"))
|
||||
}
|
||||
|
||||
pub fn get_user(&self) -> Result<User, String> {
|
||||
let result = users::dsl::users
|
||||
.filter(users::dsl::id.eq(&self.user_id))
|
||||
.get_result::<User>(&db());
|
||||
if !result.is_err() {
|
||||
let user = result.unwrap();
|
||||
return Ok(user);
|
||||
}
|
||||
Err(format!("User {} not found", self.user_id))
|
||||
}
|
||||
|
||||
pub fn get_project(&self) -> Result<Project, String> {
|
||||
let result = projects::dsl::projects
|
||||
.filter(projects::dsl::id.eq(&self.project_id))
|
||||
.get_result::<Project>(&db());
|
||||
if !result.is_err() {
|
||||
let project = result.unwrap();
|
||||
return Ok(project);
|
||||
}
|
||||
Err(format!("Project {} not found", self.project_id))
|
||||
}
|
||||
|
||||
pub fn find(user_id: i32, project_id: i32) -> Result<Self, String> {
|
||||
let result = project_accesss::dsl::project_accesss
|
||||
.filter(project_accesss::dsl::user_id.eq(user_id))
|
||||
.filter(project_accesss::dsl::project_id.eq(project_id))
|
||||
.get_result::<Self>(&db());
|
||||
if !result.is_err() {
|
||||
let project_access = result.unwrap();
|
||||
return Ok(project_access);
|
||||
}
|
||||
Err(format!("Project Access with project_id{} and user_id{} not found", project_id, user_id))
|
||||
}
|
||||
|
||||
pub fn find_id(id: i32) -> Result<Self, String> {
|
||||
let result = project_accesss::dsl::project_accesss
|
||||
.filter(project_accesss::dsl::id.eq(id))
|
||||
.get_result::<Self>(&db());
|
||||
if !result.is_err() {
|
||||
let project_access = result.unwrap();
|
||||
return Ok(project_access);
|
||||
}
|
||||
Err(format!("ProjectAccess {} not found", id))
|
||||
}
|
||||
|
||||
pub fn update(self) -> Result<Self, String> {
|
||||
let filter = project_accesss::dsl::project_accesss.filter(project_accesss::dsl::id.eq(self.id));
|
||||
let result = diesel::update(filter)
|
||||
.set((
|
||||
project_accesss::dsl::user_id.eq(self.user_id),
|
||||
project_accesss::dsl::project_id.eq(self.project_id),
|
||||
project_accesss::dsl::access_type.eq(self.access_type),
|
||||
))
|
||||
.get_result::<Self>(&db());
|
||||
if !result.is_err() {
|
||||
let project_access = result.unwrap();
|
||||
return Ok(project_access);
|
||||
}
|
||||
Err(format!("ProjectAccess {} not update", self.id))
|
||||
}
|
||||
|
||||
pub fn delete(self) -> Result<String, String> {
|
||||
let id = self.id.clone();
|
||||
let filter_pa = project_accesss::dsl::project_accesss.filter(project_accesss::dsl::id.eq(&id));
|
||||
let result_del_pa = diesel::delete(filter_pa)
|
||||
.returning(project_accesss::dsl::id)
|
||||
.get_result::<i32>(&db());
|
||||
if result_del_pa.is_err() {
|
||||
return Err(format!("ProjectAccess cannot be deleted in db()"));
|
||||
}
|
||||
return Ok("ProjectAccess was deleted".to_string());
|
||||
}
|
||||
|
||||
pub fn to_json(self) -> Value {
|
||||
let mut project_access_value = json!(self);
|
||||
project_access_value["user"] = json!(self.get_user().unwrap());
|
||||
project_access_value["project"] = json!(self.get_project().unwrap());
|
||||
project_access_value
|
||||
}
|
||||
}
|
||||
@@ -1,42 +1,5 @@
|
||||
// @generated automatically by Diesel CLI.
|
||||
|
||||
diesel::table! {
|
||||
entitys (id) {
|
||||
id -> Int4,
|
||||
project_id -> Int4,
|
||||
name -> Varchar,
|
||||
type_entity -> Int4,
|
||||
data -> Text,
|
||||
parent_id -> Nullable<Int4>,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
project_accesss (id) {
|
||||
id -> Int4,
|
||||
user_id -> Int4,
|
||||
project_id -> Int4,
|
||||
access_type -> Int4,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
projects (id) {
|
||||
id -> Int4,
|
||||
creator_id -> Int4,
|
||||
uuid -> Varchar,
|
||||
name -> Varchar,
|
||||
password -> Varchar,
|
||||
time_limit -> Timestamp,
|
||||
premium -> Int4,
|
||||
is_public -> Bool,
|
||||
image -> Varchar,
|
||||
origin_filename -> Varchar,
|
||||
description -> Text,
|
||||
data -> Text,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
users (id) {
|
||||
id -> Int4,
|
||||
@@ -47,17 +10,6 @@ diesel::table! {
|
||||
email -> Varchar,
|
||||
google -> Varchar,
|
||||
email_valid -> Varchar,
|
||||
data -> Text,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::joinable!(entitys -> projects (project_id));
|
||||
diesel::joinable!(project_accesss -> projects (project_id));
|
||||
diesel::joinable!(project_accesss -> users (user_id));
|
||||
diesel::joinable!(projects -> users (creator_id));
|
||||
|
||||
diesel::allow_tables_to_appear_in_same_query!(
|
||||
entitys,
|
||||
project_accesss,
|
||||
projects,
|
||||
users,
|
||||
);
|
||||
|
||||
@@ -375,7 +375,7 @@ pub fn envoye_un_mail(tmpl: &Data<Tera>, template_name: &'static str, context: &
|
||||
let body = tmpl.render(template_name, context).unwrap();
|
||||
|
||||
let email = Message::builder()
|
||||
.from("Site DrWhy <noreply@imaplan.fr>".parse().unwrap())
|
||||
.from("Site DrWhy <contact@sorlinv.fr>".parse().unwrap())
|
||||
.to(format!("<{}>", email_adress).parse().unwrap())
|
||||
.subject(subject)
|
||||
.multipart(MultiPart::alternative_plain_html(
|
||||
@@ -385,8 +385,8 @@ pub fn envoye_un_mail(tmpl: &Data<Tera>, template_name: &'static str, context: &
|
||||
|
||||
let sender = SmtpTransport::starttls_relay("ssl0.ovh.net").unwrap()
|
||||
.credentials(Credentials::new(
|
||||
"noreply@imaplan.fr".to_string(),
|
||||
"24rueduMoulin".to_string(),
|
||||
"contact@sorlinv.fr".to_string(),
|
||||
"Wqaxszcde123".to_string(),
|
||||
))
|
||||
// .authentication(vec![Mechanism::Plain])
|
||||
.pool_config(PoolConfig::new().max_size(20))
|
||||
|
||||
1
static/img/google.svg
Normal file
1
static/img/google.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" fill="#4285F4"/><path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" fill="#34A853"/><path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" fill="#FBBC05"/><path d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" fill="#EA4335"/><path d="M1 1h22v22H1z" fill="none"/></svg>
|
||||
|
After Width: | Height: | Size: 742 B |
BIN
static/img/logo.png
Normal file
BIN
static/img/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 141 KiB |
@@ -2,7 +2,6 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{% block title %}{% endblock title %} - DrWhy</title>
|
||||
|
||||
{% block head %}
|
||||
{% include 'includecss.html.twig' %}
|
||||
{% endblock head %}
|
||||
@@ -10,6 +9,5 @@
|
||||
<body>
|
||||
{% block body %}{% endblock body %}
|
||||
{% block footer %}{% include 'includescript.html.twig' %}{% endblock footer %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
<form class="" action="/change_password/{{user.password}}" method="post" enctype="multipart/form-data">
|
||||
{# Error message #}
|
||||
{% if message_error is defined %}<div class="text-danger text-center font-weight-bold mb-3">{{ message_error }}</div>{% endif %}
|
||||
{# Password #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control rounded-4" name="password" type="password" placeholder="mdp" required>
|
||||
{% if message_error is defined %}<div class="text-danger text-center font-weight-bold ">{{ message_error }}</div>{% endif %}
|
||||
<div class="">
|
||||
<label for="password">Mot de passe</label>
|
||||
<input name="password" type="password" placeholder="mdp" required>
|
||||
</div>
|
||||
{# Password again #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control" name="repassword" type="password" placeholder="mdp" required>
|
||||
<div class="">
|
||||
<label for="repassword">Confirmez le mot de passe</label>
|
||||
<input name="repassword" type="password" placeholder="mdp" required>
|
||||
</div>
|
||||
{# Submit button #}
|
||||
<button class="w-100 mb-2 btn btn-lg rounded-4 btn-primary mt-3" type="submit">Envoyer</button>
|
||||
<button class="w-100 mb-2 btn btn-lg rounded-4 btn-primary " type="submit">Envoyer</button>
|
||||
</form>
|
||||
@@ -1,13 +1,9 @@
|
||||
<form class="" action="/forgotpassword" method="post" enctype="multipart/form-data">
|
||||
{# Email #}
|
||||
<div class="form-floating mt-3 mb-3">
|
||||
<input class="form-control" name="email" type="email" placeholder="JohnDoe" required>
|
||||
<div class=" ">
|
||||
<input name="email" type="email" placeholder="JohnDoe" required>
|
||||
<label for="email">Email</label>
|
||||
</div>
|
||||
{# Submit button #}
|
||||
<button class="w-100 mb-2 btn btn-lg rounded-4 btn-primary" type="submit">Envoyer</button>
|
||||
{# Forgot password #}
|
||||
<a href="/login" class="text-muted fs-6">Se connecter</a><br>
|
||||
{# Register #}
|
||||
<a href="/register" class="text-muted fs-6">Créer un compte</a>
|
||||
</form>
|
||||
|
||||
@@ -1,43 +1,20 @@
|
||||
<form class="" action="/login" method="post">
|
||||
{% if message_login is defined %}<div class="text-danger text-center font-weight-bold mb-3">{{ message_login }}</div>{% endif %}
|
||||
{# Email #}
|
||||
<div class="form-floating mb-3">
|
||||
<input name="username" type="text" class="form-control rounded-4" id="floatingUser" placeholder="name@example.com">
|
||||
{% if message_login is defined %}<div class="text-danger text-center font-weight-bold ">{{ message_login }}</div>{% endif %}
|
||||
<div class="">
|
||||
<label for="floatingUser">Nom d'utilisateur ou Email</label>
|
||||
<input name="username" type="text" id="floatingUser" placeholder="name@example.com">
|
||||
</div>
|
||||
{# Password #}
|
||||
<div class="form-floating mb-3">
|
||||
<input name="password" type="password" class="form-control rounded-4" id="floatingPassword" placeholder="Password">
|
||||
<div class="">
|
||||
<label for="floatingPassword">Mot de passe</label>
|
||||
<input name="password" type="password" id="floatingPassword" placeholder="Password">
|
||||
</div>
|
||||
{# Error message #}
|
||||
{# Submit button #}
|
||||
<button class="w-100 mb-3 btn btn-lg rounded-4 btn-primary" type="submit">Se connecter</button>
|
||||
{# Forgot password #}
|
||||
<a href="/forgotpassword" class="color-hover">Mot de passe oublié ?</a><br>
|
||||
{# Register #}
|
||||
<a href="/register" class="color-hover">Créer un compte</a>
|
||||
{# Divider #}
|
||||
<hr class="my-4">
|
||||
{# Third party #}
|
||||
<h2 class="fs-5 fw-bold mb-3 text-center">Ou</h2>
|
||||
{# Google #}
|
||||
<button class="w-100 btn btn-lg rounded-4 btn-primary" type="submit">Se connecter</button>
|
||||
<div id="g_id_onload"
|
||||
data-client_id="723424966880-015kn0qncavlgbj4j3k1ggs3arn7tdkd.apps.googleusercontent.com"
|
||||
data-client_id="1041713159432-vad6qp7ce7p9iid9qjdiopi7n6ajvmtv.apps.googleusercontent.com"
|
||||
data-login_uri="/auth"
|
||||
data-auto_prompt="false">
|
||||
</div>
|
||||
<div class="g_id_signin d-flex justify-content-center mb-2"
|
||||
data-type="standard"
|
||||
data-size="large"
|
||||
data-theme="filled_black"
|
||||
data-text="sign_in_with"
|
||||
data-shape="rectangular"
|
||||
data-logo_alignment="left">
|
||||
</div>
|
||||
{# GitHub #}
|
||||
<button class=" w-100 py-2 mb-2 btn btn-outline-secondary rounded-4" type="submit">
|
||||
<span class="mdi mdi-github"></span>
|
||||
Se connecter avec GitHub
|
||||
</button>
|
||||
data-auto_prompt="false"
|
||||
></div>
|
||||
<button class="g_id_signin"></button>
|
||||
<a href="/forgotpassword" class="color-hover">Mot de passe oublié ?</a><br>
|
||||
<a href="/register" class="color-hover">Créer un compte</a>
|
||||
</form>
|
||||
@@ -1,78 +1,37 @@
|
||||
<form class="" action="/register" method="post" enctype="multipart/form-data">
|
||||
{# Error message #}
|
||||
{% if message_register is defined %}<div class="text-danger font-weight-bold mt-3">{{ message_register }}</div>{% endif %}
|
||||
{% if message_register is defined %}<div class="text-danger font-weight-bold ">{{ message_register }}</div>{% endif %}
|
||||
{# UserName #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control" name="username" type="text" placeholder="JohnDoe" required>
|
||||
<div class="">
|
||||
<label for="username">Nom d'utilisateur</label>
|
||||
<input name="username" type="text" placeholder="JohnDoe" required>
|
||||
</div>
|
||||
{# Email #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control" name="email" type="email" placeholder = "mail@example.com" required>
|
||||
<div class="">
|
||||
<label for="username">Email</label>
|
||||
<input name="email" type="email" placeholder = "mail@example.com" required>
|
||||
</div>
|
||||
{# Password #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control rounded-4" name="password" type="password" placeholder="mdp" required>
|
||||
<div class="">
|
||||
<label for="password">Mot de passe</label>
|
||||
<input name="password" type="password" placeholder="mdp" required>
|
||||
</div>
|
||||
{# Password again #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control" name="repassword" type="password" placeholder="mdp" required>
|
||||
<div class="">
|
||||
<label for="repassword">Confirmez le mot de passe</label>
|
||||
<input name="repassword" type="password" placeholder="mdp" required>
|
||||
</div>
|
||||
{# Image #}
|
||||
<div class="form-group mt-3">
|
||||
<label for="input-image" class="input-label-img d-flex">
|
||||
<input name="image" type="file" accept="image/png, image/jpg, image/gif, image/jpeg"/>
|
||||
<div class="">
|
||||
<label for="input-image">
|
||||
<span>Image de profil </span>
|
||||
<input name="image" type="file" accept="image/png, image/jpg, image/gif, image/jpeg"/>
|
||||
</label>
|
||||
{# <label class="" for="image">Image</label>
|
||||
<input class="form-control" name="image" type="file"> #}
|
||||
</div>
|
||||
{# Submit button #}
|
||||
<button class="w-100 mt-3 mb-3 btn btn-lg rounded-4 btn-primary" type="submit">S'inscrire</button>
|
||||
{# Login #}
|
||||
<button type="submit">S'inscrire</button>
|
||||
<div id="g_id_onload"
|
||||
data-client_id="1041713159432-vad6qp7ce7p9iid9qjdiopi7n6ajvmtv.apps.googleusercontent.com"
|
||||
data-login_uri="/auth"
|
||||
data-auto_prompt="false"
|
||||
></div>
|
||||
<button class="g_id_signin"></button>
|
||||
<a href="/forgotpassword" class="color-hover">Mot de passe oublié ?</a><br>
|
||||
<a href="/login" class="color-hover">Se connecter</a>
|
||||
{# Divider #}
|
||||
<hr class="my-4">
|
||||
{# Third-Party #}
|
||||
<h2 class="fs-5 fw-bold mb-3 text-center">Ou</h2>
|
||||
{# Google #}
|
||||
<div id="g_id_onload"
|
||||
data-client_id="723424966880-015kn0qncavlgbj4j3k1ggs3arn7tdkd.apps.googleusercontent.com"
|
||||
data-login_uri="/auth"
|
||||
data-auto_prompt="false">
|
||||
</div>
|
||||
<div class="g_id_signin d-flex justify-content-center mb-2"
|
||||
data-type="standard"
|
||||
data-size="large"
|
||||
data-theme="filled_black"
|
||||
data-text="sign_in_with"
|
||||
data-shape="rectangular"
|
||||
data-logo_alignment="left">
|
||||
</div>
|
||||
{# GitHub #}
|
||||
<button class=" w-100 py-2 mb-2 btn btn-outline-secondary rounded-4" type="submit">
|
||||
<span class="mdi mdi-github"></span>
|
||||
Se connecter avec GitHub
|
||||
</button>
|
||||
<hr>
|
||||
</form>
|
||||
|
||||
{# CSS #}
|
||||
<style media= "screen" >
|
||||
.input-label-img {
|
||||
border: 1px solid #ccc;
|
||||
display: inline-block;
|
||||
padding: 6px 12px;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
border-radius: 0.25rem;
|
||||
height: calc(3.5rem + 2px);
|
||||
padding: 1rem 0.75rem;
|
||||
}
|
||||
.input-label-img > input {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -1,26 +1,26 @@
|
||||
<form class="" action="/register_google/{{registrable_user.username}}" method="post" enctype="multipart/form-data">
|
||||
{# Email #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control" name="email" type="email" value ={{registrable_user.email}} placeholder = "mail@example.com" disabled >
|
||||
<div class="">
|
||||
<input name="email" type="email" value ={{registrable_user.email}} placeholder = "mail@example.com" disabled >
|
||||
<label for="username">Email</label>
|
||||
</div>
|
||||
{# UserName #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control" name="username" type="text" placeholder="JohnDoe" value ={{registrable_user.email}} required>
|
||||
<div class="">
|
||||
<input name="username" type="text" placeholder="JohnDoe" value ={{registrable_user.email}} required>
|
||||
<label for="username">Nom d'utilisateur</label>
|
||||
</div>
|
||||
{# Password #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control rounded-4" name="password" type="password" placeholder="mdp" required>
|
||||
<div class="">
|
||||
<input name="password" type="password" placeholder="mdp" required>
|
||||
<label for="password">Mot de passe</label>
|
||||
</div>
|
||||
{# Error message #}
|
||||
{% if message is defined %}<div class="text-danger font-weight-bold mt-3">{{ message }}</div>{% endif %}
|
||||
{% if message is defined %}<div class="text-danger font-weight-bold ">{{ message }}</div>{% endif %}
|
||||
{# Password again #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control" name="repassword" type="password" placeholder="mdp" required>
|
||||
<div class="">
|
||||
<input name="repassword" type="password" placeholder="mdp" required>
|
||||
<label for="repassword">Confirmez le mot de passe</label>
|
||||
</div>
|
||||
{# Submit button #}
|
||||
<button class="w-100 mt-3 mb-3 btn btn-lg rounded-4 btn-primary" type="submit">S'inscrire</button>
|
||||
<button class="w-100 btn btn-lg rounded-4 btn-primary" type="submit">S'inscrire</button>
|
||||
</form>
|
||||
@@ -1,23 +1,60 @@
|
||||
<header>
|
||||
<nav>
|
||||
<ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><img src="/static/img/logo.svg" alt="DrWhy" height="24" width="24"></li>
|
||||
<li><img src="/static/img/logo.svg" alt="DrWhy" height="75" width="75"></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="#">Dr WHO(2005)</a></li>
|
||||
<li><a href="#">Dr WHO Classic(1963)</a></li>
|
||||
<li><a href="#">Torchwood</a></li>
|
||||
<li><a href="#">Sarah janes adventure</a></li>
|
||||
<li><a href="#">K-9</a></li>
|
||||
<li><a href="#">K-9 and Company</a></li>
|
||||
<li><a href="#">Class</a></li>
|
||||
<li>
|
||||
<details role="list">
|
||||
<summary class="mdi mdi-movie" aria-haspopup="listbox" role="Link">
|
||||
Series
|
||||
</summary>
|
||||
<ul role="listbox">
|
||||
<li><a href="/medias?q=/Series/DrWho">Dr WHO(2005)</a></li>
|
||||
<li><a href="/medias?q=/Series/DrWho Classic">Dr WHO Classic(1963)</a></li>
|
||||
<li><a href="/medias?q=/Series/Torchwood">Torchwood</a></li>
|
||||
<li><a href="/medias?q=/Series/The Sarah Jane Adventures">The Sarah Jane Adventures</a></li>
|
||||
<li><a href="/medias?q=/Series/Class">Class</a></li>
|
||||
<li><a href="/medias?q=/Series/K-9">K-9</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</li>
|
||||
<li>
|
||||
<details role="list">
|
||||
<summary class="mdi mdi-thought-bubble" aria-haspopup="listbox" role="Link">
|
||||
BD
|
||||
</summary>
|
||||
<ul role="listbox">
|
||||
<li><a href="/medias?q=/BD">Comming soon</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</li>
|
||||
<li>
|
||||
<details role="list">
|
||||
<summary class="mdi mdi-book-open-variant" aria-haspopup="listbox" role="Link">
|
||||
Romans
|
||||
</summary>
|
||||
<ul role="listbox">
|
||||
<li><a href="/medias?q=/Romans">Comming soon</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</li>
|
||||
<li>
|
||||
<details role="list">
|
||||
<summary class="mdi mdi-podcast" aria-haspopup="listbox" role="Link">
|
||||
Podcast
|
||||
</summary>
|
||||
<ul role="listbox">
|
||||
<li><a href="/medias?q=/Podcast">Comming soon</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
{% if user is defined %}
|
||||
<details role="list">
|
||||
<summary aria-haspopup="listbox" role="button">
|
||||
<summary aria-haspopup="listbox" role="Link">
|
||||
<img src="{{user.image}}" alt="avatar" class="rounded" width="50" height="50">
|
||||
</summary>
|
||||
<ul role="listbox">
|
||||
@@ -26,8 +63,8 @@
|
||||
</ul>
|
||||
</details>
|
||||
{% else %}
|
||||
<button class="contrast" data-target="modal-signin" onClick="toggleModal(event)">Inscription</button>
|
||||
<button class="contrast" data-target="modal-login" onClick="toggleModal(event)">Connexion</button>
|
||||
<button class="outline" data-target="modal-signin" onClick="toggleModal(event)">Inscription</button>
|
||||
<button class="outline" data-target="modal-login" onClick="toggleModal(event)">Connexion</button>
|
||||
{# <button type="button" class="btn btn-primary text-light ms-2" data-bs-toggle="modal" data-bs-target="#modalSignUp">Inscription</button>
|
||||
<button type="button" class="btn btn-black text-light ms-2" data-bs-toggle="modal" data-bs-target="#modalLogIn">Connexion</button> #}
|
||||
{% endif %}
|
||||
@@ -35,6 +72,8 @@
|
||||
<ul>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
{% if user is not defined %}
|
||||
<dialog id="modal-login">
|
||||
<article>
|
||||
<a href="#close"
|
||||
@@ -57,38 +96,4 @@
|
||||
{% include 'forms/user/register.html.twig' %}
|
||||
</article>
|
||||
</dialog>
|
||||
|
||||
|
||||
{% if user is not defined %}
|
||||
{# Modal pour LogIn #}
|
||||
{# <div class="modal fade" role="dialog" id="modalLogIn">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content rounded-5 shadow">
|
||||
<div class="modal-header p-5 pb-4 border-bottom-0">
|
||||
<!-- <h5 class="modal-title">Modal title</h5> -->
|
||||
<h2 class="fw-bold mb-0">Connexion</h2>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body p-5 pt-0">
|
||||
{% include 'forms/user/login.html.twig' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> #}
|
||||
|
||||
{# Modal pour SignUp #}
|
||||
{# <div class="modal fade" role="dialog" id="modalSignUp">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content rounded-5 shadow">
|
||||
<div class="modal-header p-5 pb-4 border-bottom-0">
|
||||
<!-- <h5 class="modal-title">Modal title</h5> -->
|
||||
<h2 class="fw-bold mb-0">Inscription</h2>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body p-5 pt-0">
|
||||
{% include 'forms/user/register.html.twig' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> #}
|
||||
{% endif %}
|
||||
@@ -11,9 +11,11 @@
|
||||
<meta name="theme-color" content="#333333">
|
||||
|
||||
<link href="https://vjs.zencdn.net/7.17.0/video-js.css" rel="stylesheet" />
|
||||
<link href="https://unpkg.com/@videojs/themes@1/dist/fantasy/index.css" rel="stylesheet">
|
||||
|
||||
<script src="https://accounts.google.com/gsi/client" async defer></script>
|
||||
<link href="https://unpkg.com/@videojs/themes@1/dist/fantasy/index.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css" rel="stylesheet">
|
||||
|
||||
<script src="https://accounts.google.com/gsi/client"></script>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/pico.min.css">
|
||||
<script src="/static/js/modal.js"></script>
|
||||
@@ -2,10 +2,8 @@
|
||||
{% block title %}Acceuil{% endblock %}
|
||||
{% block body %}
|
||||
<body>
|
||||
|
||||
{% include "header.html.twig" %}
|
||||
|
||||
|
||||
{% include "footer.html.twig"%}
|
||||
|
||||
</body>
|
||||
|
||||
19
templates/medias.html.twig
Normal file
19
templates/medias.html.twig
Normal file
@@ -0,0 +1,19 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% block title %}Acceuil{% endblock %}
|
||||
{% block body %}
|
||||
<body>
|
||||
{% include "header.html.twig" %}
|
||||
<nav aria-label="breadcrumb">
|
||||
{% set current_path = "" %}
|
||||
<ul>
|
||||
{% for item in path|split(pat="/") %}
|
||||
{% set current_path = current_path ~ "/" ~ item %}
|
||||
<li><a href="/medias?q={{current_path}}">{{item}}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
{% include "footer.html.twig"%}
|
||||
|
||||
</body>
|
||||
{% endblock %}
|
||||
@@ -9,41 +9,41 @@
|
||||
<body>
|
||||
{% include 'header.html.twig' %}
|
||||
<main>
|
||||
<div class="d-flex flex-column justify-content-center align-items-center">
|
||||
<h2 class="fw-bold mt-3">Profil</h2>
|
||||
<form action="/profile/{{user.id}}" class="w-75" method="post" enctype="multipart/form-data">
|
||||
<div style="width: 75%; margin: auto">
|
||||
<h2 class="fw-bold ">Profil</h2>
|
||||
<form action="/profile/{{user.id}}" method="post" enctype="multipart/form-data">
|
||||
{# Username #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control" name="username" type="text" placeholder="JohnDoe" value="{{user.username}}">
|
||||
<div class="">
|
||||
<label for="username">Nom d'utilisateur</label>
|
||||
<input name="username" type="text" placeholder="JohnDoe" value="{{user.username}}">
|
||||
</div>
|
||||
{# Email #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control" name="email" type="email" placeholder = "mail@example.com" value="{{user.email}}">
|
||||
<div class="">
|
||||
<label for="username">Email</label>
|
||||
<input name="email" type="email" placeholder = "mail@example.com" value="{{user.email}}">
|
||||
</div>
|
||||
{# Password #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control rounded-4" name="password" type="password" placeholder="mdp">
|
||||
<div class="">
|
||||
<label for="password">Mot de passe</label>
|
||||
<input name="password" type="password" placeholder="mdp">
|
||||
</div>
|
||||
{# Error message #}
|
||||
{% if message_register is defined %}<div class="text-danger font-weight-bold mt-3">{{ message_register }}</div>{% endif %}
|
||||
{% if message_register is defined %}<div class="text-danger font-weight-bold ">{{ message_register }}</div>{% endif %}
|
||||
{# Password again #}
|
||||
<div class="form-floating mt-3">
|
||||
<input class="form-control" name="repassword" type="password" placeholder="mdp" >
|
||||
<div class="">
|
||||
<label for="repassword">Confirmez le mot de passe</label>
|
||||
<input name="repassword" type="password" placeholder="mdp" >
|
||||
</div>
|
||||
{# Image #}
|
||||
<div class="form-group mt-3 w-50" style="float:left">
|
||||
<div class=" w-50" style="float:left">
|
||||
<input name="image" type="file">
|
||||
<label for="image">Image</label>
|
||||
<input class="form-control" name="image" type="file">
|
||||
</div>
|
||||
<div class ="w-50 ps-4" style="float:right">
|
||||
<img src="{{user.image}}" alt="Image de profil" height="128" class="mt-3">
|
||||
<img src="{{user.image}}" alt="Image de profil" height="128" class="">
|
||||
</div>
|
||||
{# Submit #}
|
||||
<button class="mt-3 mb-3 btn btn-lg rounded-4 btn-primary" type="submit">Modifier</button>
|
||||
<button class=" btn btn-lg rounded-4 btn-primary" type="submit">Modifier</button>
|
||||
{# Delete #}
|
||||
<a class=" btn btn-lg ms-3 rounded-4 btn-danger" href="/delete/{{user.id}}" comfirm="Êtes vous sure de vouloir supprimer votre compte ?">Supprimer le compte</a
|
||||
</form>
|
||||
@@ -51,20 +51,13 @@
|
||||
{% if message_profile is defined %}<div class="text-success font-weight-bold">{{ message_profile }}</div>{% endif %}
|
||||
</div>
|
||||
{% if user.google == "" %}
|
||||
<p class="text-center mt-3">AJOUTER GOOGLE AU COMPTE</p>
|
||||
<p class="text-center ">AJOUTER GOOGLE AU COMPTE</p>
|
||||
<div id="g_id_onload"
|
||||
data-client_id="723424966880-015kn0qncavlgbj4j3k1ggs3arn7tdkd.apps.googleusercontent.com"
|
||||
data-login_uri="/auth/{{user.id}}"
|
||||
data-auto_prompt="false">
|
||||
</div>
|
||||
<div class="g_id_signin d-flex justify-content-center mb-2"
|
||||
data-type="standard"
|
||||
data-size="large"
|
||||
data-theme="filled_black"
|
||||
data-text="sign_in_with"
|
||||
data-shape="rectangular"
|
||||
data-logo_alignment="left">
|
||||
</div>
|
||||
data-client_id="1041713159432-vad6qp7ce7p9iid9qjdiopi7n6ajvmtv.apps.googleusercontent.com"
|
||||
data-login_uri="/auth"
|
||||
data-auto_prompt="false"
|
||||
></div>
|
||||
<button class="g_id_signin"></button>
|
||||
{% endif %}
|
||||
</main>
|
||||
{% include "footer.html.twig"%}
|
||||
|
||||
Reference in New Issue
Block a user