add opengraph metadata for preview cards
This commit is contained in:
parent
b0a2f7ec7c
commit
16e7ea4806
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1585,7 +1585,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "transbeam"
|
name = "transbeam"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix",
|
"actix",
|
||||||
"actix-files",
|
"actix-files",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "transbeam"
|
name = "transbeam"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
authors = ["xenofem <xenofem@xeno.science>"]
|
authors = ["xenofem <xenofem@xeno.science>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
@ -28,6 +28,8 @@ transbeam is configured with the following environment variables:
|
||||||
(default: `./storage`)
|
(default: `./storage`)
|
||||||
- `TRANSBEAM_STATIC_DIR`: path where the web app's static files live
|
- `TRANSBEAM_STATIC_DIR`: path where the web app's static files live
|
||||||
(default: `./static`)
|
(default: `./static`)
|
||||||
|
- `TRANSBEAM_BASE_URL`: base URL for this transbeam instance, without
|
||||||
|
trailing `/`
|
||||||
- `TRANSBEAM_PORT`: port to listen on localhost for http requests
|
- `TRANSBEAM_PORT`: port to listen on localhost for http requests
|
||||||
(default: 8080)
|
(default: 8080)
|
||||||
- `TRANSBEAM_REVERSE_PROXY`: whether transbeam is running behind a
|
- `TRANSBEAM_REVERSE_PROXY`: whether transbeam is running behind a
|
||||||
|
|
20
src/main.rs
20
src/main.rs
|
@ -30,6 +30,7 @@ struct AppState {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
|
base_url: String,
|
||||||
max_upload_size: u64,
|
max_upload_size: u64,
|
||||||
max_lifetime: u16,
|
max_lifetime: u16,
|
||||||
upload_password: String,
|
upload_password: String,
|
||||||
|
@ -58,12 +59,14 @@ pub fn log_auth_failure(ip_addr: &str) {
|
||||||
#[template(path = "index.html")]
|
#[template(path = "index.html")]
|
||||||
struct IndexPage {
|
struct IndexPage {
|
||||||
cachebuster: String,
|
cachebuster: String,
|
||||||
|
base_url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
async fn index(data: web::Data<AppState>) -> impl Responder {
|
async fn index(data: web::Data<AppState>) -> impl Responder {
|
||||||
IndexPage {
|
IndexPage {
|
||||||
cachebuster: data.config.cachebuster.clone(),
|
cachebuster: data.config.cachebuster.clone(),
|
||||||
|
base_url: data.config.base_url.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +81,7 @@ struct DownloadRequest {
|
||||||
struct DownloadPage<'a> {
|
struct DownloadPage<'a> {
|
||||||
info: DownloadInfo,
|
info: DownloadInfo,
|
||||||
cachebuster: &'a str,
|
cachebuster: &'a str,
|
||||||
|
base_url: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
@ -134,6 +138,7 @@ async fn handle_download(
|
||||||
offsets,
|
offsets,
|
||||||
},
|
},
|
||||||
cachebuster: &data.config.cachebuster,
|
cachebuster: &data.config.cachebuster,
|
||||||
|
base_url: &data.config.base_url,
|
||||||
}
|
}
|
||||||
.to_response())
|
.to_response())
|
||||||
}
|
}
|
||||||
|
@ -175,6 +180,7 @@ async fn download_info(
|
||||||
#[template(path = "404.html")]
|
#[template(path = "404.html")]
|
||||||
struct NotFoundPage<'a> {
|
struct NotFoundPage<'a> {
|
||||||
cachebuster: &'a str,
|
cachebuster: &'a str,
|
||||||
|
base_url: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn not_found<T>(req: HttpRequest, data: web::Data<AppState>, report: bool) -> actix_web::Result<T> {
|
fn not_found<T>(req: HttpRequest, data: web::Data<AppState>, report: bool) -> actix_web::Result<T> {
|
||||||
|
@ -184,6 +190,7 @@ fn not_found<T>(req: HttpRequest, data: web::Data<AppState>, report: bool) -> ac
|
||||||
}
|
}
|
||||||
let mut resp = NotFoundPage {
|
let mut resp = NotFoundPage {
|
||||||
cachebuster: &data.config.cachebuster,
|
cachebuster: &data.config.cachebuster,
|
||||||
|
base_url: &data.config.base_url,
|
||||||
}
|
}
|
||||||
.to_response();
|
.to_response();
|
||||||
*resp.status_mut() = StatusCode::NOT_FOUND;
|
*resp.status_mut() = StatusCode::NOT_FOUND;
|
||||||
|
@ -269,6 +276,14 @@ where
|
||||||
.unwrap_or_else(default)
|
.unwrap_or_else(default)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn env_or_panic<T: FromStr>(var: &str) -> T
|
||||||
|
where
|
||||||
|
<T as FromStr>::Err: Debug,
|
||||||
|
{
|
||||||
|
let val = std::env::var(var).unwrap_or_else(|_| panic!("{} must be set!", var));
|
||||||
|
val.parse::<T>().unwrap_or_else(|_| panic!("Invalid value {} for variable {}", val, var))
|
||||||
|
}
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
dotenv::dotenv().ok();
|
dotenv::dotenv().ok();
|
||||||
|
@ -276,6 +291,7 @@ async fn main() -> std::io::Result<()> {
|
||||||
|
|
||||||
let static_dir: PathBuf = env_or_else("TRANSBEAM_STATIC_DIR", || PathBuf::from("static"));
|
let static_dir: PathBuf = env_or_else("TRANSBEAM_STATIC_DIR", || PathBuf::from("static"));
|
||||||
let storage_dir: PathBuf = env_or_else("TRANSBEAM_STORAGE_DIR", || PathBuf::from("storage"));
|
let storage_dir: PathBuf = env_or_else("TRANSBEAM_STORAGE_DIR", || PathBuf::from("storage"));
|
||||||
|
let base_url: String = env_or_panic("TRANSBEAM_BASE_URL");
|
||||||
let port: u16 = env_or("TRANSBEAM_PORT", 8080);
|
let port: u16 = env_or("TRANSBEAM_PORT", 8080);
|
||||||
let mnemonic_codes: bool = env_or("TRANSBEAM_MNEMONIC_CODES", true);
|
let mnemonic_codes: bool = env_or("TRANSBEAM_MNEMONIC_CODES", true);
|
||||||
let reverse_proxy: bool = env_or("TRANSBEAM_REVERSE_PROXY", true);
|
let reverse_proxy: bool = env_or("TRANSBEAM_REVERSE_PROXY", true);
|
||||||
|
@ -284,13 +300,13 @@ async fn main() -> std::io::Result<()> {
|
||||||
env_or::<ByteSize>("TRANSBEAM_MAX_UPLOAD_SIZE", ByteSize(16 * bytesize::GB)).as_u64();
|
env_or::<ByteSize>("TRANSBEAM_MAX_UPLOAD_SIZE", ByteSize(16 * bytesize::GB)).as_u64();
|
||||||
let max_storage_size: u64 =
|
let max_storage_size: u64 =
|
||||||
env_or::<ByteSize>("TRANSBEAM_MAX_STORAGE_SIZE", ByteSize(64 * bytesize::GB)).as_u64();
|
env_or::<ByteSize>("TRANSBEAM_MAX_STORAGE_SIZE", ByteSize(64 * bytesize::GB)).as_u64();
|
||||||
let upload_password: String =
|
let upload_password: String = env_or_panic("TRANSBEAM_UPLOAD_PASSWORD");
|
||||||
std::env::var("TRANSBEAM_UPLOAD_PASSWORD").expect("TRANSBEAM_UPLOAD_PASSWORD must be set!");
|
|
||||||
let cachebuster: String = env_or_else("TRANSBEAM_CACHEBUSTER", String::new);
|
let cachebuster: String = env_or_else("TRANSBEAM_CACHEBUSTER", String::new);
|
||||||
|
|
||||||
let data = web::Data::new(AppState {
|
let data = web::Data::new(AppState {
|
||||||
file_store: RwLock::new(FileStore::load(storage_dir.clone(), max_storage_size).await?),
|
file_store: RwLock::new(FileStore::load(storage_dir.clone(), max_storage_size).await?),
|
||||||
config: Config {
|
config: Config {
|
||||||
|
base_url,
|
||||||
max_upload_size,
|
max_upload_size,
|
||||||
max_lifetime,
|
max_lifetime,
|
||||||
upload_password,
|
upload_password,
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block title %}Download not found - transbeam{% endblock %}
|
{% block title %}Download not found - transbeam{% endblock %}
|
||||||
|
{% block og_title %}Download not found{% endblock %}
|
||||||
|
{% block og_description %}{% endblock %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script src="js/download-landing.js?{{ cachebuster }}"></script>
|
<script src="js/download-landing.js?{{ cachebuster }}"></script>
|
||||||
|
|
|
@ -3,12 +3,18 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
<meta name="color-scheme" content="light dark">
|
<meta name="color-scheme" content="light dark"/>
|
||||||
<link rel="stylesheet" type="text/css" href="css/transbeam.css?{{ cachebuster }}"/>
|
<link rel="stylesheet" type="text/css" href="css/transbeam.css?{{ cachebuster }}"/>
|
||||||
<link rel="stylesheet" type="text/css" href="css/colors.css?{{ cachebuster }}"/>
|
<link rel="stylesheet" type="text/css" href="css/colors.css?{{ cachebuster }}"/>
|
||||||
<link rel="apple-touch-icon" href="images/site-icons/transbeam-apple.png"/>
|
<link rel="apple-touch-icon" href="images/site-icons/transbeam-apple.png"/>
|
||||||
<link rel="manifest" href="manifest.json"/>
|
<link rel="manifest" href="manifest.json"/>
|
||||||
<title>{% block title %}transbeam{% endblock %}</title>
|
<title>{% block title %}transbeam{% endblock %}</title>
|
||||||
|
<meta name="og:type" content="website"/>
|
||||||
|
<meta name="og:site_name" content="transbeam"/>
|
||||||
|
<meta name="og:title" content="{% block og_title %}transbeam{% endblock %}"/>
|
||||||
|
<meta name="og:description" content="{% block og_description %}Low-latency file-drop web app{% endblock %}"/>
|
||||||
|
<meta name="og:image" content="{{ base_url }}/images/site-icons/transbeam-192.png"/>
|
||||||
|
<meta name="og:url" content="{{ base_url }}/{% block relative_path %}{% endblock %}"/>
|
||||||
{% block head %}{% endblock %}
|
{% block head %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body {% block body_attrs %}{% endblock %}>
|
<body {% block body_attrs %}{% endblock %}>
|
||||||
|
|
|
@ -2,6 +2,19 @@
|
||||||
|
|
||||||
{% block title %}{{ info.file.name }} - transbeam{% endblock %}
|
{% block title %}{{ info.file.name }} - transbeam{% endblock %}
|
||||||
|
|
||||||
|
{% block og_title %}{{ info.file.name }}{% endblock %}
|
||||||
|
{% block og_description -%}
|
||||||
|
{% let formatted_total_size = bytesize::to_string(info.file.size.clone(), false).replace(" ", "") -%}
|
||||||
|
{% match info.file.contents -%}
|
||||||
|
{% when Some with (files) -%}
|
||||||
|
{{ files.len() }} files, {{ formatted_total_size }} total
|
||||||
|
{%- else -%}
|
||||||
|
{{ formatted_total_size }}
|
||||||
|
{%- endmatch %}, expires {{ info.file.expiry.format(DATE_DISPLAY_FORMAT).unwrap() }}
|
||||||
|
{%- endblock %}
|
||||||
|
|
||||||
|
{% block relative_path %}download?code={{ info.code }}{% endblock %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<script src="js/util.js?{{ cachebuster }}"></script>
|
<script src="js/util.js?{{ cachebuster }}"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
Loading…
Reference in a new issue