M src/config.rs => src/config.rs +14 -7
@@ 1,5 1,5 @@
use lazy_static::lazy_static;
-use serde_derive::{Serialize, Deserialize};
+use serde_derive::{Deserialize, Serialize};
use std::{fs, path::PathBuf};
lazy_static! {
@@ 8,19 8,26 @@ lazy_static! {
config.push("git-server");
config.push("git-server.toml");
if config.exists() {
- let config:Config = toml::from_str(&String::from_utf8_lossy(&fs::read(config.as_path()).expect("Failed to read the config file"))).expect("Could not parse the toml in the config file");
- config
- }
- else {
+ let config: Config = toml::from_str(&String::from_utf8_lossy(
+ &fs::read(config.as_path()).expect("Failed to read the config file"),
+ ))
+ .expect("Could not parse the toml in the config file");
+ config
+ } else {
let config_struct = Config {
name: "Example User".to_string(),
- description: "This is billy and he loves his [website](https://example.com)!!!".to_string(),
+ description: "This is billy and he loves his [website](https://example.com)!!!"
+ .to_string(),
git_location: dirs::home_dir().unwrap_or(PathBuf::from("/")),
};
config.pop();
let _ = fs::create_dir_all(config.clone());
config.push("git-server.toml");
- fs::write(config, toml::to_string(&config_struct).expect("Failed to stringify config")).expect("Failed to set the config content");
+ fs::write(
+ config,
+ toml::to_string(&config_struct).expect("Failed to stringify config"),
+ )
+ .expect("Failed to set the config content");
config_struct
}
};
M src/git/repos.rs => src/git/repos.rs +41 -32
@@ 1,37 1,40 @@
-use std::fs;
-use serde_derive::Serialize;
use crate::config::CONFIG;
+use serde_derive::Serialize;
+use std::fs;
pub fn get_repos() -> Option<Vec<Repo>> {
let home = CONFIG.git_location.clone();
- Some(sort_modified(fs::read_dir(home.clone()).ok()?
- .filter(|path| path.is_ok())
- .map(|path| path.unwrap())
- .filter(|path| path.file_type().is_ok())
- .filter(|path| path.file_type().unwrap().is_dir())
- .filter(|path| path.metadata().is_ok())
- .filter(|path| path.metadata().unwrap().modified().is_ok())
- .map(|path| path.file_name().into_string())
- .filter(|path| path.is_ok())
- .map(|path| path.unwrap())
- .filter(|path| !path.starts_with("."))
- .filter(|path| path.ends_with(".git"))
- .map(|path| {
- let mut description_path = home.clone();
- description_path.push(path.clone());
- description_path.push("DESCRIPTION");
- let description = match fs::read(description_path.clone()) {
- Ok(content) => {
- String::from_utf8_lossy(&content).parse().unwrap_or("".to_string())
- },
- Err(_) => "".to_string()
- };
- Repo {
- name: path[0..path.len() - 4].to_string(),
- description
- }
- })
- .collect::<Vec<Repo>>()))
+ Some(sort_modified(
+ fs::read_dir(home.clone())
+ .ok()?
+ .filter(|path| path.is_ok())
+ .map(|path| path.unwrap())
+ .filter(|path| path.file_type().is_ok())
+ .filter(|path| path.file_type().unwrap().is_dir())
+ .filter(|path| path.metadata().is_ok())
+ .filter(|path| path.metadata().unwrap().modified().is_ok())
+ .map(|path| path.file_name().into_string())
+ .filter(|path| path.is_ok())
+ .map(|path| path.unwrap())
+ .filter(|path| !path.starts_with("."))
+ .filter(|path| path.ends_with(".git"))
+ .map(|path| {
+ let mut description_path = home.clone();
+ description_path.push(path.clone());
+ description_path.push("DESCRIPTION");
+ let description = match fs::read(description_path.clone()) {
+ Ok(content) => String::from_utf8_lossy(&content)
+ .parse()
+ .unwrap_or("".to_string()),
+ Err(_) => "".to_string(),
+ };
+ Repo {
+ name: path[0..path.len() - 4].to_string(),
+ description,
+ }
+ })
+ .collect::<Vec<Repo>>(),
+ ))
}
#[derive(Serialize, Clone)]
@@ 43,12 46,18 @@ pub struct Repo {
fn sort_modified(repos: Vec<Repo>) -> Vec<Repo> {
let mut repos = repos.clone();
let home = CONFIG.git_location.clone();
- repos.sort_by(|a,b| {
+ repos.sort_by(|a, b| {
let mut a_loc = home.clone();
a_loc.push(format!("{}.git", a.name));
let mut b_loc = home.clone();
b_loc.push(format!("{}.git", b.name));
- b_loc.metadata().unwrap().modified().unwrap().partial_cmp(&a_loc.metadata().unwrap().modified().unwrap()).unwrap()
+ b_loc
+ .metadata()
+ .unwrap()
+ .modified()
+ .unwrap()
+ .partial_cmp(&a_loc.metadata().unwrap().modified().unwrap())
+ .unwrap()
});
repos
}
M src/index.rs => src/index.rs +30 -22
@@ 1,39 1,47 @@
-use crate::git::repos::get_repos;
use crate::config::CONFIG;
+use crate::git::repos::get_repos;
use crate::git::repos::Repo;
-use rocket_dyn_templates::{Template, context};
+use rocket_dyn_templates::{context, Template};
-const PAGE_REPO_COUNT:usize = 10;
+const PAGE_REPO_COUNT: usize = 10;
#[get("/?<page>&<search>")]
pub fn index(page: Option<usize>, search: Option<String>) -> Option<Template> {
let mut repos = get_repos()?;
let page = page.unwrap_or(1);
if search.is_some() {
- repos = repos.iter().filter(|repo| repo.name.contains(&*search.as_ref().unwrap()) || repo.description.contains(&*search.as_ref().unwrap())).map(|repo| repo.clone()).collect::<Vec<Repo>>();
+ repos = repos
+ .iter()
+ .filter(|repo| {
+ repo.name.contains(&*search.as_ref().unwrap())
+ || repo.description.contains(&*search.as_ref().unwrap())
+ })
+ .map(|repo| repo.clone())
+ .collect::<Vec<Repo>>();
}
let total_page = if repos.len() > 0 {
- (repos.len()-1)/PAGE_REPO_COUNT+1
- }
- else {
+ (repos.len() - 1) / PAGE_REPO_COUNT + 1
+ } else {
1
};
- let last_item = if repos.len() > page*PAGE_REPO_COUNT {
- page*PAGE_REPO_COUNT
- }
- else {
+ let last_item = if repos.len() > page * PAGE_REPO_COUNT {
+ page * PAGE_REPO_COUNT
+ } else {
repos.len()
};
- Some(Template::render("index", context! {
- title: "Me",
- user: CONFIG.name.clone(),
- description: markdown::to_html(&CONFIG.description.clone()),
- repos: repos[(page-1)*PAGE_REPO_COUNT..last_item].to_vec(),
- search: search.unwrap_or("".to_string()),
- page,
- total_page,
- page_inc: page+1,
- page_dec: if page > 1 {page-1} else {page}
- }))
+ Some(Template::render(
+ "index",
+ context! {
+ title: "Me",
+ user: CONFIG.name.clone(),
+ description: markdown::to_html(&CONFIG.description.clone()),
+ repos: repos[(page-1)*PAGE_REPO_COUNT..last_item].to_vec(),
+ search: search.unwrap_or("".to_string()),
+ page,
+ total_page,
+ page_inc: page+1,
+ page_dec: if page > 1 {page-1} else {page}
+ },
+ ))
}
M src/main.rs => src/main.rs +5 -4
@@ 1,11 1,12 @@
-#[macro_use] extern crate rocket;
+#[macro_use]
+extern crate rocket;
+mod config;
mod git;
mod index;
-mod config;
-use rocket_dyn_templates::Template;
-use rocket::fs::FileServer;
use rocket::fs::relative;
+use rocket::fs::FileServer;
+use rocket_dyn_templates::Template;
#[launch]
fn rocket() -> _ {
A templates/index.html +57 -0
@@ 0,0 1,57 @@
+{{#*inline "page"}}
+<div class="container" style="margin-top:56px">
+ <div class="row">
+ <div class="col-md-4">
+ <h2>{{ user }}!</h2>
+ {{{ description }}}
+ </div>
+ <div class="col-md-8">
+ <form>
+ <input class="form-control" dir="auto" name="search" placeholder="Search" type="text" value="{{ search }}">
+ </form>
+ <div class="event-list">
+ {{#each repos}}
+ <div class="event">
+ <h4>
+ <a href="/{{this.name}}">{{ this.name }}</a>
+ </h4>
+ <p>{{ this.description }}</p>
+ </div>
+ {{/each}}
+ </div>
+ {{#if (ne total_page 1)}}
+ <div class="row">
+ <div class="col-4">
+ {{#if (ne page 1)}}
+ <a class="btn btn-default" href="?page={{page_dec}}&search={{search}}">
+ <span aria-hidden="true" class="icon icon-caret-left">
+ <svg viewBox="0 0 192 512" xmlns="http://www.w3.org/2000/svg">
+ <path d="M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142z"></path>
+ </svg>
+ </span>
+ prev
+ </a>
+ {{/if}}
+ </div>
+ <div class="col-4 text-centered">
+ {{page}} / {{ total_page }}
+ </div>
+ {{#if (ne page total_page)}}
+ <div class="col-4 text-right">
+ <a class="btn btn-default" href="?page={{page_inc}}&search={{search}}">
+ next
+ <span aria-hidden="true" class="icon icon-caret-right">
+ <svg viewBox="0 0 192 512" xmlns="http://www.w3.org/2000/svg">
+ <path d="M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"></path>
+ </svg>
+ </span>
+ </a>
+ </div>
+ {{/if}}
+ </div>
+ {{/if}}
+ </div>
+ </div>
+</div>
+{{/inline}}
+{{> layout}}<
\ No newline at end of file
M templates/layout.html.hbs => templates/layout.html.hbs +10 -10
@@ 1,12 1,12 @@
<!doctype html>
<html>
- <head>
- <meta charset="utf8">
- <meta content="width=device-width, initial-scale=1" name="viewport">
- <title>{{ title }} :: Arthur Melton Git</title>
- <link rel="stylesheet" href="/style.css">
- </head>
- <body>
- {{~> page}}
- </body>
-</html>
+ <head>
+ <meta charset="utf8">
+ <meta content="width=device-width, initial-scale=1" name="viewport">
+ <title>{{ title }} :: Arthur Melton Git</title>
+ <link rel="stylesheet" href="/style.css">
+ </head>
+ <body>
+ {{~> page}}
+ </body>
+</html><
\ No newline at end of file