parent
0b6e74c1e0
commit
f657a61d55
8 changed files with 23 additions and 51 deletions
|
@ -1,2 +1,3 @@
|
||||||
websites
|
websites
|
||||||
target
|
target
|
||||||
|
favicon
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
/target
|
/target
|
||||||
/websites
|
/websites
|
||||||
|
/favicon
|
|
@ -3,27 +3,13 @@ services:
|
||||||
build: .
|
build: .
|
||||||
ports:
|
ports:
|
||||||
- "8080:8000"
|
- "8080:8000"
|
||||||
depends_on:
|
|
||||||
- postgres
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./websites:/websites
|
- ./websites:/websites
|
||||||
|
- ./favicon:/favicon
|
||||||
environment:
|
environment:
|
||||||
- "DATABASE_URL=postgres://user:pass@postgres/webarc"
|
|
||||||
- "RUST_LOG=info"
|
- "RUST_LOG=info"
|
||||||
- "ROCKET_ADDRESS=0.0.0.0"
|
- "ROCKET_ADDRESS=0.0.0.0"
|
||||||
# Rewrite links to point back to the archive itself
|
# Rewrite links to point back to the archive itself
|
||||||
- "ROUTE_INTERNAL=true"
|
- "ROUTE_INTERNAL=true"
|
||||||
# Download missing routes on demand
|
# Download missing routes on demand
|
||||||
- "DOWNLOAD_ON_DEMAND=true"
|
- "DOWNLOAD_ON_DEMAND=true"
|
||||||
|
|
||||||
postgres:
|
|
||||||
image: timescale/timescaledb:latest-pg16
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- 5432:5432
|
|
||||||
volumes:
|
|
||||||
- ./db:/var/lib/postgresql/data/
|
|
||||||
environment:
|
|
||||||
- POSTGRES_USER=user
|
|
||||||
- POSTGRES_PASSWORD=pass
|
|
||||||
- POSTGRES_DB=webarc
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
CREATE TABLE site_favicon (
|
|
||||||
domain VARCHAR(500) NOT NULL PRIMARY KEY,
|
|
||||||
favicon bytea NOT NULL
|
|
||||||
);
|
|
|
@ -1,8 +1,4 @@
|
||||||
use std::{
|
use std::path::PathBuf;
|
||||||
fmt::format,
|
|
||||||
fs::read_to_string,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn read_dir(dir: &PathBuf) -> Vec<String> {
|
pub fn read_dir(dir: &PathBuf) -> Vec<String> {
|
||||||
let mut list = Vec::new();
|
let mut list = Vec::new();
|
||||||
|
@ -216,7 +212,7 @@ impl WebsiteArchive {
|
||||||
// redownload after threshold
|
// redownload after threshold
|
||||||
|
|
||||||
fn run_command(cmd: &[&str]) {
|
fn run_command(cmd: &[&str]) {
|
||||||
let mut cmd_setup = std::process::Command::new(cmd[0].clone());
|
let mut cmd_setup = std::process::Command::new(cmd[0]);
|
||||||
let cmd_setup = cmd_setup
|
let cmd_setup = cmd_setup
|
||||||
.args(cmd.into_iter().skip(1).collect::<Vec<_>>())
|
.args(cmd.into_iter().skip(1).collect::<Vec<_>>())
|
||||||
.stdout(std::process::Stdio::inherit())
|
.stdout(std::process::Stdio::inherit())
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
use based::get_pg;
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn download_favicon(domain: &str) -> Option<Vec<u8>> {
|
pub async fn download_favicon(domain: &str) -> Option<Vec<u8>> {
|
||||||
let mut favicon_url = url::Url::parse(&format!("https://{}", domain)).ok()?;
|
let mut favicon_url = url::Url::parse(&format!("https://{}", domain)).ok()?;
|
||||||
favicon_url.set_path("/favicon.ico");
|
favicon_url.set_path("/favicon.ico");
|
||||||
|
@ -21,10 +18,7 @@ pub async fn download_favicon(domain: &str) -> Option<Vec<u8>> {
|
||||||
pub async fn download_favicons_for_sites(sites: Vec<String>) {
|
pub async fn download_favicons_for_sites(sites: Vec<String>) {
|
||||||
for site in sites {
|
for site in sites {
|
||||||
if let Some(fav) = download_favicon(&site).await {
|
if let Some(fav) = download_favicon(&site).await {
|
||||||
sqlx::query("INSERT INTO site_favicon VALUES ($1, $2)")
|
std::fs::write(std::path::Path::new("./favicon").join(site), fav).unwrap();
|
||||||
.bind(site)
|
|
||||||
.bind(fav)
|
|
||||||
.execute(get_pg!()).await.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
use archive::WebsiteArchive;
|
use archive::WebsiteArchive;
|
||||||
use based::get_pg;
|
|
||||||
use rocket::routes;
|
use rocket::routes;
|
||||||
|
|
||||||
mod archive;
|
mod archive;
|
||||||
mod pages;
|
|
||||||
mod favicon;
|
mod favicon;
|
||||||
|
mod pages;
|
||||||
|
|
||||||
#[rocket::launch]
|
#[rocket::launch]
|
||||||
async fn launch() -> _ {
|
async fn launch() -> _ {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
let pg = get_pg!();
|
|
||||||
sqlx::migrate!("./migrations").run(pg).await.unwrap();
|
|
||||||
|
|
||||||
let arc = WebsiteArchive::new("./websites");
|
let arc = WebsiteArchive::new("./websites");
|
||||||
|
|
||||||
favicon::download_favicons_for_sites(arc.domains()).await;
|
favicon::download_favicons_for_sites(arc.domains()).await;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
use std::path::PathBuf;
|
use std::{io::Read, path::PathBuf};
|
||||||
|
|
||||||
use based::{
|
use based::{
|
||||||
get_pg, page::Shell, request::{assets::DataResponse, respond_html, RawResponse, RequestContext, StringResponse}
|
page::Shell,
|
||||||
|
request::{assets::DataResponse, respond_html, RequestContext, StringResponse},
|
||||||
};
|
};
|
||||||
use maud::{html, PreEscaped};
|
use maud::{html, PreEscaped};
|
||||||
use rocket::{get, Data, State};
|
use rocket::{get, State};
|
||||||
|
|
||||||
use crate::archive::{PathEntry, WebsiteArchive};
|
use crate::archive::{PathEntry, WebsiteArchive};
|
||||||
|
|
||||||
|
@ -26,15 +27,17 @@ pub async fn render_page(content: PreEscaped<String>, ctx: RequestContext) -> St
|
||||||
|
|
||||||
#[get("/favicon/<domain>")]
|
#[get("/favicon/<domain>")]
|
||||||
pub async fn favicon_route(domain: &str) -> Option<DataResponse> {
|
pub async fn favicon_route(domain: &str) -> Option<DataResponse> {
|
||||||
let fav: Option<(Vec<u8>,)> = sqlx::query_as("SELECT favicon FROM site_favicon WHERE domain = $1")
|
let mut buf = Vec::new();
|
||||||
.bind(domain)
|
std::fs::File::open(std::path::Path::new("./favicon").join(domain))
|
||||||
.fetch_optional(get_pg!()).await.unwrap();
|
.ok()?
|
||||||
|
.read_to_end(&mut buf)
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
if let Some(fav_data) = fav {
|
Some(DataResponse::new(
|
||||||
return Some(DataResponse::new(fav_data.0, "image/x-icon", Some(60 * 60 * 24 * 5)));
|
buf,
|
||||||
}
|
"image/x-icon",
|
||||||
|
Some(60 * 60 * 24 * 5),
|
||||||
None
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
|
|
Loading…
Add table
Reference in a new issue