add opengraph metadata for preview cards

This commit is contained in:
xenofem 2022-06-29 20:00:58 -04:00
parent b0a2f7ec7c
commit 16e7ea4806
7 changed files with 44 additions and 5 deletions

2
Cargo.lock generated
View file

@ -1585,7 +1585,7 @@ dependencies = [
[[package]]
name = "transbeam"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"actix",
"actix-files",

View file

@ -1,6 +1,6 @@
[package]
name = "transbeam"
version = "0.1.0"
version = "0.2.0"
authors = ["xenofem <xenofem@xeno.science>"]
edition = "2021"
license = "MIT"

View file

@ -28,6 +28,8 @@ transbeam is configured with the following environment variables:
(default: `./storage`)
- `TRANSBEAM_STATIC_DIR`: path where the web app's static files live
(default: `./static`)
- `TRANSBEAM_BASE_URL`: base URL for this transbeam instance, without
trailing `/`
- `TRANSBEAM_PORT`: port to listen on localhost for http requests
(default: 8080)
- `TRANSBEAM_REVERSE_PROXY`: whether transbeam is running behind a

View file

@ -30,6 +30,7 @@ struct AppState {
}
struct Config {
base_url: String,
max_upload_size: u64,
max_lifetime: u16,
upload_password: String,
@ -58,12 +59,14 @@ pub fn log_auth_failure(ip_addr: &str) {
#[template(path = "index.html")]
struct IndexPage {
cachebuster: String,
base_url: String,
}
#[get("/")]
async fn index(data: web::Data<AppState>) -> impl Responder {
IndexPage {
cachebuster: data.config.cachebuster.clone(),
base_url: data.config.base_url.clone(),
}
}
@ -78,6 +81,7 @@ struct DownloadRequest {
struct DownloadPage<'a> {
info: DownloadInfo,
cachebuster: &'a str,
base_url: &'a str,
}
#[derive(Serialize)]
@ -134,6 +138,7 @@ async fn handle_download(
offsets,
},
cachebuster: &data.config.cachebuster,
base_url: &data.config.base_url,
}
.to_response())
}
@ -175,6 +180,7 @@ async fn download_info(
#[template(path = "404.html")]
struct NotFoundPage<'a> {
cachebuster: &'a str,
base_url: &'a str,
}
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 {
cachebuster: &data.config.cachebuster,
base_url: &data.config.base_url,
}
.to_response();
*resp.status_mut() = StatusCode::NOT_FOUND;
@ -269,6 +276,14 @@ where
.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]
async fn main() -> std::io::Result<()> {
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 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 mnemonic_codes: bool = env_or("TRANSBEAM_MNEMONIC_CODES", 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();
let max_storage_size: u64 =
env_or::<ByteSize>("TRANSBEAM_MAX_STORAGE_SIZE", ByteSize(64 * bytesize::GB)).as_u64();
let upload_password: String =
std::env::var("TRANSBEAM_UPLOAD_PASSWORD").expect("TRANSBEAM_UPLOAD_PASSWORD must be set!");
let upload_password: String = env_or_panic("TRANSBEAM_UPLOAD_PASSWORD");
let cachebuster: String = env_or_else("TRANSBEAM_CACHEBUSTER", String::new);
let data = web::Data::new(AppState {
file_store: RwLock::new(FileStore::load(storage_dir.clone(), max_storage_size).await?),
config: Config {
base_url,
max_upload_size,
max_lifetime,
upload_password,

View file

@ -1,6 +1,8 @@
{% extends "base.html" %}
{% block title %}Download not found - transbeam{% endblock %}
{% block og_title %}Download not found{% endblock %}
{% block og_description %}{% endblock %}
{% block head %}
<script src="js/download-landing.js?{{ cachebuster }}"></script>

View file

@ -3,12 +3,18 @@
<head>
<meta charset="utf-8"/>
<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/colors.css?{{ cachebuster }}"/>
<link rel="apple-touch-icon" href="images/site-icons/transbeam-apple.png"/>
<link rel="manifest" href="manifest.json"/>
<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 %}
</head>
<body {% block body_attrs %}{% endblock %}>

View file

@ -2,6 +2,19 @@
{% 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 %}
<script src="js/util.js?{{ cachebuster }}"></script>
<script type="text/javascript">